LAPTOP-SB56SG4Q\86185
3 years ago
758 changed files with 120895 additions and 1 deletions
@ -1,3 +1,4 @@
|
||||
# open-fineui-swing |
||||
|
||||
利用fineui标准,开发设计器的 swing UI |
||||
利用fineui标准,开发设计器的 swing UI\ |
||||
这只是一个核心得框架代码,布局和核心组件的支持需要开发者一起迭代了 |
@ -0,0 +1,124 @@
|
||||
|
||||
apply plugin: 'java' |
||||
|
||||
[compileJava,compileTestJava]*.options*.encoding = 'UTF-8' |
||||
|
||||
ext { |
||||
/** |
||||
* 项目中依赖的jar的路径 |
||||
* 1.如果依赖的jar需要打包到zip中,放置在lib根目录下 |
||||
* 2.如果依赖的jar仅仅是编译时需要,防止在lib下子目录下即可 |
||||
*/ |
||||
libPath = "$projectDir/../../webroot/WEB-INF/lib" |
||||
|
||||
/** |
||||
* 是否对插件的class进行加密保护,防止反编译 |
||||
*/ |
||||
guard = true |
||||
|
||||
def pluginInfo = getPluginInfo() |
||||
pluginPre = "fine-plugin" |
||||
pluginName = pluginInfo.id |
||||
pluginVersion = pluginInfo.version |
||||
|
||||
outputPath = "$projectDir/../../webroot/WEB-INF/plugins/plugin-" + pluginName + "-1.0/classes" |
||||
} |
||||
|
||||
group = 'com.fr.plugin' |
||||
version = '10.0' |
||||
sourceCompatibility = '8' |
||||
|
||||
sourceSets { |
||||
main { |
||||
java.outputDir = file(outputPath) |
||||
output.resourcesDir = file(outputPath) |
||||
} |
||||
} |
||||
|
||||
ant.importBuild("encrypt.xml") |
||||
//定义ant变量 |
||||
ant.projectDir = projectDir |
||||
ant.references["compile.classpath"] = ant.path { |
||||
fileset(dir: libPath, includes: '**/*.jar') |
||||
fileset(dir: ".",includes:"**/*.jar" ) |
||||
} |
||||
|
||||
classes.dependsOn('clean') |
||||
|
||||
task copyFiles(type: Copy,dependsOn: 'classes'){ |
||||
from outputPath |
||||
into "$projectDir/classes" |
||||
} |
||||
|
||||
task preJar(type:Copy,dependsOn: guard ? 'compile_encrypt_javas' : 'compile_plain_javas'){ |
||||
from "$projectDir/classes" |
||||
into "$projectDir/transform-classes" |
||||
include "**/*.*" |
||||
} |
||||
jar.dependsOn("preJar") |
||||
|
||||
task makeJar(type: Jar,dependsOn: preJar){ |
||||
from fileTree(dir: "$projectDir/transform-classes") |
||||
baseName pluginPre |
||||
appendix pluginName |
||||
version pluginVersion |
||||
destinationDir = file("$buildDir/libs") |
||||
|
||||
doLast(){ |
||||
delete file("$projectDir/classes") |
||||
delete file("$projectDir/transform-classes") |
||||
} |
||||
} |
||||
|
||||
task copyFile(type: Copy,dependsOn: ["makeJar"]){ |
||||
from "$buildDir/libs" |
||||
from("$projectDir/lib") { |
||||
include "*.jar" |
||||
} |
||||
from "$projectDir/plugin.xml" |
||||
into file("$buildDir/temp/plugin") |
||||
} |
||||
|
||||
task zip(type:Zip,dependsOn:["copyFile"]){ |
||||
from "$buildDir/temp/plugin" |
||||
destinationDir file("$buildDir/install") |
||||
baseName pluginPre |
||||
appendix pluginName |
||||
version pluginVersion |
||||
} |
||||
|
||||
//控制build时包含哪些文件,排除哪些文件 |
||||
processResources { |
||||
// exclude everything |
||||
// 用*.css没效果 |
||||
// exclude '**/*.css' |
||||
// except this file |
||||
// include 'xx.xml' |
||||
} |
||||
|
||||
/*读取plugin.xml中的version*/ |
||||
def getPluginInfo(){ |
||||
def xmlFile = file("plugin.xml") |
||||
if (!xmlFile.exists()) { |
||||
return ["id":"none", "version":"1.0.0"] |
||||
} |
||||
def plugin = new XmlParser().parse(xmlFile) |
||||
def version = plugin.version[0].text() |
||||
def id = plugin.id[0].text() |
||||
return ["id":id,"version":version] |
||||
} |
||||
|
||||
repositories { |
||||
mavenLocal() |
||||
maven { |
||||
url = uri('http://mvn.finedevelop.com/repository/maven-public/') |
||||
} |
||||
} |
||||
|
||||
dependencies { |
||||
//使用本地jar |
||||
implementation fileTree(dir: 'lib', include: ['**/*.jar']) |
||||
implementation fileTree(dir: libPath, include: ['**/*.jar']) |
||||
} |
||||
|
||||
|
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
||||
<project> |
||||
<target name="compile_encrypt_javas" depends="copyFiles"> |
||||
<echo message="加密文件"/> |
||||
<echo message="${projectDir}"/> |
||||
<taskdef name="pretreatment" classname="com.fr.plugin.pack.PluginPretreatmentTask"> |
||||
<classpath refid="compile.classpath"/> |
||||
</taskdef> |
||||
<pretreatment baseDir="${projectDir}"/> |
||||
</target> |
||||
<target name="compile_plain_javas" depends="copyFiles"> |
||||
</target> |
||||
</project> |
Binary file not shown.
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><plugin> |
||||
<id>com.tptj.tool.hg.fineui.swing</id> |
||||
<name><![CDATA[ Swing Fine UI ]]></name> |
||||
<active>yes</active> |
||||
<version>1.0</version> |
||||
<env-version>10.0</env-version> |
||||
<vendor>tptj</vendor> |
||||
<jartime>2019-07-18</jartime> |
||||
<description><![CDATA[ ]]></description> |
||||
<change-notes><![CDATA[]]></change-notes> |
||||
<main-package>com.tptj.tool.hg.fineui.swing</main-package> |
||||
<function-recorder class="com.tptj.tool.hg.fineui.swing.DemoTableData"/> |
||||
<extra-designer> |
||||
<TableDataDefineProvider class="com.tptj.tool.hg.fineui.swing.DemoTableDataRegister"/> |
||||
</extra-designer> |
||||
</plugin> |
@ -0,0 +1,282 @@
|
||||
package com.tptj.tool.hg.fineui.swing; |
||||
|
||||
import com.eclipsesource.v8.V8; |
||||
import com.eclipsesource.v8.V8Array; |
||||
import com.eclipsesource.v8.V8Object; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.tptj.tool.hg.engine.js.Debugger; |
||||
import com.tptj.tool.hg.engine.js.JsEngineMaker; |
||||
import com.tptj.tool.hg.engine.js.JsProcess; |
||||
import com.tptj.tool.hg.fineui.swing.element.Element; |
||||
import com.tptj.tool.hg.fineui.swing.element.JPanelElement; |
||||
|
||||
import javax.swing.*; |
||||
import java.awt.event.WindowEvent; |
||||
import java.awt.event.WindowListener; |
||||
|
||||
/** |
||||
* @author 秃破天际 |
||||
* @version 10.0 |
||||
* Created by 秃破天际 on 2021/10/28 |
||||
**/ |
||||
public class FineUIEngine { |
||||
|
||||
public JsEngineMaker engine; |
||||
|
||||
private static volatile FineUIEngine instance = null; |
||||
|
||||
public static FineUIEngine getInstance() { |
||||
if (null == instance) { |
||||
synchronized (FineUIEngine.class) { |
||||
if (null == instance) { |
||||
instance = new FineUIEngine(); |
||||
} |
||||
} |
||||
} |
||||
return instance; |
||||
} |
||||
|
||||
private FineUIEngine() { |
||||
init(); |
||||
} |
||||
|
||||
private void init() { |
||||
try { |
||||
//之间一次引入全部fineui,会因为各种环境参数方法的缺失而大量报错,因为调试难度很大,
|
||||
// 所以采用逐渐引入,逐渐调试的方式去逐渐覆盖,
|
||||
// 待全面适配成功后应该可以直接引入fineui.min.js了
|
||||
engine = JsEngineMaker.newInstance(); |
||||
JsProcess.create(engine.getEngine(),()->{ |
||||
engine.importJs( |
||||
//com/fr/fineui 目录下的都是fineui自身的源码
|
||||
"com/fr/fineui/core/0.foundation.js", |
||||
"com/fr/fineui/core/1.lodash.js", |
||||
"com/fr/fineui/core/2.base.js", |
||||
"com/fr/fineui/core/3.ob.js", |
||||
"com/fr/fineui/core/4.widget.js", |
||||
"com/fr/fineui/core/5.shortcut.js", |
||||
"com/fr/fineui/core/6.inject.js", |
||||
"com/fr/fineui/core/7.plugin.js", |
||||
"com/fr/fineui/core/system.js", |
||||
"com/fr/fineui/core/version.js", |
||||
|
||||
"com/fr/fineui/core/constant/date.i18n.js", |
||||
"com/fr/fineui/core/constant/events.js", |
||||
"com/fr/fineui/core/constant/var.js", |
||||
|
||||
"com/fr/fineui/core/func/alias.js", |
||||
"com/fr/fineui/core/func/array.js", |
||||
"com/fr/fineui/core/func/date.js", |
||||
"com/fr/fineui/core/func/function.js", |
||||
"com/fr/fineui/core/func/number.js", |
||||
"com/fr/fineui/core/func/string.js", |
||||
|
||||
"com/fr/fineui/core/structure/aes.js", |
||||
"com/fr/fineui/core/structure/aspect.js", |
||||
"com/fr/fineui/core/structure/base64.js", |
||||
"com/fr/fineui/core/structure/cache.js", |
||||
"com/fr/fineui/core/structure/cellSizeAndPositionManager.js", |
||||
"com/fr/fineui/core/structure/heap.js", |
||||
"com/fr/fineui/core/structure/linkedHashMap.js", |
||||
"com/fr/fineui/core/structure/lru.js", |
||||
"com/fr/fineui/core/structure/prefixIntervalTree.js", |
||||
"com/fr/fineui/core/structure/queue.js", |
||||
"com/fr/fineui/core/structure/sectionManager.js", |
||||
"com/fr/fineui/core/structure/tree.js", |
||||
"com/fr/fineui/core/structure/vector.js", |
||||
|
||||
"com/fr/fineui/core/utils/chinesePY.js", |
||||
"com/fr/fineui/core/utils/i18n.js", |
||||
|
||||
"com/fr/fineui/core/wrapper/layout.js", |
||||
"com/fr/fineui/core/wrapper/layout/layout.absolute.js", |
||||
"com/fr/fineui/core/wrapper/layout/layout.adaptive.js", |
||||
"com/fr/fineui/core/wrapper/layout/layout.border.js", |
||||
"com/fr/fineui/core/wrapper/layout/layout.default.js", |
||||
"com/fr/fineui/core/wrapper/layout/layout.flow.js", |
||||
"com/fr/fineui/core/wrapper/layout/layout.horizontal.js", |
||||
"com/fr/fineui/core/wrapper/layout/layout.tape.js", |
||||
"com/fr/fineui/core/wrapper/layout/layout.grid.js", |
||||
"com/fr/fineui/core/wrapper/layout/layout.window.js", |
||||
"com/fr/fineui/core/wrapper/layout/layout.vertical.js", |
||||
"com/fr/fineui/core/wrapper/layout/adapt/adapt.center.js", |
||||
"com/fr/fineui/core/wrapper/layout/adapt/adapt.vertical.js", |
||||
|
||||
"com/fr/fineui/core/wrapper/layout/flex/flex.vertical.js", |
||||
"com/fr/fineui/core/wrapper/layout/flex/flex.horizontal.js", |
||||
"com/fr/fineui/core/wrapper/layout/flex/flex.center.js", |
||||
"com/fr/fineui/core/wrapper/layout/flex/flex.horizontal.center.js", |
||||
"com/fr/fineui/core/wrapper/layout/flex/flex.vertical.center.js", |
||||
"com/fr/fineui/core/wrapper/layout/flex/flex.leftrightvertical.center.js", |
||||
|
||||
//com/tptj/tool/hg/fineui/swing 下的都是适配swing的js代码
|
||||
// 自定义布局
|
||||
"com/tptj/tool/hg/fineui/swing/core/wrapper/layout.static.js", |
||||
"com/tptj/tool/hg/fineui/swing/core/wrapper/layout.horizontal.js", |
||||
"com/tptj/tool/hg/fineui/swing/core/wrapper/layout.vertical.js", |
||||
"com/tptj/tool/hg/fineui/swing/core/wrapper/layout.vertical_adapt.js", |
||||
"com/tptj/tool/hg/fineui/swing/core/wrapper/layout.center_adapt.js", |
||||
|
||||
|
||||
"com/tptj/tool/hg/fineui/swing/core/platform/swing/config.js", |
||||
"com/tptj/tool/hg/fineui/swing/core/platform/swing/dom.js", |
||||
"com/tptj/tool/hg/fineui/swing/core/platform/swing/function.js", |
||||
|
||||
|
||||
"com/tptj/tool/hg/fineui/swing/core/element.js", |
||||
"com/tptj/tool/hg/fineui/swing/core/extra.js", |
||||
|
||||
//自定义的基础控件,最基本的控件需要由swing实现后,映射到fineui中,高级的组件就可以
|
||||
//由开发者按照fineui的组件继承方式进行组合创建新的组件了
|
||||
"com/tptj/tool/hg/fineui/swing/base/single/label.js", |
||||
"com/tptj/tool/hg/fineui/swing/widget/editor/editor.text.js" |
||||
|
||||
); |
||||
return null; |
||||
}).run(); |
||||
engine.setDebugger(new Debugger() { |
||||
@Override |
||||
public void debug(Object... obj) { |
||||
//用来打断点查看JS的属性和变量的,因为V8调试是很麻烦的,所以一般开发者可以简单的
|
||||
//利用这个入口对调试的变量进行查看
|
||||
//console.debug(变量1,变量2,变量3,....)
|
||||
int a = 1; |
||||
} |
||||
}); |
||||
} catch (Exception e) { |
||||
FineLoggerFactory.getLogger().error(e, "FineUI swing引擎初始化失败!{}", e.getMessage()); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 设置本次渲染的根节点 |
||||
* |
||||
* @param element |
||||
*/ |
||||
public FineUIEngine body(Element element) { |
||||
engine.set("body", element); |
||||
return this; |
||||
} |
||||
|
||||
public FineUIEngine importJs(String... path) { |
||||
engine.importJs(path); |
||||
return this; |
||||
} |
||||
|
||||
public void close(){ |
||||
engine.close(); |
||||
} |
||||
|
||||
public static Object trans(V8 v8,Object result){ |
||||
return JsEngineMaker.trans(v8,result); |
||||
} |
||||
|
||||
public static void close( Object value ){ |
||||
JsEngineMaker.close(value); |
||||
} |
||||
|
||||
public static Object call(V8Object js, String method, Object ... args)throws Exception{ |
||||
//为了保证跨线程调用成功,在java中调用JS对象的方法时,
|
||||
// 需要使用JsProcess.create(V8Object,Action)的方式
|
||||
return JsProcess.create(js,()->{ |
||||
return executeFunction(js, method, args); |
||||
}).run(); |
||||
} |
||||
|
||||
public static Object executeFunction( V8Object js, String method, Object ... args ){ |
||||
return JsEngineMaker.executeFunction(js, method, args); |
||||
} |
||||
|
||||
public static V8Array executeArrayFunction( V8Object js, String method, Object ... args ){ |
||||
return JsEngineMaker.executeArrayFunction(js, method, args); |
||||
} |
||||
|
||||
public static V8Object executeObjectFunction( V8Object js, String method, Object ... args ){ |
||||
return JsEngineMaker.executeObjectFunction(js, method, args); |
||||
} |
||||
|
||||
public static String executeStringFunction( V8Object js, String method, Object ... args ){ |
||||
return JsEngineMaker.executeStringFunction(js, method, args); |
||||
} |
||||
|
||||
public static boolean executeBooleanFunction( V8Object js, String method, Object ... args ){ |
||||
return JsEngineMaker.executeBooleanFunction(js, method, args); |
||||
} |
||||
|
||||
public static double executeDoubleFunction( V8Object js, String method, Object ... args ){ |
||||
return JsEngineMaker.executeDoubleFunction(js, method, args); |
||||
} |
||||
|
||||
public static int executeIntegerFunction( V8Object js, String method, Object ... args ){ |
||||
return JsEngineMaker.executeIntegerFunction(js, method, args); |
||||
} |
||||
|
||||
public static void executeVoidFunction( V8Object js, String method, Object ... args ){ |
||||
JsEngineMaker.executeVoidFunction(js, method, args); |
||||
} |
||||
|
||||
public static void main(String[] args) throws Exception { |
||||
//最终UI整个结构就在el里面~再用java把el渲染出来即可
|
||||
//目前利用这个框架简单的实现了 绝对布局 边界(圣杯)布局、水平带布局、垂直带布局、网格布局、窗口布局 几个经典的fineui静态布局
|
||||
//设计器插件本身其实也基本都是静态布局即可满足需要
|
||||
JPanelElement el = new JPanelElement(); |
||||
FineUIEngine engine = FineUIEngine.getInstance(); |
||||
JsProcess.create(engine.engine.getEngine(),()->{ |
||||
engine.body(el) |
||||
//demo下面的就是实际使用时的代码了,该框架包开发完毕,使用者要写的就是按照demo目录下那些代码了
|
||||
//.importJs("com/tptj/tool/hg/fineui/swing/demo/layout.border.js");
|
||||
//.importJs("com/tptj/tool/hg/fineui/swing/demo/layout.tape.js");
|
||||
//.importJs("com/tptj/tool/hg/fineui/swing/demo/layout.grid.js");
|
||||
.importJs("com/tptj/tool/hg/fineui/swing/demo/layout.window.js"); |
||||
return null; |
||||
}).run(); |
||||
|
||||
|
||||
JFrame frame = new JFrame("Fine UI Demo"); |
||||
frame.setSize(800, 600); |
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); |
||||
|
||||
frame.getContentPane().add(el.getComponent()); |
||||
frame.addWindowListener(new WindowListener() { |
||||
@Override |
||||
public void windowOpened(WindowEvent e) { |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public void windowClosing(WindowEvent e) { |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public void windowClosed(WindowEvent e) { |
||||
//hugh:使用的是V8的引擎,这个引擎要求必须是主动释放资源,否则会内存泄露
|
||||
//所以在使用完毕后一定要记得关闭
|
||||
engine.close(); |
||||
} |
||||
|
||||
@Override |
||||
public void windowIconified(WindowEvent e) { |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public void windowDeiconified(WindowEvent e) { |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public void windowActivated(WindowEvent e) { |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public void windowDeactivated(WindowEvent e) { |
||||
|
||||
} |
||||
}); |
||||
// 显示窗口
|
||||
frame.setVisible(true); |
||||
System.out.println(el); |
||||
} |
||||
} |
@ -0,0 +1,279 @@
|
||||
package com.tptj.tool.hg.fineui.swing.element; |
||||
|
||||
import com.eclipsesource.v8.V8Object; |
||||
import com.fr.general.GeneralUtils; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.tptj.tool.hg.fineui.swing.FineUIEngine; |
||||
import com.tptj.tool.hg.fineui.swing.element.layout.LayoutBuilder; |
||||
import com.tptj.tool.hg.fineui.swing.element.layout.LayoutType; |
||||
import com.tptj.tool.hg.fineui.swing.stable.ColorUtils; |
||||
import javax.swing.*; |
||||
import java.awt.*; |
||||
import java.util.*; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* @author 秃破天际 |
||||
* @version 10.0 |
||||
* Created by 秃破天际 on 2021/10/29 |
||||
**/ |
||||
public abstract class AbstractElement<T extends JComponent> implements Element<T> { |
||||
|
||||
private T component; |
||||
private JComponent wrapper; |
||||
private V8Object ref; |
||||
private String type; |
||||
//记录当前的控件状态,用于驱动一些特殊事件
|
||||
private Status status; |
||||
public AbstractElement(T component) { |
||||
this.wrapper = component; |
||||
this.component = component; |
||||
} |
||||
|
||||
public void setComponent(T component) { |
||||
this.wrapper = component; |
||||
this.component = component; |
||||
} |
||||
|
||||
private Map<String, Object> attributes = new HashMap<String, Object>(); |
||||
private Map<String, Object> data = new HashMap<String, Object>(); |
||||
private Set<String> clazz_set = new HashSet<String>(); |
||||
private Map<String, Object> css = new HashMap<String, Object>(); |
||||
private int width; |
||||
private int height; |
||||
private Object val; |
||||
|
||||
|
||||
private AbstractElement parent; |
||||
private List<AbstractElement> children = new ArrayList<AbstractElement>(); |
||||
|
||||
public AbstractElement() { } |
||||
|
||||
public Status getStatus() { |
||||
return status; |
||||
} |
||||
|
||||
public void setStatus(Status status) { |
||||
this.status = status; |
||||
} |
||||
|
||||
@Override |
||||
public JComponent getWrapper() { |
||||
return wrapper; |
||||
} |
||||
|
||||
@Override |
||||
public T getComponent() { |
||||
return component; |
||||
} |
||||
|
||||
@Override |
||||
public void setType(String type) { |
||||
this.type = type; |
||||
} |
||||
|
||||
@Override |
||||
public void mounted() { |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public AbstractElement parent() { |
||||
return parent; |
||||
} |
||||
|
||||
@Override |
||||
public void setParent(AbstractElement parent) { |
||||
this.parent = parent; |
||||
} |
||||
|
||||
@Override |
||||
public void ref(V8Object obj) { |
||||
this.ref = obj; |
||||
} |
||||
|
||||
@Override |
||||
public void removeClass(String clazz) { |
||||
clazz_set.remove(clazz); |
||||
} |
||||
|
||||
@Override |
||||
public void setData(String name, Object data) { |
||||
this.data.put(name, data); |
||||
} |
||||
|
||||
@Override |
||||
public void css(String name, String val) { |
||||
switch (name) { |
||||
case "overflow": |
||||
case "overflowX": |
||||
case "overflowY": |
||||
case "overflow-x": |
||||
case "overflow-y": |
||||
if ("auto".equals(val)) { |
||||
wrapper = new JScrollPane(component); |
||||
} |
||||
break; |
||||
case "background": |
||||
component.setOpaque(true); |
||||
Color color = ColorUtils.str2Color(val); |
||||
component.setBackground( color ); |
||||
break; |
||||
case "color": |
||||
color = ColorUtils.str2Color(val); |
||||
component.setForeground(color); |
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
css.put(name, val); |
||||
} |
||||
|
||||
|
||||
|
||||
@Override |
||||
public Map<String, Object> getStyle() { |
||||
return css; |
||||
} |
||||
|
||||
@Override |
||||
public void cssMap(V8Object map) { |
||||
String[] keys = map.getKeys(); |
||||
for (String key : keys) { |
||||
css(key, GeneralUtils.objectToString( map.get(key) ) ); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void unbind() { |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public void destroy() { |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public Object getData(String name) { |
||||
return data.get(name); |
||||
} |
||||
|
||||
@Override |
||||
public void addClass(String clazz) { |
||||
clazz_set.add(clazz); |
||||
} |
||||
|
||||
@Override |
||||
public void setAttr(String name, Object val) { |
||||
attributes.put(name, val); |
||||
} |
||||
|
||||
@Override |
||||
public Object getAttr(String name) { |
||||
return attributes.get(name); |
||||
} |
||||
|
||||
@Override |
||||
public void empty() { |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public void layout(String layoutType) { |
||||
LayoutType layout = LayoutBuilder.layout(layoutType, this); |
||||
component.setLayout(layout.init()); |
||||
for (int i = 0, len = children.size(); i < len; i++) { |
||||
AbstractElement childElement = children.get(i); |
||||
layout.layout(childElement,i); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void append(AbstractElement element) { |
||||
if (null == element.getComponent()) { |
||||
List<AbstractElement> children = element.children(); |
||||
for (AbstractElement child : children) { |
||||
append(child); |
||||
} |
||||
} else { |
||||
children.add(element); |
||||
element.setParent(this); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public List<AbstractElement> children() { |
||||
return children; |
||||
} |
||||
|
||||
@Override |
||||
public void appendTo(AbstractElement element) { |
||||
parent = element; |
||||
element.append(this); |
||||
} |
||||
|
||||
@Override |
||||
public void appendChild(AbstractElement element) { |
||||
append(element); |
||||
} |
||||
|
||||
@Override |
||||
public void setWidth(int width) { |
||||
this.width = width; |
||||
} |
||||
|
||||
@Override |
||||
public void setHeight(int height) { |
||||
this.height = height; |
||||
} |
||||
|
||||
@Override |
||||
public int getWidth() { |
||||
return component.getWidth(); |
||||
} |
||||
|
||||
@Override |
||||
public int getHeight() { |
||||
return component.getHeight(); |
||||
} |
||||
|
||||
@Override |
||||
public void setVal(Object val) { |
||||
this.val = val; |
||||
} |
||||
|
||||
protected Object callJsMethod( String name, Object ... args ){ |
||||
try{ |
||||
return FineUIEngine.call(ref,name,args); |
||||
}catch(Exception e){ |
||||
FineLoggerFactory.getLogger().error(e,e.getMessage()); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
@Override |
||||
public Object getVal() { |
||||
return val; |
||||
} |
||||
|
||||
@Override |
||||
public int getRectStyleAttr( String name, int max, int min ){ |
||||
Object val = css.get(name); |
||||
if("".equals(val)){ |
||||
return min; |
||||
} |
||||
if( null == val ){ |
||||
return min; |
||||
} |
||||
if( val instanceof String && ((String)val).endsWith("%") ){ |
||||
String sv = (String)val; |
||||
sv = sv.substring( 0, sv.length()-1 ); |
||||
double vald = GeneralUtils.objectToNumber(sv).doubleValue() * max ; |
||||
vald = vald/100; |
||||
return (int)vald; |
||||
} |
||||
return ( null == val || "initial".equals(val) || min > GeneralUtils.objectToNumber(val).intValue() ) |
||||
? min : GeneralUtils.objectToNumber(val).intValue(); |
||||
} |
||||
} |
@ -0,0 +1,61 @@
|
||||
package com.tptj.tool.hg.fineui.swing.element; |
||||
|
||||
import com.eclipsesource.v8.V8Object; |
||||
|
||||
import javax.swing.*; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* @author 秃破天际 |
||||
* @version 10.0 |
||||
* Created by 秃破天际 on 2021/10/29 |
||||
* 模拟dom的基本操作 |
||||
**/ |
||||
public interface Element<T extends JComponent> { |
||||
T getComponent(); |
||||
void setType(String type); |
||||
void mounted(); |
||||
JComponent getWrapper(); |
||||
|
||||
Map<String,Object> getStyle(); |
||||
int getRectStyleAttr( String name,int max, int min ); |
||||
|
||||
AbstractElement parent(); |
||||
void setParent(AbstractElement parent); |
||||
void ref( V8Object obj ); |
||||
void removeClass(String clazz); |
||||
|
||||
/** |
||||
* swing组件的渲染都从这个地方接入 |
||||
* @param name |
||||
* @param val |
||||
*/ |
||||
void css(String name,String val); |
||||
void cssMap(V8Object map); |
||||
void unbind(); |
||||
void destroy(); |
||||
|
||||
void setData(String name,Object data); |
||||
Object getData(String name); |
||||
|
||||
void addClass(String clazz); |
||||
|
||||
void setAttr(String name,Object val); |
||||
Object getAttr(String name); |
||||
|
||||
void empty(); |
||||
void layout(String layoutType); |
||||
void append( AbstractElement element ); |
||||
List<AbstractElement> children(); |
||||
void appendTo( AbstractElement element ); |
||||
void appendChild( AbstractElement element ); |
||||
|
||||
void setWidth(int width); |
||||
void setHeight(int height); |
||||
int getWidth(); |
||||
int getHeight(); |
||||
|
||||
void setVal(Object val); |
||||
Object getVal(); |
||||
} |
@ -0,0 +1,15 @@
|
||||
package com.tptj.tool.hg.fineui.swing.element; |
||||
|
||||
|
||||
import javax.swing.*; |
||||
|
||||
/** |
||||
* @author 秃破天际 |
||||
* @version 10.0 |
||||
* Created by 秃破天际 on 2021/10/29 |
||||
**/ |
||||
public class JPanelElement extends AbstractElement<JPanel> { |
||||
public JPanelElement() { |
||||
super(new JPanel()); |
||||
} |
||||
} |
@ -0,0 +1,43 @@
|
||||
package com.tptj.tool.hg.fineui.swing.element; |
||||
|
||||
import com.fr.design.gui.ilable.UILabel; |
||||
import com.fr.general.GeneralUtils; |
||||
|
||||
import javax.swing.*; |
||||
|
||||
/** |
||||
* @author 秃破天际 |
||||
* @version 10.0 |
||||
* Created by 秃破天际 on 2021/10/29 |
||||
**/ |
||||
public class LabelElement extends AbstractElement<UILabel> { |
||||
|
||||
public LabelElement() { |
||||
super(new UILabel()); |
||||
} |
||||
|
||||
@Override |
||||
public Object getVal(){ |
||||
return getComponent().getText(); |
||||
} |
||||
|
||||
@Override |
||||
public void setVal( Object val ){ |
||||
super.setVal(val); |
||||
getComponent().setText( GeneralUtils.objectToString(val) ); |
||||
} |
||||
@Override |
||||
public void css(String name, String val) { |
||||
super.css(name, val); |
||||
val = val.toUpperCase(); |
||||
if( "text-align".equals( name ) ){ |
||||
if( "LEFT".equals(val) ){ |
||||
getComponent().setHorizontalAlignment( SwingConstants.LEFT ); |
||||
}else if( "CENTER".equals(val) ){ |
||||
getComponent().setHorizontalAlignment( SwingConstants.CENTER ); |
||||
}else if( "RIGHT".equals(val) ){ |
||||
getComponent().setHorizontalAlignment( SwingConstants.RIGHT ); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
package com.tptj.tool.hg.fineui.swing.element; |
||||
|
||||
/** |
||||
* @author 秃破天际 |
||||
* @version 10.0 |
||||
* Created by 秃破天际 on 2021/11/2 |
||||
* 简单的声明组件的几个状态,用来驱动一些特殊的事件。 |
||||
* 本身其实并不强制要求实现所有的fineui的事件,实现一些常用的即可 |
||||
**/ |
||||
public enum Status { |
||||
FREE,FOCUS,EDITING |
||||
} |
@ -0,0 +1,154 @@
|
||||
package com.tptj.tool.hg.fineui.swing.element; |
||||
|
||||
import com.fr.design.gui.ipasswordfield.UIPassWordField; |
||||
import com.fr.design.gui.itextfield.UITextField; |
||||
import com.fr.general.GeneralUtils; |
||||
|
||||
import com.fr.stable.StringUtils; |
||||
|
||||
import javax.swing.*; |
||||
import javax.swing.event.DocumentEvent; |
||||
import javax.swing.event.DocumentListener; |
||||
import java.awt.event.FocusEvent; |
||||
import java.awt.event.FocusListener; |
||||
import java.awt.event.KeyEvent; |
||||
import java.awt.event.KeyListener; |
||||
|
||||
/** |
||||
* @author 秃破天际 |
||||
* @version 10.0 |
||||
* Created by 秃破天际 on 2021/11/2 |
||||
**/ |
||||
public class TextElement extends AbstractElement<JTextField>{ |
||||
public TextElement() { |
||||
super(new UITextField()); |
||||
init(); |
||||
} |
||||
private void validationChecker(){ |
||||
callJsMethod("validationChecker"); |
||||
} |
||||
private boolean quitChecker(){ |
||||
return (boolean) callJsMethod("quitChecker"); |
||||
} |
||||
private void init() { |
||||
JTextField wgt = getComponent(); |
||||
wgt.getDocument().addDocumentListener(new DocumentListener() { |
||||
@Override |
||||
public void insertUpdate(DocumentEvent e) { |
||||
validationChecker(); |
||||
callJsMethod("fireEvent","EVENT_CHANGE", wgt.getText() ); |
||||
} |
||||
|
||||
@Override |
||||
public void removeUpdate(DocumentEvent e) { |
||||
validationChecker(); |
||||
callJsMethod("fireEvent","EVENT_CHANGE", wgt.getText() ); |
||||
if( StringUtils.isEmpty( wgt.getText() ) ){ |
||||
callJsMethod("fireEvent","EVENT_EMPTY"); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void changedUpdate(DocumentEvent e) { |
||||
validationChecker(); |
||||
callJsMethod("fireEvent","EVENT_CHANGE", wgt.getText() ); |
||||
if( StringUtils.isEmpty( wgt.getText() ) ){ |
||||
callJsMethod("fireEvent","EVENT_EMPTY"); |
||||
} |
||||
} |
||||
}); |
||||
wgt.addFocusListener(new FocusListener() { |
||||
@Override |
||||
public void focusGained(FocusEvent e) { |
||||
setStatus(Status.FOCUS); |
||||
callJsMethod("fireEvent","EVENT_FOCUS" ); |
||||
} |
||||
|
||||
@Override |
||||
public void focusLost(FocusEvent e) { |
||||
setStatus(Status.FREE); |
||||
callJsMethod("fireEvent","EVENT_BLUR" ); |
||||
if( quitChecker() ){ |
||||
callJsMethod("fireEvent","EVENT_CONFIRM" ); |
||||
} |
||||
} |
||||
}); |
||||
/** |
||||
EVENT_CHANGE 输入值改变事件 |
||||
EVENT_FOCUS focus事件 |
||||
EVENT_BLUR blur事件 |
||||
EVENT_KEY_DOWN keydown事件,300毫秒debounce才会触发 |
||||
EVENT_ENTER 回车按键事件,当quitChecker为null或检查值不等于false时触发 |
||||
EVENT_SPACE 空格按键事件 |
||||
EVENT_BACKSPACE 删除按键事件,backspace或del按键触发 |
||||
|
||||
EVENT_START 开始输入事件 |
||||
EVENT_PAUSE 暂停输入事件 |
||||
EVENT_STOP 停止输入事件 |
||||
EVENT_CONFIRM 退出输入状态且当前值为有效值时表示的确定事件 |
||||
EVENT_CHANGE_CONFIRM 当confirm事件触发时如果当前值与上一次有效值不同就会触发该事件 |
||||
EVENT_REMOVE 清除事件,当EVENT_BACKSPACE触发时,删除到空的时候触发 |
||||
EVENT_EMPTY 空事件,输入框无值时触发 |
||||
EVENT_VALID 有效事件,输入框值有效触发 |
||||
EVENT_ERROR 无效事件,输入框值无效触发 |
||||
EVENT_RESTRICT 被限制事件,当回车键按下但是quitChecker检查为false,表示不允许被退出 |
||||
**/ |
||||
wgt.addKeyListener(new KeyListener() { |
||||
@Override |
||||
public void keyTyped(KeyEvent e) { |
||||
|
||||
} |
||||
@Override |
||||
public void keyPressed(KeyEvent e) { |
||||
char c = e.getKeyChar(); |
||||
if( KeyEvent.VK_SPACE == (int)c ){ |
||||
callJsMethod("fireEvent","EVENT_SPACE" ); |
||||
}else if( KeyEvent.VK_BACK_SPACE == (int)c || KeyEvent.VK_DELETE == (int)c ){ |
||||
callJsMethod("fireEvent","EVENT_BACKSPACE" ); |
||||
}else if( KeyEvent.VK_ENTER == (int)c ){ |
||||
callJsMethod("fireEvent","EVENT_BACKSPACE" ); |
||||
if( StringUtils.isEmpty( wgt.getText() ) ){ |
||||
callJsMethod("fireEvent","EVENT_REMOVE" ); |
||||
} |
||||
} |
||||
if( Status.FOCUS == getStatus() ){ |
||||
callJsMethod("fireEvent","EVENT_START" ); |
||||
} |
||||
setStatus(Status.EDITING); |
||||
callJsMethod("fireEvent","EVENT_KEY_DOWN" ); |
||||
} |
||||
@Override |
||||
public void keyReleased(KeyEvent e) { |
||||
|
||||
} |
||||
}); |
||||
} |
||||
|
||||
@Override |
||||
public Object getVal(){ |
||||
return getComponent().getText(); |
||||
} |
||||
|
||||
@Override |
||||
public void setVal( Object val ){ |
||||
super.setVal(val); |
||||
getComponent().setText( GeneralUtils.objectToString(val) ); |
||||
} |
||||
|
||||
@Override |
||||
public void css(String name, String val){ |
||||
super.css(name, val); |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public void setAttr(String name, Object val){ |
||||
super.setAttr(name, val); |
||||
name = name.toLowerCase(); |
||||
if("type".equals(name) && "password".equals(val)){ |
||||
//换JAVA控件只能在这里换,之后就不允许换了!否则会导致渲染的样式丢失
|
||||
setComponent( new UIPassWordField() ); |
||||
init(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,464 @@
|
||||
package com.tptj.tool.hg.fineui.swing.element; |
||||
|
||||
import java.awt.Component; |
||||
import java.awt.Container; |
||||
import java.awt.Dimension; |
||||
import java.awt.Insets; |
||||
import java.awt.LayoutManager; |
||||
|
||||
/** |
||||
* A vertical flow layout arranges components in a directional flow, much like |
||||
* lines of text in a paragraph. VerticalFlow layouts are typically used to |
||||
* arrange buttons in a panel. It arranges buttons vertically until no more |
||||
* buttons fit on the same line. The line alignment is determined by the |
||||
* <code>align</code> property. The possible values are: |
||||
* <ul> |
||||
* <li>{@link #TOP TOP} |
||||
* <li>{@link #BOTTOM BOTTOM} |
||||
* <li>{@link #CENTER CENTER} |
||||
* </ul> |
||||
* A vertical flow layout lets each component assume its natural (preferred) |
||||
* size. |
||||
*/ |
||||
public class VerticalFlowLayout implements LayoutManager { |
||||
|
||||
/** |
||||
* This value indicates that each row of components should be top-justified. |
||||
*/ |
||||
public static final int TOP = 0; |
||||
|
||||
/** |
||||
* This value indicates that each row of components should be centered. |
||||
*/ |
||||
public static final int CENTER = 1; |
||||
|
||||
/** |
||||
* This value indicates that each row of components should be |
||||
* bottom-justified. |
||||
*/ |
||||
public static final int BOTTOM = 2; |
||||
|
||||
/** |
||||
* <code>align</code> is the property that determines how each column |
||||
* distributes empty space. It can be one of the following values: |
||||
* <ul> |
||||
* <li><code>TOP</code> |
||||
* <li><code>RIGHT</code> |
||||
* <li><code>BOTTOM</code> |
||||
* </ul> |
||||
* |
||||
* @see #getAlignment() |
||||
* @see #setAlignment(int) |
||||
*/ |
||||
private int align; |
||||
|
||||
/** |
||||
* The vertical flow layout manager allows a separation of components with |
||||
* gaps. The horizontal gap will specify the space between columns and |
||||
* between the columns and the borders of the <code>Container</code>. |
||||
* |
||||
* |
||||
* @see #getHgap() |
||||
* @see #setHgap(int) |
||||
*/ |
||||
private int hgap; |
||||
|
||||
/** |
||||
* The vertical flow layout manager allows a separation of components with |
||||
* gaps. The vertical gap will specify the space between components and |
||||
* between the components and the borders of the <code>Container</code>. |
||||
* |
||||
* @see #getVgap() |
||||
* @see #setVgap(int) |
||||
*/ |
||||
private int vgap; |
||||
|
||||
/** |
||||
* If true, components will be filled with <code>Container</code> |
||||
* horizontally. |
||||
* |
||||
* @see #isHfill() |
||||
* @see #setHfill(boolean) |
||||
*/ |
||||
private boolean hfill; |
||||
|
||||
/** |
||||
* Constructs a new <code>VerticalFlowLayout</code> with a centered |
||||
* alignment and a default 5-unit horizontal and vertical gaps and not |
||||
* filled with <code>Container</code> horizontally. |
||||
*/ |
||||
public VerticalFlowLayout() { |
||||
this(CENTER, 5, 5, false); |
||||
} |
||||
|
||||
/** |
||||
* Constructs a new <code>FlowLayout</code> with the specified alignment and |
||||
* a default 5-unit horizontal and vertical gaps and not filled with |
||||
* <code>Container</code> horizontally. The value of the alignment argument |
||||
* must be one of <code>FlowLayout.TOP</code>, |
||||
* <code>FlowLayout.BOTTOM</code>, <code>FlowLayout.CENTER</code>. |
||||
* |
||||
* @param align |
||||
* the alignment value |
||||
*/ |
||||
public VerticalFlowLayout(int align) { |
||||
this(align, 5, 5, false); |
||||
} |
||||
|
||||
/** |
||||
* Constructs a new <code>VerticalFlowLayout</code> with the indicated |
||||
* alignment and the indicated horizontal and vertical gaps and not filled |
||||
* with <code>Container</code> horizontally. |
||||
* <p> |
||||
* The value of the alignment argument must be one of |
||||
* <code>FlowLayout.TOP</code>, <code>FlowLayout.BOTTOM</code>, |
||||
* <code>FlowLayout.CENTER</code>. |
||||
* |
||||
* @param align |
||||
* the alignment value |
||||
* @param hgap |
||||
* the horizontal gap between columns and between the columns and |
||||
* the borders of the <code>Container</code> |
||||
* @param vgap |
||||
* the vertical gap between components and between the components |
||||
* and the borders of the <code>Container</code> |
||||
*/ |
||||
public VerticalFlowLayout(int align, int hgap, int vgap) { |
||||
this(align, hgap, vgap, false); |
||||
} |
||||
|
||||
/** |
||||
* Constructs a new <code>VerticalFlowLayout</code> with the indicated |
||||
* alignment and the indicated horizontal and vertical gaps and the |
||||
* indicated filled with <code>Container</code> horizontally. |
||||
* <p> |
||||
* The value of the alignment argument must be one of |
||||
* <code>FlowLayout.TOP</code>, <code>FlowLayout.BOTTOM</code>, |
||||
* <code>FlowLayout.CENTER</code>. |
||||
* |
||||
* @param align |
||||
* the alignment value |
||||
* @param hgap |
||||
* the horizontal gap between columns and between the columns and |
||||
* the borders of the <code>Container</code> |
||||
* @param vgap |
||||
* the vertical gap between components and between the components |
||||
* and the borders of the <code>Container</code> |
||||
* @param hfill |
||||
* the horizontal filling of components in the |
||||
* <code>Container</code> |
||||
*/ |
||||
public VerticalFlowLayout(int align, int hgap, int vgap, boolean hfill) { |
||||
this.align = align; |
||||
this.hgap = hgap; |
||||
this.vgap = vgap; |
||||
this.hfill = hfill; |
||||
} |
||||
|
||||
/** |
||||
* Gets the alignment for this layout. Possible values are |
||||
* <code>FlowLayout.TOP</code>, <code>FlowLayout.BOTTOM</code>, |
||||
* <code>FlowLayout.CENTER</code>. |
||||
* |
||||
* @return the alignment value for this layout |
||||
* @see #setAlignment(int) |
||||
*/ |
||||
public int getAlignment() { |
||||
return align; |
||||
} |
||||
|
||||
/** |
||||
* Sets the alignment for this layout. Possible values are |
||||
* <ul> |
||||
* <li><code>FlowLayout.TOP</code> |
||||
* <li><code>FlowLayout.BOTTOM</code> |
||||
* <li><code>FlowLayout.CENTER</code> |
||||
* </ul> |
||||
* |
||||
* @param align |
||||
* one of the alignment values shown above |
||||
* @see #getAlignment() |
||||
*/ |
||||
public void setAlignment(int align) { |
||||
this.align = align; |
||||
} |
||||
|
||||
/** |
||||
* Gets the horizontal gap between columns and between the columns and the |
||||
* borders of the <code>Container</code> |
||||
* |
||||
* @return the horizontal gap between columns and between the columns and |
||||
* the borders of the <code>Container</code> |
||||
* @see #setHgap(int) |
||||
*/ |
||||
public int getHgap() { |
||||
return hgap; |
||||
} |
||||
|
||||
/** |
||||
* Sets the horizontal gap between columns and between the columns and the |
||||
* borders of the <code>Container</code>. |
||||
* |
||||
* @param hgap |
||||
* the horizontal gap between columns and between the columns and |
||||
* the borders of the <code>Container</code> |
||||
* @see #getHgap() |
||||
*/ |
||||
public void setHgap(int hgap) { |
||||
this.hgap = hgap; |
||||
} |
||||
|
||||
/** |
||||
* Gets the vertical gap between components and between the components and |
||||
* the borders of the <code>Container</code>. |
||||
* |
||||
* @return the vertical gap between components and between the components |
||||
* and the borders of the <code>Container</code> |
||||
* @see #setVgap(int) |
||||
*/ |
||||
public int getVgap() { |
||||
return vgap; |
||||
} |
||||
|
||||
/** |
||||
* Sets the vertical gap between components and between the components and |
||||
* the borders of the <code>Container</code>. |
||||
* |
||||
* @param vgap |
||||
* the vertical gap between components and between the components |
||||
* and the borders of the <code>Container</code> |
||||
* @see #getVgap() |
||||
*/ |
||||
public void setVgap(int vgap) { |
||||
this.vgap = vgap; |
||||
} |
||||
|
||||
/** |
||||
* Gets the horizontal filling of components in the |
||||
* <code>Container</code>.The default is false. |
||||
* |
||||
* @return the horizontal filling of components in the |
||||
* <code>Container</code> |
||||
* @see #setHfill(boolean) |
||||
*/ |
||||
public boolean isHfill() { |
||||
return hfill; |
||||
} |
||||
|
||||
/** |
||||
* Sets the horizontal filling of components in the |
||||
* <code>Container</code>.The default is false. |
||||
* |
||||
* @param hfill |
||||
* the horizontal filling of components in the |
||||
* <code>Container</code> |
||||
* @see #isHfill() |
||||
*/ |
||||
public void setHfill(boolean hfill) { |
||||
this.hfill = hfill; |
||||
} |
||||
|
||||
/** |
||||
* Adds the specified component to the layout. Not used by this class. |
||||
* |
||||
* @param name |
||||
* the name of the component |
||||
* @param comp |
||||
* the component to be added |
||||
*/ |
||||
@Override |
||||
public void addLayoutComponent(String name, Component comp) { |
||||
} |
||||
|
||||
/** |
||||
* Removes the specified component from the layout. Not used by this class. |
||||
* |
||||
* @param comp |
||||
* the component to remove |
||||
*/ |
||||
@Override |
||||
public void removeLayoutComponent(Component comp) { |
||||
} |
||||
|
||||
/** |
||||
* Returns the preferred dimensions for this layout given the <i>visible</i> |
||||
* components in the specified target container. |
||||
* |
||||
* @param target |
||||
* the container that needs to be layout |
||||
* @return the preferred dimensions to layout the subcomponents of the |
||||
* specified container |
||||
* @see #minimumLayoutSize(Container) |
||||
*/ |
||||
@Override |
||||
public Dimension preferredLayoutSize(Container target) { |
||||
synchronized (target.getTreeLock()) { |
||||
Dimension dim = new Dimension(0, 0); |
||||
int nmembers = target.getComponentCount(); |
||||
boolean firstVisibleComponent = true; |
||||
for (int i = 0; i < nmembers; i++) { |
||||
Component m = target.getComponent(i); |
||||
if (m.isVisible()) { |
||||
Dimension d = m.getPreferredSize(); |
||||
dim.width = Math.max(dim.width, d.width); |
||||
if (firstVisibleComponent) { |
||||
firstVisibleComponent = false; |
||||
} else { |
||||
dim.height += vgap; |
||||
} |
||||
dim.height += d.height; |
||||
} |
||||
} |
||||
Insets insets = target.getInsets(); |
||||
dim.width += insets.left + insets.right + hgap * 2; |
||||
dim.height += insets.top + insets.bottom + vgap * 2; |
||||
return dim; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Returns the minimum dimensions needed to layout the <i>visible</i> |
||||
* components contained in the specified target container. |
||||
* |
||||
* @param target |
||||
* the container that needs to be layout |
||||
* @return the minimum dimensions to layout the sub components of the |
||||
* specified container |
||||
* @see #preferredLayoutSize(Container) |
||||
*/ |
||||
@Override |
||||
public Dimension minimumLayoutSize(Container target) { |
||||
synchronized (target.getTreeLock()) { |
||||
Dimension dim = new Dimension(0, 0); |
||||
int nmembers = target.getComponentCount(); |
||||
boolean firstVisibleComponent = true; |
||||
for (int i = 0; i < nmembers; i++) { |
||||
Component m = target.getComponent(i); |
||||
if (m.isVisible()) { |
||||
Dimension d = m.getMinimumSize(); |
||||
dim.width = Math.max(dim.width, d.width); |
||||
if (firstVisibleComponent) { |
||||
firstVisibleComponent = false; |
||||
} else { |
||||
dim.height += vgap; |
||||
} |
||||
dim.height += d.height; |
||||
} |
||||
} |
||||
Insets insets = target.getInsets(); |
||||
dim.width += insets.left + insets.right + hgap * 2; |
||||
dim.height += insets.top + insets.bottom + vgap * 2; |
||||
return dim; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Layout the container. This method lets each <i>visible</i> component take |
||||
* its preferred size by reshaping the components in the target container in |
||||
* order to satisfy the alignment of this <code>VerticalFlowLayout</code> |
||||
* object. |
||||
* |
||||
* @param target |
||||
* the specified component being layout |
||||
*/ |
||||
@Override |
||||
public void layoutContainer(Container target) { |
||||
synchronized (target.getTreeLock()) { |
||||
Insets insets = target.getInsets(); |
||||
int maxwidth = target.getWidth() - (insets.left + insets.right + hgap * 2); |
||||
int maxheight = target.getSize().height - (insets.top + insets.bottom + vgap * 2); |
||||
int nmembers = target.getComponentCount(); |
||||
int x = insets.left + hgap, y = 0; |
||||
int colw = 0, start = 0; |
||||
for (int i = 0; i < nmembers; i++) { |
||||
Component m = target.getComponent(i); |
||||
if (m.isVisible()) { |
||||
Dimension d = m.getPreferredSize(); |
||||
if (hfill) { |
||||
d.width = maxwidth; |
||||
} |
||||
m.setSize(d.width, d.height); |
||||
if ((y == 0) || ((y + d.height) <= maxheight)) { |
||||
if (y > 0) { |
||||
y += vgap; |
||||
} |
||||
y += d.height; |
||||
colw = Math.max(colw, d.width); |
||||
} else { |
||||
colw = moveComponents(target, x, insets.top + vgap, colw, maxheight - y, start, i); |
||||
y = d.height; |
||||
x += hgap + colw; |
||||
colw = d.width; |
||||
start = i; |
||||
} |
||||
} |
||||
} |
||||
moveComponents(target, x, insets.top + vgap, colw, maxheight - y, start, nmembers); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Centers the elements in the specified column, if there is any slack. |
||||
* |
||||
* @param target |
||||
* the component which needs to be moved |
||||
* @param x |
||||
* the x coordinate |
||||
* @param y |
||||
* the y coordinate |
||||
* @param width |
||||
* the width dimensions |
||||
* @param height |
||||
* the height dimensions |
||||
* @param colStart |
||||
* the beginning of the row |
||||
* @param colEnd |
||||
* the the ending of the row |
||||
* @return actual column width |
||||
*/ |
||||
private int moveComponents(Container target, int x, int y, int width, int height, int colStart, int colEnd) { |
||||
switch (align) { |
||||
case TOP: |
||||
y += 0; |
||||
break; |
||||
case CENTER: |
||||
y += height / 2; |
||||
break; |
||||
case BOTTOM: |
||||
y += height; |
||||
break; |
||||
} |
||||
for (int i = colStart; i < colEnd; i++) { |
||||
Component m = target.getComponent(i); |
||||
if (m.isVisible()) { |
||||
int cx = x + (width - m.getWidth()) / 2; |
||||
m.setLocation(cx, y); |
||||
y += m.getHeight() + vgap; |
||||
} |
||||
} |
||||
return width; |
||||
} |
||||
|
||||
/** |
||||
* Returns a string representation of this <code>VerticalFlowLayout</code> |
||||
* object and its values. |
||||
* |
||||
* @return a string representation of this layout |
||||
*/ |
||||
public String toString() { |
||||
String str = ""; |
||||
switch (align) { |
||||
case TOP: |
||||
str = ",align=top"; |
||||
break; |
||||
case CENTER: |
||||
str = ",align=center"; |
||||
break; |
||||
case BOTTOM: |
||||
str = ",align=bottom"; |
||||
break; |
||||
} |
||||
return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap + ",hfill=" + hfill + str + "]"; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,24 @@
|
||||
package com.tptj.tool.hg.fineui.swing.element.layout; |
||||
|
||||
import com.tptj.tool.hg.fineui.swing.element.Element; |
||||
import com.tptj.tool.hg.fineui.swing.element.layout.impl.AbsoluteLayout; |
||||
import javax.swing.*; |
||||
import java.awt.*; |
||||
/** |
||||
* @author 秃破天际 |
||||
* @version 10.0 |
||||
* Created by 秃破天际 on 2021/11/1 |
||||
**/ |
||||
public class AbsoluteType extends AbstractLayoutType { |
||||
|
||||
@Override |
||||
public LayoutManager init() { |
||||
return new AbsoluteLayout(element); |
||||
} |
||||
|
||||
@Override |
||||
public void layout(Element child, int idx) { |
||||
JComponent childComponent = child.getWrapper(); |
||||
element.getComponent().add(childComponent); |
||||
} |
||||
} |
@ -0,0 +1,21 @@
|
||||
package com.tptj.tool.hg.fineui.swing.element.layout; |
||||
|
||||
|
||||
import com.tptj.tool.hg.fineui.swing.element.Element; |
||||
|
||||
/** |
||||
* @author 秃破天际 |
||||
* @version 10.0 |
||||
* Created by 秃破天际 on 2021/11/1 |
||||
**/ |
||||
public abstract class AbstractLayoutType implements LayoutType { |
||||
|
||||
protected Element element; |
||||
|
||||
@Override |
||||
public void setElement(Element element) { |
||||
this.element = element; |
||||
} |
||||
|
||||
|
||||
} |
@ -0,0 +1,34 @@
|
||||
package com.tptj.tool.hg.fineui.swing.element.layout; |
||||
|
||||
import com.tptj.tool.hg.fineui.swing.element.Element; |
||||
|
||||
import javax.swing.*; |
||||
import java.awt.*; |
||||
|
||||
/** |
||||
* @author 秃破天际 |
||||
* @version 10.0 |
||||
* Created by 秃破天际 on 2021/11/1 |
||||
**/ |
||||
public class CenterAdaptType extends AbstractLayoutType { |
||||
@Override |
||||
public LayoutManager init() { |
||||
return new BoxLayout( element.getComponent(), BoxLayout.X_AXIS); |
||||
} |
||||
|
||||
@Override |
||||
public void layout(Element child,int idx ) { |
||||
JComponent component = element.getComponent(); |
||||
Box box = new Box(BoxLayout.Y_AXIS); |
||||
box.add(Box.createVerticalGlue()); |
||||
box.add( child.getWrapper() ); |
||||
box.add(Box.createVerticalGlue()); |
||||
if (idx == 0) { |
||||
component.add(Box.createHorizontalGlue()); |
||||
} |
||||
component.add(box); |
||||
if ( idx == element.children().size() - 1) { |
||||
component.add(Box.createHorizontalGlue()); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,28 @@
|
||||
package com.tptj.tool.hg.fineui.swing.element.layout; |
||||
|
||||
import com.tptj.tool.hg.fineui.swing.element.Element; |
||||
import com.tptj.tool.hg.fineui.swing.element.VerticalFlowLayout; |
||||
|
||||
import javax.swing.*; |
||||
import java.awt.*; |
||||
|
||||
/** |
||||
* @author 秃破天际 |
||||
* @version 10.0 |
||||
* Created by 秃破天际 on 2021/11/1 |
||||
**/ |
||||
public class HorizontalAdaptType extends AbstractLayoutType{ |
||||
@Override |
||||
public LayoutManager init() { |
||||
return new VerticalFlowLayout(VerticalFlowLayout.TOP, 0, 0, true); |
||||
} |
||||
|
||||
@Override |
||||
public void layout(Element child, int idx) { |
||||
Box box = new Box(BoxLayout.X_AXIS); |
||||
box.add(Box.createHorizontalGlue()); |
||||
box.add( child.getWrapper() ); |
||||
box.add(Box.createHorizontalGlue()); |
||||
element.getComponent().add(box); |
||||
} |
||||
} |
@ -0,0 +1,21 @@
|
||||
package com.tptj.tool.hg.fineui.swing.element.layout; |
||||
|
||||
import com.tptj.tool.hg.fineui.swing.element.Element; |
||||
|
||||
import javax.swing.*; |
||||
|
||||
/** |
||||
* @author 秃破天际 |
||||
* @version 10.0 |
||||
* Created by 秃破天际 on 2021/11/1 |
||||
**/ |
||||
public class HorizontalType extends CenterAdaptType{ |
||||
|
||||
@Override |
||||
public void layout(Element child, int idx) { |
||||
Box box = new Box(BoxLayout.Y_AXIS); |
||||
box.add(child.getWrapper()); |
||||
box.add(Box.createVerticalGlue()); |
||||
element.getComponent().add(box); |
||||
} |
||||
} |
@ -0,0 +1,52 @@
|
||||
package com.tptj.tool.hg.fineui.swing.element.layout; |
||||
|
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.tptj.tool.hg.fineui.swing.element.Element; |
||||
|
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* @author 秃破天际 |
||||
* @version 10.0 |
||||
* Created by 秃破天际 on 2021/11/1 |
||||
**/ |
||||
public class LayoutBuilder { |
||||
public static final String ABSOLUTE = "absolute"; |
||||
public static final String CENTER_ADAPT = "center_adapt"; |
||||
public static final String VERTICAL = "vertical"; |
||||
public static final String VERTICAL_ADAPT = "vertical_adapt"; |
||||
public static final String HORIZONTAL = "horizontal"; |
||||
public static final String HORIZONTAL_ADAPT = "horizontal_adapt"; |
||||
|
||||
private LayoutBuilder(){ |
||||
|
||||
} |
||||
private static final Map<String,Class<? extends LayoutType>> types = new HashMap<String,Class<? extends LayoutType>>(); |
||||
static{ |
||||
types.put(ABSOLUTE,AbsoluteType.class); |
||||
types.put(CENTER_ADAPT,CenterAdaptType.class); |
||||
types.put(VERTICAL,VerticalType.class); |
||||
types.put(VERTICAL_ADAPT,VerticalAdaptType.class); |
||||
types.put(HORIZONTAL,HorizontalType.class); |
||||
types.put(HORIZONTAL_ADAPT,HorizontalAdaptType.class); |
||||
} |
||||
|
||||
public static LayoutType layout(String type,Element element){ |
||||
Class<? extends LayoutType> layout_type = types.get(type); |
||||
if( null == layout_type ){ |
||||
FineLoggerFactory.getLogger().error("不支持的布局:{}",type); |
||||
layout_type = AbsoluteType.class; |
||||
} |
||||
try{ |
||||
LayoutType layout = layout_type.newInstance(); |
||||
layout.setElement(element); |
||||
return layout; |
||||
}catch(Exception e){ |
||||
FineLoggerFactory.getLogger().error(e,"布局失败{},{}",type,e.getMessage()); |
||||
} |
||||
AbsoluteType dft = new AbsoluteType(); |
||||
dft.setElement(element); |
||||
return dft; |
||||
} |
||||
} |
@ -0,0 +1,19 @@
|
||||
package com.tptj.tool.hg.fineui.swing.element.layout; |
||||
|
||||
import com.tptj.tool.hg.fineui.swing.element.Element; |
||||
|
||||
import java.awt.*; |
||||
|
||||
/** |
||||
* @author 秃破天际 |
||||
* @version 10.0 |
||||
* Created by 秃破天际 on 2021/11/1 |
||||
**/ |
||||
public interface LayoutType { |
||||
|
||||
LayoutManager init(); |
||||
|
||||
void layout( Element child,int idx ); |
||||
|
||||
void setElement( Element element ); |
||||
} |
@ -0,0 +1,21 @@
|
||||
package com.tptj.tool.hg.fineui.swing.element.layout; |
||||
|
||||
import com.tptj.tool.hg.fineui.swing.element.Element; |
||||
|
||||
import javax.swing.*; |
||||
|
||||
/** |
||||
* @author 秃破天际 |
||||
* @version 10.0 |
||||
* Created by 秃破天际 on 2021/11/1 |
||||
**/ |
||||
public class VerticalAdaptType extends CenterAdaptType { |
||||
@Override |
||||
public void layout(Element child, int idx ) { |
||||
Box box = new Box(BoxLayout.Y_AXIS); |
||||
box.add(Box.createVerticalGlue()); |
||||
box.add( child.getWrapper() ); |
||||
box.add(Box.createVerticalGlue()); |
||||
element.getComponent().add(box); |
||||
} |
||||
} |
@ -0,0 +1,23 @@
|
||||
package com.tptj.tool.hg.fineui.swing.element.layout; |
||||
|
||||
import com.tptj.tool.hg.fineui.swing.element.Element; |
||||
import com.tptj.tool.hg.fineui.swing.element.VerticalFlowLayout; |
||||
|
||||
import java.awt.*; |
||||
|
||||
/** |
||||
* @author 秃破天际 |
||||
* @version 10.0 |
||||
* Created by 秃破天际 on 2021/11/1 |
||||
**/ |
||||
public class VerticalType extends AbstractLayoutType{ |
||||
@Override |
||||
public LayoutManager init() { |
||||
return new VerticalFlowLayout(VerticalFlowLayout.TOP, 0, 0, true); |
||||
} |
||||
|
||||
@Override |
||||
public void layout(Element child, int idx) { |
||||
element.getComponent().add( child.getWrapper() ); |
||||
} |
||||
} |
@ -0,0 +1,52 @@
|
||||
package com.tptj.tool.hg.fineui.swing.element.layout.impl; |
||||
|
||||
import com.tptj.tool.hg.fineui.swing.element.Element; |
||||
|
||||
import java.awt.*; |
||||
|
||||
/** |
||||
* @author 秃破天际 |
||||
* @version 10.0 |
||||
* Created by 秃破天际 on 2021/11/1 |
||||
**/ |
||||
public class AbsoluteLayout extends BaseFineUILayout { |
||||
|
||||
public AbsoluteLayout(Element element) { |
||||
super(element); |
||||
} |
||||
|
||||
@Override |
||||
protected Rectangle getFineUIRect(Element child, int width, int height) { |
||||
Dimension size = child.getWrapper().getPreferredSize(); |
||||
int w = child.getRectStyleAttr("width",width,NOT_EXIST); |
||||
int h = child.getRectStyleAttr("height",height, NOT_EXIST); |
||||
int l = child.getRectStyleAttr("left",width, NOT_EXIST); |
||||
int r = child.getRectStyleAttr("right",width, NOT_EXIST); |
||||
int t = child.getRectStyleAttr("top",height, NOT_EXIST); |
||||
int b = child.getRectStyleAttr("bottom",height, NOT_EXIST); |
||||
Rectangle rt = new Rectangle(l,t,w,h); |
||||
if( w == NOT_EXIST ){ |
||||
if( l != NOT_EXIST && r != NOT_EXIST ){ |
||||
rt.width = width - l - r; |
||||
}else{ |
||||
rt.width = size.width; |
||||
} |
||||
} |
||||
if( h == NOT_EXIST ){ |
||||
if( t != NOT_EXIST && b != NOT_EXIST){ |
||||
rt.height = height - t - b; |
||||
}else{ |
||||
rt.height = size.height; |
||||
} |
||||
} |
||||
if( l == NOT_EXIST && r != NOT_EXIST ){ |
||||
rt.x = width - rt.width - r; |
||||
} |
||||
if( t == NOT_EXIST && b != NOT_EXIST){ |
||||
rt.y = height - rt.height - b; |
||||
} |
||||
//内外边距的计算可以在这里继续
|
||||
return rt; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,95 @@
|
||||
package com.tptj.tool.hg.fineui.swing.element.layout.impl; |
||||
|
||||
import com.tptj.tool.hg.fineui.swing.element.AbstractElement; |
||||
import com.tptj.tool.hg.fineui.swing.element.Element; |
||||
|
||||
import java.awt.*; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* @author 秃破天际 |
||||
* @version 10.0 |
||||
* Created by 秃破天际 on 2021/11/1 |
||||
**/ |
||||
public abstract class BaseFineUILayout implements LayoutManager2 { |
||||
public static final int NOT_EXIST = -99999; |
||||
protected Element element; |
||||
|
||||
public BaseFineUILayout(Element element){ |
||||
this.element = element; |
||||
} |
||||
|
||||
@Override |
||||
public void addLayoutComponent(Component comp, Object constraints) { |
||||
//不需要了
|
||||
} |
||||
|
||||
@Override |
||||
public Dimension maximumLayoutSize(Container target) { |
||||
return null; |
||||
} |
||||
|
||||
@Override |
||||
public float getLayoutAlignmentX(Container target) { |
||||
return 0; |
||||
} |
||||
|
||||
@Override |
||||
public float getLayoutAlignmentY(Container target) { |
||||
return 0; |
||||
} |
||||
|
||||
@Override |
||||
public void invalidateLayout(Container target) { |
||||
System.out.println(""); |
||||
} |
||||
|
||||
@Override |
||||
public void addLayoutComponent(String name, Component comp) { |
||||
//不需要了
|
||||
} |
||||
|
||||
@Override |
||||
public void removeLayoutComponent(Component comp) { |
||||
//暂时不需要了
|
||||
} |
||||
|
||||
@Override |
||||
public Dimension preferredLayoutSize(Container parent) { |
||||
List<AbstractElement> children = element.children(); |
||||
int p_width = 0; |
||||
int p_height = 0; |
||||
int width = parent.getParent().getWidth(); |
||||
int height = parent.getParent().getHeight(); |
||||
for( Element child : children ){ |
||||
Rectangle rect = getFineUIRect(child, width, height); |
||||
if( rect.x + rect.width > p_width ){ |
||||
p_width = rect.x + rect.width; |
||||
} |
||||
if( rect.y + rect.height > p_height ){ |
||||
p_height = rect.y + rect.height; |
||||
} |
||||
} |
||||
return new Dimension(p_width, p_height); |
||||
} |
||||
|
||||
@Override |
||||
public Dimension minimumLayoutSize(Container parent) { |
||||
return null; |
||||
} |
||||
|
||||
@Override |
||||
public void layoutContainer(Container parent) { |
||||
int width = parent.getWidth(); |
||||
int height = parent.getHeight(); |
||||
List<AbstractElement> children = element.children(); |
||||
for( Element child : children ){ |
||||
Rectangle rect = getFineUIRect(child, width, height); |
||||
child.getComponent().setBounds(rect.x,rect.y,rect.width,rect.height); |
||||
} |
||||
} |
||||
|
||||
protected abstract Rectangle getFineUIRect(Element child,int width,int height); |
||||
|
||||
|
||||
} |
@ -0,0 +1,58 @@
|
||||
package com.tptj.tool.hg.fineui.swing.stable; |
||||
|
||||
import com.fr.stable.StringUtils; |
||||
|
||||
import java.awt.*; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* @author 秃破天际 |
||||
* @version 10.0 |
||||
* Created by 秃破天际 on 2021/11/1 |
||||
* 颜色转换工具 |
||||
**/ |
||||
public class ColorUtils { |
||||
private static final Map<String,Color> colors = new HashMap<String,Color>(); |
||||
static{ |
||||
colors.put("YELLOW",Color.YELLOW); |
||||
colors.put("BLACK",Color.BLACK); |
||||
colors.put("BLUE",Color.BLUE); |
||||
colors.put("CYAN",Color.CYAN); |
||||
colors.put("DARK_GRAY",Color.DARK_GRAY); |
||||
colors.put("GRAY",Color.GRAY); |
||||
colors.put("GREEN",Color.GREEN); |
||||
colors.put("LIGHT_GRAY",Color.LIGHT_GRAY); |
||||
colors.put("MAGENTA",Color.MAGENTA); |
||||
colors.put("ORANGE",Color.ORANGE); |
||||
colors.put("PINK",Color.PINK); |
||||
colors.put("RED",Color.RED); |
||||
colors.put("WHITE",Color.WHITE); |
||||
} |
||||
public static Color str2Color(String str) { |
||||
if(StringUtils.isEmpty(str) ){ |
||||
return null; |
||||
} |
||||
str = str.toUpperCase().replaceAll(" ",""); |
||||
if( str.startsWith("#") ){ |
||||
str = str.substring(1); |
||||
if( str.length() < 5 ){ |
||||
StringBuilder sb = new StringBuilder(); |
||||
for( int i=0,len=str.length(); i<len; i++ ){ |
||||
sb.append( str.charAt(i) ).append( str.charAt(i) ); |
||||
} |
||||
str = sb.toString(); |
||||
} |
||||
return new Color( Integer.parseInt(str,16),str.length() == 8 ); |
||||
}else if( str.startsWith("RGB") ){ |
||||
str = str.substring(4,str.length()-1); |
||||
String [] parts = str.split(","); |
||||
return new Color( Integer.parseInt(parts[0]), Integer.parseInt(parts[1]), Integer.parseInt(parts[2]) ); |
||||
}else if( str.startsWith("RGBA") ){ |
||||
str = str.substring(5,str.length()-1); |
||||
String [] parts = str.split(","); |
||||
return new Color( Integer.parseInt(parts[0]), Integer.parseInt(parts[1]), Integer.parseInt(parts[2]) , Integer.parseInt(parts[3]) ); |
||||
} |
||||
return colors.get(str); |
||||
} |
||||
} |
@ -0,0 +1,10 @@
|
||||
BI.prepares.push(function () { |
||||
BI.Resizers = new BI.ResizeController(); |
||||
BI.Layers = new BI.LayerController(); |
||||
BI.Maskers = new BI.MaskersController(); |
||||
BI.Bubbles = new BI.BubblesController(); |
||||
BI.Tooltips = new BI.TooltipsController(); |
||||
BI.Popovers = new BI.PopoverController(); |
||||
BI.Broadcasts = new BI.BroadcastController(); |
||||
BI.StyleLoaders = new BI.StyleLoaderManager(); |
||||
}); |
@ -0,0 +1,152 @@
|
||||
/** |
||||
* 当没有元素时有提示信息的view |
||||
* |
||||
* Created by GUY on 2015/9/8. |
||||
* @class BI.Pane |
||||
* @extends BI.Widget |
||||
* @abstract |
||||
*/ |
||||
BI.Pane = BI.inherit(BI.Widget, { |
||||
|
||||
_defaultConfig: function () { |
||||
return BI.extend(BI.Pane.superclass._defaultConfig.apply(this, arguments), { |
||||
_baseCls: "bi-pane", |
||||
tipText: BI.i18nText("BI-No_Selected_Item"), |
||||
loadingText: "", |
||||
loadingSize: "small", |
||||
overlap: true, |
||||
onLoaded: BI.emptyFn |
||||
}); |
||||
}, |
||||
|
||||
_assertTip: function () { |
||||
var self = this, o = this.options; |
||||
if (!this._tipText) { |
||||
BI.createWidget({ |
||||
type: "bi.absolute_center_adapt", |
||||
element: this, |
||||
items: [{ |
||||
type: "bi.label", |
||||
ref: function (_ref) { |
||||
self._tipText = _ref; |
||||
}, |
||||
cls: "bi-tips", |
||||
text: o.tipText, |
||||
height: 25 |
||||
}] |
||||
}); |
||||
} |
||||
}, |
||||
|
||||
loading: function () { |
||||
var self = this, o = this.options; |
||||
var isIE = BI.isIE(); |
||||
var loadingAnimation = BI.createWidget({ |
||||
type: "bi.horizontal", |
||||
cls: "bi-loading-widget" + (isIE ? " wave-loading hack" : ""), |
||||
height: this._getSize(60), |
||||
width: this._getSize(60), |
||||
hgap: this._getSize(10), |
||||
vgap: 2.5, |
||||
items: isIE ? [] : [{ |
||||
type: "bi.layout", |
||||
cls: "animate-rect rect1", |
||||
height: this._getSize(50), |
||||
width: this._getSize(5) |
||||
}, { |
||||
type: "bi.layout", |
||||
cls: "animate-rect rect2", |
||||
height: this._getSize(50), |
||||
width: this._getSize(5) |
||||
}, { |
||||
type: "bi.layout", |
||||
cls: "animate-rect rect3", |
||||
height: this._getSize(50), |
||||
width: this._getSize(5) |
||||
}] |
||||
}); |
||||
// pane在同步方式下由items决定tipText的显示与否
|
||||
// loading的异步情况下由loaded后对面板的populate的时机决定
|
||||
this.setTipVisible(false); |
||||
if (o.overlap === true) { |
||||
if (!BI.Layers.has(this.getName() + "-loading")) { |
||||
BI.createWidget({ |
||||
type: "bi.center_adapt", |
||||
cls: "loading-container", |
||||
items: this._getLoadingTipItems(loadingAnimation), |
||||
element: BI.Layers.make(this.getName() + "-loading", this) |
||||
}); |
||||
} |
||||
BI.Layers.show(self.getName() + "-loading"); |
||||
} else if (BI.isNull(this._loading)) { |
||||
loadingAnimation.element.css("zIndex", 1); |
||||
BI.createWidget({ |
||||
type: "bi.center_adapt", |
||||
element: this, |
||||
cls: "loading-container", |
||||
items: this._getLoadingTipItems(loadingAnimation) |
||||
}); |
||||
} |
||||
self.fireEvent(BI.Pane.EVENT_LOADING); |
||||
this.element.addClass("loading-status"); |
||||
}, |
||||
|
||||
_getSize: function (v) { |
||||
return Math.ceil(v / (this.options.loadingSize === "small" ? 2 : 1)); |
||||
}, |
||||
|
||||
_getLoadingTipItems: function (loadingTip) { |
||||
var self = this, o = this.options; |
||||
var loadingTipItems = [{ |
||||
type: "bi.horizontal_adapt", |
||||
items: [loadingTip] |
||||
}]; |
||||
BI.isNotEmptyString(o.loadingText) && loadingTipItems.push({ |
||||
type: "bi.text", |
||||
text: o.loadingText, |
||||
tgap: this._getSize(10) |
||||
}); |
||||
|
||||
return [{ |
||||
type: "bi.vertical", |
||||
ref: function (_ref) { |
||||
self._loading = _ref; |
||||
}, |
||||
items: loadingTipItems |
||||
}]; |
||||
}, |
||||
|
||||
loaded: function () { |
||||
var self = this, o = this.options; |
||||
BI.Layers.remove(self.getName() + "-loading"); |
||||
this._loading && this._loading.destroy(); |
||||
o.onLoaded(); |
||||
self.fireEvent(BI.Pane.EVENT_LOADED); |
||||
this.element.removeClass("loading-status"); |
||||
}, |
||||
|
||||
check: function () { |
||||
this.setTipVisible(BI.isEmpty(this.options.items)); |
||||
}, |
||||
|
||||
setTipVisible: function (b) { |
||||
if (b === true) { |
||||
this._assertTip(); |
||||
this._tipText.setVisible(true); |
||||
} else { |
||||
this._tipText && this._tipText.setVisible(false); |
||||
} |
||||
}, |
||||
|
||||
setTipText: function (text) { |
||||
this._assertTip(); |
||||
this._tipText.setText(text); |
||||
}, |
||||
|
||||
populate: function (items) { |
||||
this.options.items = items || []; |
||||
this.check(); |
||||
} |
||||
}); |
||||
BI.Pane.EVENT_LOADED = "EVENT_LOADED"; |
||||
BI.Pane.EVENT_LOADING = "EVENT_LOADING"; |
@ -0,0 +1,38 @@
|
||||
/** |
||||
* @author windy |
||||
* @version 2.0 |
||||
* Created by windy on 2020/3/17 |
||||
*/ |
||||
|
||||
describe("CollectionTest", function () { |
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("collection", function () { |
||||
var items = []; |
||||
var cellCount = 100; |
||||
for (var i = 0; i < cellCount; i++) { |
||||
items[i] = { |
||||
type: "bi.label", |
||||
text: i |
||||
}; |
||||
} |
||||
var grid = BI.Test.createWidget({ |
||||
type: "bi.collection_view", |
||||
width: 400, |
||||
height: 300, |
||||
items: items, |
||||
cellSizeAndPositionGetter: function (index) { |
||||
return { |
||||
x: index % 10 * 50, |
||||
y: Math.floor(index / 10) * 50, |
||||
width: 50, |
||||
height: 50 |
||||
}; |
||||
} |
||||
}); |
||||
// TODO 列表展示类控件不知道该测什么,先标记一下
|
||||
grid.destroy(); |
||||
}); |
||||
}); |
@ -0,0 +1,379 @@
|
||||
/** |
||||
* CollectionView |
||||
* |
||||
* Created by GUY on 2016/1/15. |
||||
* @class BI.CollectionView |
||||
* @extends BI.Widget |
||||
*/ |
||||
BI.CollectionView = BI.inherit(BI.Widget, { |
||||
_defaultConfig: function () { |
||||
return BI.extend(BI.CollectionView.superclass._defaultConfig.apply(this, arguments), { |
||||
baseCls: "bi-collection", |
||||
// width: 400, //必设
|
||||
// height: 300, //必设
|
||||
overflowX: true, |
||||
overflowY: true, |
||||
cellSizeAndPositionGetter: BI.emptyFn, |
||||
horizontalOverscanSize: 0, |
||||
verticalOverscanSize: 0, |
||||
scrollLeft: 0, |
||||
scrollTop: 0, |
||||
items: [] |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var self = this, o = this.options; |
||||
this.renderedCells = []; |
||||
this.renderedKeys = []; |
||||
this.renderRange = {}; |
||||
this._scrollLock = false; |
||||
this._debounceRelease = BI.debounce(function () { |
||||
self._scrollLock = false; |
||||
}, 1000 / 60); |
||||
this.container = BI._lazyCreateWidget({ |
||||
type: "bi.absolute" |
||||
}); |
||||
this.element.scroll(function () { |
||||
if (self._scrollLock === true) { |
||||
return; |
||||
} |
||||
o.scrollLeft = self.element.scrollLeft(); |
||||
o.scrollTop = self.element.scrollTop(); |
||||
self._calculateChildrenToRender(); |
||||
self.fireEvent(BI.CollectionView.EVENT_SCROLL, { |
||||
scrollLeft: o.scrollLeft, |
||||
scrollTop: o.scrollTop |
||||
}); |
||||
}); |
||||
BI._lazyCreateWidget({ |
||||
type: "bi.vertical", |
||||
element: this, |
||||
scrollable: o.overflowX === true && o.overflowY === true, |
||||
scrolly: o.overflowX === false && o.overflowY === true, |
||||
scrollx: o.overflowX === true && o.overflowY === false, |
||||
items: [this.container] |
||||
}); |
||||
if (o.items.length > 0) { |
||||
this._calculateSizeAndPositionData(); |
||||
this._populate(); |
||||
} |
||||
}, |
||||
|
||||
// mounted之后绑定事件
|
||||
mounted: function () { |
||||
var o = this.options; |
||||
if (o.scrollLeft !== 0 || o.scrollTop !== 0) { |
||||
this.element.scrollTop(o.scrollTop); |
||||
this.element.scrollLeft(o.scrollLeft); |
||||
} |
||||
}, |
||||
|
||||
_calculateSizeAndPositionData: function () { |
||||
var o = this.options; |
||||
var cellMetadata = []; |
||||
var sectionManager = new BI.SectionManager(); |
||||
var height = 0; |
||||
var width = 0; |
||||
|
||||
for (var index = 0, len = o.items.length; index < len; index++) { |
||||
var cellMetadatum = o.cellSizeAndPositionGetter(index); |
||||
|
||||
if (cellMetadatum.height == null || isNaN(cellMetadatum.height) || |
||||
cellMetadatum.width == null || isNaN(cellMetadatum.width) || |
||||
cellMetadatum.x == null || isNaN(cellMetadatum.x) || |
||||
cellMetadatum.y == null || isNaN(cellMetadatum.y)) { |
||||
throw Error(); |
||||
} |
||||
|
||||
height = Math.max(height, cellMetadatum.y + cellMetadatum.height); |
||||
width = Math.max(width, cellMetadatum.x + cellMetadatum.width); |
||||
|
||||
cellMetadatum.index = index; |
||||
cellMetadata[index] = cellMetadatum; |
||||
sectionManager.registerCell(cellMetadatum, index); |
||||
} |
||||
|
||||
this._cellMetadata = cellMetadata; |
||||
this._sectionManager = sectionManager; |
||||
this._height = height; |
||||
this._width = width; |
||||
}, |
||||
|
||||
_cellRenderers: function (height, width, x, y) { |
||||
this._lastRenderedCellIndices = this._sectionManager.getCellIndices(height, width, x, y); |
||||
return this._cellGroupRenderer(); |
||||
}, |
||||
|
||||
_cellGroupRenderer: function () { |
||||
var self = this, o = this.options; |
||||
var rendered = []; |
||||
BI.each(this._lastRenderedCellIndices, function (i, index) { |
||||
var cellMetadata = self._sectionManager.getCellMetadata(index); |
||||
rendered.push(cellMetadata); |
||||
}); |
||||
return rendered; |
||||
}, |
||||
|
||||
_calculateChildrenToRender: function () { |
||||
var self = this, o = this.options; |
||||
var scrollLeft = BI.clamp(o.scrollLeft, 0, this._getMaxScrollLeft()); |
||||
var scrollTop = BI.clamp(o.scrollTop, 0, this._getMaxScrollTop()); |
||||
var left = Math.max(0, scrollLeft - o.horizontalOverscanSize); |
||||
var top = Math.max(0, scrollTop - o.verticalOverscanSize); |
||||
var right = Math.min(this._width, scrollLeft + o.width + o.horizontalOverscanSize); |
||||
var bottom = Math.min(this._height, scrollTop + o.height + o.verticalOverscanSize); |
||||
if (right > 0 && bottom > 0) { |
||||
// 如果滚动的区间并没有超出渲染的范围
|
||||
if (top >= this.renderRange.minY && bottom <= this.renderRange.maxY && left >= this.renderRange.minX && right <= this.renderRange.maxX) { |
||||
return; |
||||
} |
||||
var childrenToDisplay = this._cellRenderers(bottom - top, right - left, left, top); |
||||
var renderedCells = [], renderedKeys = {}, renderedWidgets = {}; |
||||
// 存储所有的left和top
|
||||
var lefts = {}, tops = {}; |
||||
for (var i = 0, len = childrenToDisplay.length; i < len; i++) { |
||||
var datum = childrenToDisplay[i]; |
||||
lefts[datum.x] = datum.x; |
||||
lefts[datum.x + datum.width] = datum.x + datum.width; |
||||
tops[datum.y] = datum.y; |
||||
tops[datum.y + datum.height] = datum.y + datum.height; |
||||
} |
||||
lefts = BI.toArray(lefts); |
||||
tops = BI.toArray(tops); |
||||
var leftMap = BI.invert(lefts); |
||||
var topMap = BI.invert(tops); |
||||
// 存储上下左右四个边界
|
||||
var leftBorder = {}, rightBorder = {}, topBorder = {}, bottomBorder = {}; |
||||
var assertMinBorder = function (border, offset) { |
||||
if (border[offset] == null) { |
||||
border[offset] = Number.MAX_VALUE; |
||||
} |
||||
}; |
||||
var assertMaxBorder = function (border, offset) { |
||||
if (border[offset] == null) { |
||||
border[offset] = 0; |
||||
} |
||||
}; |
||||
for (var i = 0, len = childrenToDisplay.length; i < len; i++) { |
||||
var datum = childrenToDisplay[i]; |
||||
var index = this.renderedKeys[datum.index] && this.renderedKeys[datum.index][1]; |
||||
var child; |
||||
if (index >= 0) { |
||||
// if (datum.width !== this.renderedCells[index]._width) {
|
||||
// this.renderedCells[index]._width = datum.width;
|
||||
this.renderedCells[index].el.setWidth(datum.width); |
||||
// }
|
||||
// if (datum.height !== this.renderedCells[index]._height) {
|
||||
// this.renderedCells[index]._height = datum.height;
|
||||
this.renderedCells[index].el.setHeight(datum.height); |
||||
// }
|
||||
// if (this.renderedCells[index]._left !== datum.x) {
|
||||
this.renderedCells[index].el.element.css("left", datum.x / BI.pixRatio + BI.pixUnit); |
||||
// }
|
||||
// if (this.renderedCells[index]._top !== datum.y) {
|
||||
this.renderedCells[index].el.element.css("top", datum.y / BI.pixRatio + BI.pixUnit); |
||||
// }
|
||||
renderedCells.push(child = this.renderedCells[index]); |
||||
} else { |
||||
child = BI._lazyCreateWidget(BI.extend({ |
||||
type: "bi.label", |
||||
width: datum.width, |
||||
height: datum.height |
||||
}, o.items[datum.index], { |
||||
cls: (o.items[datum.index].cls || "") + " collection-cell" + (datum.y === 0 ? " first-row" : "") + (datum.x === 0 ? " first-col" : ""), |
||||
_left: datum.x, |
||||
_top: datum.y |
||||
})); |
||||
renderedCells.push({ |
||||
el: child, |
||||
left: datum.x, |
||||
top: datum.y, |
||||
_left: datum.x, |
||||
_top: datum.y, |
||||
// _width: datum.width,
|
||||
// _height: datum.height
|
||||
}); |
||||
} |
||||
var startTopIndex = topMap[datum.y] | 0; |
||||
var endTopIndex = topMap[datum.y + datum.height] | 0; |
||||
for (var k = startTopIndex; k <= endTopIndex; k++) { |
||||
var t = tops[k]; |
||||
assertMinBorder(leftBorder, t); |
||||
assertMaxBorder(rightBorder, t); |
||||
leftBorder[t] = Math.min(leftBorder[t], datum.x); |
||||
rightBorder[t] = Math.max(rightBorder[t], datum.x + datum.width); |
||||
} |
||||
var startLeftIndex = leftMap[datum.x] | 0; |
||||
var endLeftIndex = leftMap[datum.x + datum.width] | 0; |
||||
for (var k = startLeftIndex; k <= endLeftIndex; k++) { |
||||
var l = lefts[k]; |
||||
assertMinBorder(topBorder, l); |
||||
assertMaxBorder(bottomBorder, l); |
||||
topBorder[l] = Math.min(topBorder[l], datum.y); |
||||
bottomBorder[l] = Math.max(bottomBorder[l], datum.y + datum.height); |
||||
} |
||||
|
||||
renderedKeys[datum.index] = [datum.index, i]; |
||||
renderedWidgets[i] = child; |
||||
} |
||||
// 已存在的, 需要添加的和需要删除的
|
||||
var existSet = {}, addSet = {}, deleteArray = []; |
||||
BI.each(renderedKeys, function (i, key) { |
||||
if (self.renderedKeys[i]) { |
||||
existSet[i] = key; |
||||
} else { |
||||
addSet[i] = key; |
||||
} |
||||
}); |
||||
BI.each(this.renderedKeys, function (i, key) { |
||||
if (existSet[i]) { |
||||
return; |
||||
} |
||||
if (addSet[i]) { |
||||
return; |
||||
} |
||||
deleteArray.push(key[1]); |
||||
}); |
||||
BI.each(deleteArray, function (i, index) { |
||||
// 性能优化,不调用destroy方法防止触发destroy事件
|
||||
self.renderedCells[index].el._destroy(); |
||||
}); |
||||
var addedItems = []; |
||||
BI.each(addSet, function (index, key) { |
||||
addedItems.push(renderedCells[key[1]]); |
||||
}); |
||||
this.container.addItems(addedItems); |
||||
// 拦截父子级关系
|
||||
this.container._children = renderedWidgets; |
||||
this.container.attr("items", renderedCells); |
||||
this.renderedCells = renderedCells; |
||||
this.renderedKeys = renderedKeys; |
||||
|
||||
// Todo 左右比较特殊
|
||||
var minX = BI.min(leftBorder); |
||||
var maxX = BI.max(rightBorder); |
||||
|
||||
var minY = BI.max(topBorder); |
||||
var maxY = BI.min(bottomBorder); |
||||
|
||||
this.renderRange = {minX: minX, minY: minY, maxX: maxX, maxY: maxY}; |
||||
} |
||||
}, |
||||
|
||||
_getMaxScrollLeft: function () { |
||||
return Math.max(0, this._width - this.options.width + (this.options.overflowX ? BI.DOM.getScrollWidth() : 0)); |
||||
}, |
||||
|
||||
_getMaxScrollTop: function () { |
||||
return Math.max(0, this._height - this.options.height + (this.options.overflowY ? BI.DOM.getScrollWidth() : 0)); |
||||
}, |
||||
|
||||
_populate: function (items) { |
||||
var o = this.options; |
||||
this._reRange(); |
||||
if (items && items !== this.options.items) { |
||||
this.options.items = items; |
||||
this._calculateSizeAndPositionData(); |
||||
} |
||||
this.container.setWidth(this._width); |
||||
this.container.setHeight(this._height); |
||||
|
||||
this._debounceRelease(); |
||||
// 元素未挂载时不能设置scrollTop
|
||||
try { |
||||
this.element.scrollTop(o.scrollTop); |
||||
this.element.scrollLeft(o.scrollLeft); |
||||
} catch (e) { |
||||
} |
||||
this._calculateChildrenToRender(); |
||||
}, |
||||
|
||||
setScrollLeft: function (scrollLeft) { |
||||
if (this.options.scrollLeft === scrollLeft) { |
||||
return; |
||||
} |
||||
this._scrollLock = true; |
||||
this.options.scrollLeft = BI.clamp(scrollLeft || 0, 0, this._getMaxScrollLeft()); |
||||
this._debounceRelease(); |
||||
this.element.scrollLeft(this.options.scrollLeft); |
||||
this._calculateChildrenToRender(); |
||||
}, |
||||
|
||||
setScrollTop: function (scrollTop) { |
||||
if (this.options.scrollTop === scrollTop) { |
||||
return; |
||||
} |
||||
this._scrollLock = true; |
||||
this.options.scrollTop = BI.clamp(scrollTop || 0, 0, this._getMaxScrollTop()); |
||||
this._debounceRelease(); |
||||
this.element.scrollTop(this.options.scrollTop); |
||||
this._calculateChildrenToRender(); |
||||
}, |
||||
|
||||
setOverflowX: function (b) { |
||||
var self = this; |
||||
if (this.options.overflowX !== !!b) { |
||||
this.options.overflowX = !!b; |
||||
BI.nextTick(function () { |
||||
self.element.css({overflowX: b ? "auto" : "hidden"}); |
||||
}); |
||||
} |
||||
}, |
||||
|
||||
setOverflowY: function (b) { |
||||
var self = this; |
||||
if (this.options.overflowY !== !!b) { |
||||
this.options.overflowY = !!b; |
||||
BI.nextTick(function () { |
||||
self.element.css({overflowY: b ? "auto" : "hidden"}); |
||||
}); |
||||
} |
||||
}, |
||||
|
||||
getScrollLeft: function () { |
||||
return this.options.scrollLeft; |
||||
}, |
||||
|
||||
getScrollTop: function () { |
||||
return this.options.scrollTop; |
||||
}, |
||||
|
||||
getMaxScrollLeft: function () { |
||||
return this._getMaxScrollLeft(); |
||||
}, |
||||
|
||||
getMaxScrollTop: function () { |
||||
return this._getMaxScrollTop(); |
||||
}, |
||||
|
||||
// 重新计算children
|
||||
_reRange: function () { |
||||
this.renderRange = {}; |
||||
}, |
||||
|
||||
_clearChildren: function () { |
||||
this.container._children = {}; |
||||
this.container.attr("items", []); |
||||
}, |
||||
|
||||
restore: function () { |
||||
BI.each(this.renderedCells, function (i, cell) { |
||||
cell.el._destroy(); |
||||
}); |
||||
this._clearChildren(); |
||||
this.renderedCells = []; |
||||
this.renderedKeys = []; |
||||
this.renderRange = {}; |
||||
this._scrollLock = false; |
||||
}, |
||||
|
||||
populate: function (items) { |
||||
if (items && items !== this.options.items) { |
||||
this.restore(); |
||||
} |
||||
this._populate(items); |
||||
} |
||||
}); |
||||
BI.CollectionView.EVENT_SCROLL = "EVENT_SCROLL"; |
||||
BI.shortcut("bi.collection_view", BI.CollectionView); |
@ -0,0 +1,585 @@
|
||||
!(function () { |
||||
var needHideWhenAnotherComboOpen = {}; |
||||
/** |
||||
* @class BI.Combo |
||||
* @extends BI.Widget |
||||
*/ |
||||
BI.Combo = BI.inherit(BI.Widget, { |
||||
_defaultConfig: function () { |
||||
var conf = BI.Combo.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend(conf, { |
||||
baseCls: (conf.baseCls || "") + " bi-combo" + (BI.isIE() ? " hack" : ""), |
||||
attributes: { |
||||
tabIndex: -1 |
||||
}, |
||||
trigger: "click", // click || hover || click-hover || ""
|
||||
toggle: true, |
||||
direction: "bottom", // top||bottom||left||right||top,left||top,right||bottom,left||bottom,right||right,innerRight||right,innerLeft||innerRight||innerLeft
|
||||
logic: { |
||||
dynamic: true |
||||
}, |
||||
container: null, // popupview放置的容器,默认为this.element
|
||||
isDefaultInit: false, |
||||
destroyWhenHide: false, |
||||
hideWhenBlur: true, |
||||
hideWhenAnotherComboOpen: false, |
||||
isNeedAdjustHeight: true, // 是否需要高度调整
|
||||
isNeedAdjustWidth: true, |
||||
stopEvent: false, |
||||
stopPropagation: false, |
||||
adjustLength: 0, // 调整的距离
|
||||
adjustXOffset: 0, |
||||
adjustYOffset: 0, |
||||
hideChecker: BI.emptyFn, |
||||
offsetStyle: "left", // left,right,center
|
||||
el: {}, |
||||
popup: {}, |
||||
comboClass: "bi-combo-popup", |
||||
hoverClass: "bi-combo-hover", |
||||
belowMouse: false |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var self = this, o = this.options; |
||||
this._initCombo(); |
||||
this._initPullDownAction(); |
||||
this.combo.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { |
||||
if (self.isEnabled() && self.isValid()) { |
||||
if (type === BI.Events.EXPAND) { |
||||
self._popupView(); |
||||
} |
||||
if (type === BI.Events.COLLAPSE) { |
||||
self._hideView(); |
||||
} |
||||
if (type === BI.Events.EXPAND) { |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); |
||||
self.fireEvent(BI.Combo.EVENT_EXPAND); |
||||
} |
||||
if (type === BI.Events.COLLAPSE) { |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); |
||||
self.isViewVisible() && self.fireEvent(BI.Combo.EVENT_COLLAPSE); |
||||
} |
||||
if (type === BI.Events.CLICK) { |
||||
self.fireEvent(BI.Combo.EVENT_TRIGGER_CHANGE, obj); |
||||
} |
||||
} |
||||
}); |
||||
|
||||
self.element.on("mouseenter." + self.getName(), function (e) { |
||||
if (self.isEnabled() && self.isValid() && self.combo.isEnabled() && self.combo.isValid()) { |
||||
self.element.addClass(o.hoverClass); |
||||
} |
||||
}); |
||||
self.element.on("mouseleave." + self.getName(), function (e) { |
||||
if (self.isEnabled() && self.isValid() && self.combo.isEnabled() && self.combo.isValid()) { |
||||
self.element.removeClass(o.hoverClass); |
||||
} |
||||
}); |
||||
|
||||
BI.createWidget(BI.extend({ |
||||
element: this |
||||
}, BI.LogicFactory.createLogic("vertical", BI.extend(o.logic, { |
||||
items: [ |
||||
{ el: this.combo } |
||||
] |
||||
})))); |
||||
o.isDefaultInit && (this._assertPopupView()); |
||||
BI.Resizers.add(this.getName(), BI.bind(function (e) { |
||||
// 如果resize对象是combo的子元素,则不应该收起,或交由hideChecker去处理
|
||||
if (this.isViewVisible()) { |
||||
BI.isNotNull(e) ? this._hideIf(e) : this._hideView(); |
||||
} |
||||
}, this)); |
||||
}, |
||||
|
||||
_toggle: function (e) { |
||||
this._assertPopupViewRender(); |
||||
if (this.popupView.isVisible()) { |
||||
this._hideView(e); |
||||
} else { |
||||
if (this.isEnabled()) { |
||||
this._popupView(e); |
||||
} |
||||
} |
||||
}, |
||||
|
||||
_initPullDownAction: function () { |
||||
var self = this, o = this.options; |
||||
var evs = (this.options.trigger || "").split(","); |
||||
var st = function (e) { |
||||
if (o.stopEvent) { |
||||
e.stopEvent(); |
||||
} |
||||
if (o.stopPropagation) { |
||||
e.stopPropagation(); |
||||
} |
||||
}; |
||||
|
||||
var enterPopup = false; |
||||
|
||||
function hide(e) { |
||||
if (self.isEnabled() && self.isValid() && self.combo.isEnabled() && self.combo.isValid() && o.toggle === true) { |
||||
self._hideView(e); |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", self.combo); |
||||
self.fireEvent(BI.Combo.EVENT_COLLAPSE); |
||||
} |
||||
self.popupView && self.popupView.element.off("mouseenter." + self.getName()).off("mouseleave." + self.getName()); |
||||
enterPopup = false; |
||||
} |
||||
|
||||
BI.each(evs, function (i, ev) { |
||||
switch (ev) { |
||||
case "hover": |
||||
self.element.on("mouseenter." + self.getName(), function (e) { |
||||
if (self.isEnabled() && self.isValid() && self.combo.isEnabled() && self.combo.isValid()) { |
||||
self._popupView(e); |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.combo); |
||||
self.fireEvent(BI.Combo.EVENT_EXPAND); |
||||
} |
||||
}); |
||||
self.element.on("mouseleave." + self.getName(), function (e) { |
||||
if (self.popupView) { |
||||
self.popupView.element.on("mouseenter." + self.getName(), function (e) { |
||||
enterPopup = true; |
||||
self.popupView.element.on("mouseleave." + self.getName(), function (e) { |
||||
hide(e); |
||||
}); |
||||
self.popupView.element.off("mouseenter." + self.getName()); |
||||
}); |
||||
BI.defer(function () { |
||||
if (!enterPopup) { |
||||
hide(e); |
||||
} |
||||
}, 50); |
||||
} |
||||
}); |
||||
break; |
||||
case "click": |
||||
var debounce = BI.debounce(function (e) { |
||||
if (self.combo.element.__isMouseInBounds__(e)) { |
||||
if (self.isEnabled() && self.isValid() && self.combo.isEnabled() && self.combo.isValid()) { |
||||
// if (!o.toggle && self.isViewVisible()) {
|
||||
// return;
|
||||
// }
|
||||
o.toggle ? self._toggle(e) : self._popupView(e); |
||||
if (self.isViewVisible()) { |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.combo); |
||||
self.fireEvent(BI.Combo.EVENT_EXPAND); |
||||
} else { |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", self.combo); |
||||
self.fireEvent(BI.Combo.EVENT_COLLAPSE); |
||||
} |
||||
} |
||||
} |
||||
}, BI.EVENT_RESPONSE_TIME, { |
||||
"leading": true, |
||||
"trailing": false |
||||
}); |
||||
self.element.off(ev + "." + self.getName()).on(ev + "." + self.getName(), function (e) { |
||||
debounce(e); |
||||
st(e); |
||||
}); |
||||
break; |
||||
case "click-hover": |
||||
var debounce = BI.debounce(function (e) { |
||||
if (self.combo.element.__isMouseInBounds__(e)) { |
||||
if (self.isEnabled() && self.isValid() && self.combo.isEnabled() && self.combo.isValid()) { |
||||
// if (self.isViewVisible()) {
|
||||
// return;
|
||||
// }
|
||||
self._popupView(e); |
||||
if (self.isViewVisible()) { |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.combo); |
||||
self.fireEvent(BI.Combo.EVENT_EXPAND); |
||||
} |
||||
} |
||||
} |
||||
}, BI.EVENT_RESPONSE_TIME, { |
||||
"leading": true, |
||||
"trailing": false |
||||
}); |
||||
self.element.off("click." + self.getName()).on("click." + self.getName(), function (e) { |
||||
debounce(e); |
||||
st(e); |
||||
}); |
||||
self.element.on("mouseleave." + self.getName(), function (e) { |
||||
if (self.popupView) { |
||||
self.popupView.element.on("mouseenter." + self.getName(), function (e) { |
||||
enterPopup = true; |
||||
self.popupView.element.on("mouseleave." + self.getName(), function (e) { |
||||
hide(e); |
||||
}); |
||||
self.popupView.element.off("mouseenter." + self.getName()); |
||||
}); |
||||
BI.delay(function () { |
||||
if (!enterPopup) { |
||||
hide(e); |
||||
} |
||||
}, 50); |
||||
} |
||||
}); |
||||
break; |
||||
} |
||||
}); |
||||
}, |
||||
|
||||
_initCombo: function () { |
||||
this.combo = BI.createWidget(this.options.el, { |
||||
value: this.options.value |
||||
}); |
||||
}, |
||||
|
||||
_assertPopupView: function () { |
||||
var self = this, o = this.options; |
||||
if (this.popupView == null) { |
||||
this.popupView = BI.createWidget(this.options.popup, { |
||||
type: "bi.popup_view", |
||||
value: o.value |
||||
}, this); |
||||
this.popupView.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { |
||||
if (type === BI.Events.CLICK) { |
||||
self.combo.setValue(self.getValue()); |
||||
self.fireEvent(BI.Combo.EVENT_CHANGE, value, obj); |
||||
} |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); |
||||
}); |
||||
this.popupView.setVisible(false); |
||||
BI.nextTick(function () { |
||||
self.fireEvent(BI.Combo.EVENT_AFTER_INIT); |
||||
}); |
||||
} |
||||
}, |
||||
|
||||
_assertPopupViewRender: function () { |
||||
this._assertPopupView(); |
||||
if (!this._rendered) { |
||||
BI.createWidget({ |
||||
type: "bi.vertical", |
||||
scrolly: false, |
||||
element: this.options.container || this, |
||||
items: [ |
||||
{ el: this.popupView } |
||||
] |
||||
}); |
||||
this._rendered = true; |
||||
} |
||||
}, |
||||
|
||||
_hideIf: function (e, skipTriggerChecker) { |
||||
// if (this.element.__isMouseInBounds__(e) || (this.popupView && this.popupView.element.__isMouseInBounds__(e))) {
|
||||
// return;
|
||||
// }
|
||||
// BI-10290 公式combo双击公式内容会收起
|
||||
if (e && ((skipTriggerChecker !== true && this.element.find(e.target).length > 0) |
||||
|| (this.popupView && this.popupView.element.find(e.target).length > 0) |
||||
|| e.target.className === "CodeMirror-cursor" || BI.Widget._renderEngine.createElement(e.target).closest(".CodeMirror-hints").length > 0)) {// BI-9887 CodeMirror的公式弹框需要特殊处理下
|
||||
var directions = this.options.direction.split(","); |
||||
if (BI.contains(directions, "innerLeft") || BI.contains(directions, "innerRight")) { |
||||
// popup可以出现在trigger内部的combo,滚动时不需要消失,而是调整位置
|
||||
this.adjustWidth(); |
||||
this.adjustHeight(); |
||||
} |
||||
|
||||
return; |
||||
} |
||||
var isHide = this.options.hideChecker.apply(this, [e]); |
||||
if (isHide === false) { |
||||
return; |
||||
} |
||||
this._hideView(e); |
||||
return true; |
||||
}, |
||||
|
||||
_hideView: function (e) { |
||||
var o = this.options; |
||||
this.fireEvent(BI.Combo.EVENT_BEFORE_HIDEVIEW); |
||||
if (this.options.destroyWhenHide === true) { |
||||
this.popupView && this.popupView.destroy(); |
||||
this.popupView = null; |
||||
this._rendered = false; |
||||
} else { |
||||
this.popupView && this.popupView.invisible(); |
||||
} |
||||
|
||||
if (!e || !this.combo.element.__isMouseInBounds__(e)) { |
||||
this.element.removeClass(this.options.hoverClass); |
||||
// 应对bi-focus-shadow在收起时不失焦
|
||||
this.element.blur(); |
||||
} |
||||
|
||||
this.element.removeClass(this.options.comboClass); |
||||
delete needHideWhenAnotherComboOpen[this.getName()]; |
||||
|
||||
BI.Widget._renderEngine.createElement(document).unbind("mousedown." + this.getName()).unbind("mousewheel." + this.getName()); |
||||
o.hideWhenBlur && BI.Widget._renderEngine.createElement(window).unbind("blur." + this.getName()); |
||||
this.fireEvent(BI.Combo.EVENT_AFTER_HIDEVIEW); |
||||
}, |
||||
|
||||
_popupView: function (e) { |
||||
var self = this, o = this.options; |
||||
this._assertPopupViewRender(); |
||||
this.fireEvent(BI.Combo.EVENT_BEFORE_POPUPVIEW); |
||||
// popupVisible是为了获取其宽高, 放到可视范围之外以防止在IE下闪一下
|
||||
this.popupView.css({ left: -999999999, top: -99999999 }); |
||||
this.popupView.visible(); |
||||
BI.each(needHideWhenAnotherComboOpen, function (i, combo) { |
||||
if (i !== self.getName()) { |
||||
if (combo && combo._hideIf(e, true) === true) { |
||||
delete needHideWhenAnotherComboOpen[i]; |
||||
} |
||||
} |
||||
}); |
||||
this.options.hideWhenAnotherComboOpen && (needHideWhenAnotherComboOpen[this.getName()] = this); |
||||
this.adjustWidth(e); |
||||
this.adjustHeight(e); |
||||
|
||||
this.element.addClass(this.options.comboClass); |
||||
BI.Widget._renderEngine.createElement(document).unbind("mousedown." + this.getName()).unbind("mousewheel." + this.getName()); |
||||
o.hideWhenBlur && BI.Widget._renderEngine.createElement(window).unbind("blur." + this.getName()); |
||||
|
||||
BI.Widget._renderEngine.createElement(document).bind("mousedown." + this.getName(), BI.bind(this._hideIf, this)).bind("mousewheel." + this.getName(), BI.bind(this._hideIf, this)); |
||||
o.hideWhenBlur && BI.Widget._renderEngine.createElement(window).bind("blur." + this.getName(), BI.bind(this._hideIf, this)); |
||||
this.fireEvent(BI.Combo.EVENT_AFTER_POPUPVIEW); |
||||
}, |
||||
|
||||
adjustWidth: function (e) { |
||||
var o = this.options; |
||||
if (!this.popupView) { |
||||
return; |
||||
} |
||||
if (o.isNeedAdjustWidth === true) { |
||||
this.resetListWidth(""); |
||||
var width = this.popupView.element.outerWidth(); |
||||
var maxW = this.element.outerWidth() || o.width; |
||||
// BI-93885 最大列宽算法调整
|
||||
if (maxW < 500) { |
||||
if (width >= 500) { |
||||
maxW = 500; |
||||
} else if(width > maxW) { |
||||
// 防止小数导致差那么一点
|
||||
maxW = width + 1; |
||||
} |
||||
} |
||||
|
||||
// if (width > maxW + 80) {
|
||||
// maxW = maxW + 80;
|
||||
// } else if (width > maxW) {
|
||||
// maxW = width;
|
||||
// }
|
||||
this.resetListWidth(maxW < 100 ? 100 : maxW); |
||||
} |
||||
}, |
||||
|
||||
adjustHeight: function (e) { |
||||
var o = this.options, p = {}; |
||||
if (!this.popupView) { |
||||
return; |
||||
} |
||||
var isVisible = this.popupView.isVisible(); |
||||
this.popupView.visible(); |
||||
var combo = (o.belowMouse && BI.isNotNull(e)) ? { |
||||
element: { |
||||
offset: function () { |
||||
return { |
||||
left: e.pageX, |
||||
top: e.pageY |
||||
}; |
||||
}, |
||||
bounds: function () { |
||||
// offset为其相对于父定位元素的偏移
|
||||
return { |
||||
x: e.offsetX, |
||||
y: e.offsetY, |
||||
width: 0, |
||||
height: 24 |
||||
}; |
||||
}, |
||||
outerWidth: function () { |
||||
return 0; |
||||
}, |
||||
outerHeight: function () { |
||||
return 24; |
||||
} |
||||
} |
||||
} : this.combo; |
||||
switch (o.direction) { |
||||
case "bottom": |
||||
case "bottom,right": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, o.adjustXOffset, o.adjustYOffset || o.adjustLength, o.isNeedAdjustHeight, ["bottom", "top", "right", "left"], o.offsetStyle); |
||||
break; |
||||
case "top": |
||||
case "top,right": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, o.adjustXOffset, o.adjustYOffset || o.adjustLength, o.isNeedAdjustHeight, ["top", "bottom", "right", "left"], o.offsetStyle); |
||||
break; |
||||
case "left": |
||||
case "left,bottom": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, o.adjustXOffset || o.adjustLength, o.adjustYOffset, o.isNeedAdjustHeight, ["left", "right", "bottom", "top"], o.offsetStyle); |
||||
break; |
||||
case "right": |
||||
case "right,bottom": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, o.adjustXOffset || o.adjustLength, o.adjustYOffset, o.isNeedAdjustHeight, ["right", "left", "bottom", "top"], o.offsetStyle); |
||||
break; |
||||
case "top,left": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, o.adjustXOffset, o.adjustYOffset || o.adjustLength, o.isNeedAdjustHeight, ["top", "bottom", "left", "right"], o.offsetStyle); |
||||
break; |
||||
case "bottom,left": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, o.adjustXOffset, o.adjustYOffset || o.adjustLength, o.isNeedAdjustHeight, ["bottom", "top", "left", "right"], o.offsetStyle); |
||||
break; |
||||
case "left,top": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, o.adjustXOffset || o.adjustLength, o.adjustYOffset, o.isNeedAdjustHeight, ["left", "right", "top", "bottom"], o.offsetStyle); |
||||
break; |
||||
case "right,top": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, o.adjustXOffset || o.adjustLength, o.adjustYOffset, o.isNeedAdjustHeight, ["right", "left", "top", "bottom"], o.offsetStyle); |
||||
break; |
||||
case "right,innerRight": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, o.adjustXOffset || o.adjustLength, o.adjustYOffset, o.isNeedAdjustHeight, ["right", "left", "innerRight", "innerLeft", "bottom", "top"], o.offsetStyle); |
||||
break; |
||||
case "right,innerLeft": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, o.adjustXOffset || o.adjustLength, o.adjustYOffset, o.isNeedAdjustHeight, ["right", "left", "innerLeft", "innerRight", "bottom", "top"], o.offsetStyle); |
||||
break; |
||||
case "innerRight": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, o.adjustXOffset || o.adjustLength, o.adjustYOffset, o.isNeedAdjustHeight, ["innerRight", "innerLeft", "right", "left", "bottom", "top"], o.offsetStyle); |
||||
break; |
||||
case "innerLeft": |
||||
p = BI.DOM.getComboPosition(combo, this.popupView, o.adjustXOffset || o.adjustLength, o.adjustYOffset, o.isNeedAdjustHeight, ["innerLeft", "innerRight", "left", "right", "bottom", "top"], o.offsetStyle); |
||||
break; |
||||
case "top,custom": |
||||
case "custom,top": |
||||
p = BI.DOM.getTopAdaptPosition(combo, this.popupView, o.adjustYOffset || o.adjustLength, o.isNeedAdjustHeight); |
||||
break; |
||||
case "custom,bottom": |
||||
case "bottom,custom": |
||||
p = BI.DOM.getBottomAdaptPosition(combo, this.popupView, o.adjustYOffset || o.adjustLength, o.isNeedAdjustHeight); |
||||
break; |
||||
case "left,custom": |
||||
case "custom,left": |
||||
p = BI.DOM.getLeftAdaptPosition(combo, this.popupView, o.adjustXOffset || o.adjustLength); |
||||
delete p.top; |
||||
delete p.adaptHeight; |
||||
break; |
||||
case "custom,right": |
||||
case "right,custom": |
||||
p = BI.DOM.getRightAdaptPosition(combo, this.popupView, o.adjustXOffset || o.adjustLength); |
||||
delete p.top; |
||||
delete p.adaptHeight; |
||||
break; |
||||
} |
||||
|
||||
if ("adaptHeight" in p) { |
||||
this.resetListHeight(p["adaptHeight"]); |
||||
} |
||||
if ("left" in p) { |
||||
this.popupView.element.css({ |
||||
left: p.left |
||||
}); |
||||
} |
||||
if ("top" in p) { |
||||
this.popupView.element.css({ |
||||
top: p.top |
||||
}); |
||||
} |
||||
this.position = p; |
||||
this.popupView.setVisible(isVisible); |
||||
}, |
||||
|
||||
resetListHeight: function (h) { |
||||
this._assertPopupView(); |
||||
this.popupView.resetHeight && this.popupView.resetHeight(h); |
||||
}, |
||||
|
||||
resetListWidth: function (w) { |
||||
this._assertPopupView(); |
||||
this.popupView.resetWidth && this.popupView.resetWidth(w); |
||||
}, |
||||
|
||||
populate: function (items) { |
||||
this._assertPopupView(); |
||||
this.popupView.populate.apply(this.popupView, arguments); |
||||
this.combo.populate && this.combo.populate.apply(this.combo, arguments); |
||||
}, |
||||
|
||||
_setEnable: function (arg) { |
||||
BI.Combo.superclass._setEnable.apply(this, arguments); |
||||
if (arg === true) { |
||||
this.element.removeClass("base-disabled disabled"); |
||||
} else if (arg === false) { |
||||
this.element.addClass("base-disabled disabled"); |
||||
} |
||||
!arg && this.element.removeClass(this.options.hoverClass); |
||||
!arg && this.isViewVisible() && this._hideView(); |
||||
}, |
||||
|
||||
setValue: function (v) { |
||||
this.combo.setValue(v); |
||||
if (BI.isNull(this.popupView)) { |
||||
this.options.popup.value = v; |
||||
} else { |
||||
this.popupView.setValue(v); |
||||
} |
||||
}, |
||||
|
||||
getValue: function () { |
||||
if (BI.isNull(this.popupView)) { |
||||
return this.options.popup.value; |
||||
} else { |
||||
return this.popupView.getValue(); |
||||
} |
||||
}, |
||||
|
||||
isViewVisible: function () { |
||||
return this.isEnabled() && this.combo.isEnabled() && !!this.popupView && this.popupView.isVisible(); |
||||
}, |
||||
|
||||
showView: function (e) { |
||||
// 减少popup 调整宽高的次数
|
||||
if (this.isEnabled() && this.combo.isEnabled() && !this.isViewVisible()) { |
||||
this._popupView(e); |
||||
} |
||||
}, |
||||
|
||||
hideView: function (e) { |
||||
this._hideView(e); |
||||
}, |
||||
|
||||
getView: function () { |
||||
return this.popupView; |
||||
}, |
||||
|
||||
getPopupPosition: function () { |
||||
return this.position; |
||||
}, |
||||
|
||||
toggle: function () { |
||||
this._toggle(); |
||||
}, |
||||
|
||||
destroyed: function () { |
||||
BI.Widget._renderEngine.createElement(document) |
||||
.unbind("click." + this.getName()) |
||||
.unbind("mousedown." + this.getName()) |
||||
.unbind("mousewheel." + this.getName()) |
||||
.unbind("mouseenter." + this.getName()) |
||||
.unbind("mousemove." + this.getName()) |
||||
.unbind("mouseleave." + this.getName()); |
||||
BI.Widget._renderEngine.createElement(window) |
||||
.unbind("blur." + this.getName()); |
||||
BI.Resizers.remove(this.getName()); |
||||
this.popupView && this.popupView._destroy(); |
||||
delete needHideWhenAnotherComboOpen[this.getName()]; |
||||
} |
||||
}); |
||||
BI.Combo.EVENT_TRIGGER_CHANGE = "EVENT_TRIGGER_CHANGE"; |
||||
BI.Combo.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
BI.Combo.EVENT_EXPAND = "EVENT_EXPAND"; |
||||
BI.Combo.EVENT_COLLAPSE = "EVENT_COLLAPSE"; |
||||
BI.Combo.EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; |
||||
|
||||
|
||||
BI.Combo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; |
||||
BI.Combo.EVENT_AFTER_POPUPVIEW = "EVENT_AFTER_POPUPVIEW"; |
||||
BI.Combo.EVENT_BEFORE_HIDEVIEW = "EVENT_BEFORE_HIDEVIEW"; |
||||
BI.Combo.EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; |
||||
|
||||
BI.shortcut("bi.combo", BI.Combo); |
||||
}()); |
@ -0,0 +1,281 @@
|
||||
/** |
||||
* |
||||
* 某个可以展开的节点 |
||||
* |
||||
* Created by GUY on 2015/9/10. |
||||
* @class BI.Expander |
||||
* @extends BI.Widget |
||||
*/ |
||||
BI.Expander = BI.inherit(BI.Widget, { |
||||
_defaultConfig: function () { |
||||
return BI.extend(BI.Expander.superclass._defaultConfig.apply(this, arguments), { |
||||
baseCls: "bi-expander", |
||||
trigger: "click", |
||||
toggle: true, |
||||
// direction: "bottom", //top,bottom四个方向
|
||||
isDefaultInit: false, // 是否默认初始化子节点
|
||||
el: {}, |
||||
popup: {}, |
||||
expanderClass: "bi-expander-popup", |
||||
hoverClass: "bi-expander-hover" |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var self = this, o = this.options; |
||||
this._expanded = !!o.el.open; |
||||
this._initExpander(); |
||||
this._initPullDownAction(); |
||||
this.expander.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { |
||||
if (self.isEnabled() && self.isValid()) { |
||||
if (type === BI.Events.EXPAND) { |
||||
self._popupView(); |
||||
} |
||||
if (type === BI.Events.COLLAPSE) { |
||||
self._hideView(); |
||||
} |
||||
if (type === BI.Events.EXPAND) { |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); |
||||
self.fireEvent(BI.Expander.EVENT_EXPAND); |
||||
} |
||||
if (type === BI.Events.COLLAPSE) { |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); |
||||
self.isViewVisible() && self.fireEvent(BI.Expander.EVENT_COLLAPSE); |
||||
} |
||||
if (type === BI.Events.CLICK) { |
||||
self.fireEvent(BI.Expander.EVENT_TRIGGER_CHANGE, value, obj); |
||||
} |
||||
} |
||||
}); |
||||
|
||||
this.element.hover(function () { |
||||
if (self.isEnabled() && self.isValid() && self.expander.isEnabled() && self.expander.isValid()) { |
||||
self.element.addClass(o.hoverClass); |
||||
} |
||||
}, function () { |
||||
if (self.isEnabled() && self.isValid() && self.expander.isEnabled() && self.expander.isValid()) { |
||||
self.element.removeClass(o.hoverClass); |
||||
} |
||||
}); |
||||
BI.createWidget({ |
||||
type: "bi.vertical", |
||||
scrolly: false, |
||||
element: this, |
||||
items: [ |
||||
{el: this.expander} |
||||
] |
||||
}); |
||||
o.isDefaultInit && this._assertPopupView(); |
||||
if (this.expander.isOpened() === true) { |
||||
this._popupView(); |
||||
} |
||||
}, |
||||
|
||||
_toggle: function () { |
||||
this._assertPopupViewRender(); |
||||
if (this.popupView.isVisible()) { |
||||
this._hideView(); |
||||
} else { |
||||
if (this.isEnabled()) { |
||||
this._popupView(); |
||||
} |
||||
} |
||||
}, |
||||
|
||||
_initPullDownAction: function () { |
||||
var self = this, o = this.options; |
||||
var evs = this.options.trigger.split(","); |
||||
BI.each(evs, function (i, e) { |
||||
switch (e) { |
||||
case "hover": |
||||
self.element[e](function (e) { |
||||
if (self.isEnabled() && self.isValid() && self.expander.isEnabled() && self.expander.isValid()) { |
||||
self._popupView(); |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.expander); |
||||
self.fireEvent(BI.Expander.EVENT_EXPAND); |
||||
} |
||||
}, function () { |
||||
if (self.isEnabled() && self.isValid() && self.expander.isEnabled() && self.expander.isValid() && o.toggle) { |
||||
self._hideView(); |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", self.expander); |
||||
self.fireEvent(BI.Expander.EVENT_COLLAPSE); |
||||
} |
||||
}); |
||||
break; |
||||
case "click": |
||||
if (e) { |
||||
self.element.off(e + "." + self.getName()).on(e + "." + self.getName(), BI.debounce(function (e) { |
||||
if (self.expander.element.__isMouseInBounds__(e)) { |
||||
if (self.isEnabled() && self.isValid() && self.expander.isEnabled() && self.expander.isValid()) { |
||||
o.toggle ? self._toggle() : self._popupView(); |
||||
if (self.isExpanded()) { |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.expander); |
||||
self.fireEvent(BI.Expander.EVENT_EXPAND); |
||||
} else { |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", self.expander); |
||||
self.fireEvent(BI.Expander.EVENT_COLLAPSE); |
||||
} |
||||
} |
||||
} |
||||
}, BI.EVENT_RESPONSE_TIME, { |
||||
"leading": true, |
||||
"trailing": false |
||||
})); |
||||
} |
||||
break; |
||||
} |
||||
}); |
||||
}, |
||||
|
||||
_initExpander: function () { |
||||
this.expander = BI.createWidget(this.options.el); |
||||
}, |
||||
|
||||
_assertPopupView: function () { |
||||
var self = this, o = this.options; |
||||
if (this.popupView == null) { |
||||
this.popupView = BI.createWidget(this.options.popup, { |
||||
type: "bi.button_group", |
||||
cls: "expander-popup", |
||||
layouts: [{ |
||||
type: "bi.vertical", |
||||
hgap: 0, |
||||
vgap: 0 |
||||
}], |
||||
value: o.value |
||||
}, this); |
||||
this.popupView.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); |
||||
if (type === BI.Events.CLICK) { |
||||
// self.setValue(self.getValue());
|
||||
self.fireEvent(BI.Expander.EVENT_CHANGE, value, obj); |
||||
} |
||||
}); |
||||
this.popupView.setVisible(this.isExpanded()); |
||||
BI.nextTick(function () { |
||||
self.fireEvent(BI.Expander.EVENT_AFTER_INIT); |
||||
}); |
||||
} |
||||
}, |
||||
|
||||
_assertPopupViewRender: function () { |
||||
this._assertPopupView(); |
||||
if (!this._rendered) { |
||||
BI.createWidget({ |
||||
type: "bi.vertical", |
||||
scrolly: false, |
||||
element: this, |
||||
items: [ |
||||
{el: this.popupView} |
||||
] |
||||
}); |
||||
this._rendered = true; |
||||
} |
||||
}, |
||||
|
||||
_hideView: function () { |
||||
this.fireEvent(BI.Expander.EVENT_BEFORE_HIDEVIEW); |
||||
this._expanded = false; |
||||
this.expander.setOpened(false); |
||||
this.popupView && this.popupView.invisible(); |
||||
this.element.removeClass(this.options.expanderClass); |
||||
|
||||
this.fireEvent(BI.Expander.EVENT_AFTER_HIDEVIEW); |
||||
}, |
||||
|
||||
_popupView: function () { |
||||
this._assertPopupViewRender(); |
||||
this.fireEvent(BI.Expander.EVENT_BEFORE_POPUPVIEW); |
||||
this._expanded = true; |
||||
this.expander.setOpened(true); |
||||
this.popupView.visible(); |
||||
this.element.addClass(this.options.expanderClass); |
||||
this.fireEvent(BI.Expander.EVENT_AFTER_POPUPVIEW); |
||||
}, |
||||
|
||||
populate: function (items) { |
||||
// this._assertPopupView();
|
||||
this.popupView && this.popupView.populate.apply(this.popupView, arguments); |
||||
this.expander.populate && this.expander.populate.apply(this.expander, arguments); |
||||
}, |
||||
|
||||
_setEnable: function (arg) { |
||||
BI.Expander.superclass._setEnable.apply(this, arguments); |
||||
!arg && this.element.removeClass(this.options.hoverClass); |
||||
!arg && this.isViewVisible() && this._hideView(); |
||||
}, |
||||
|
||||
setValue: function (v) { |
||||
this.expander.setValue(v); |
||||
if (BI.isNull(this.popupView)) { |
||||
this.options.popup.value = v; |
||||
} else { |
||||
this.popupView.setValue(v); |
||||
} |
||||
}, |
||||
|
||||
getValue: function () { |
||||
if (BI.isNull(this.popupView)) { |
||||
return this.options.popup.value; |
||||
} else { |
||||
return this.popupView.getValue(); |
||||
} |
||||
}, |
||||
|
||||
isViewVisible: function () { |
||||
return this.isEnabled() && this.expander.isEnabled() && !!this.popupView && this.popupView.isVisible(); |
||||
}, |
||||
|
||||
isExpanded: function () { |
||||
return this._expanded; |
||||
}, |
||||
|
||||
showView: function () { |
||||
if (this.isEnabled() && this.expander.isEnabled()) { |
||||
this._popupView(); |
||||
} |
||||
}, |
||||
|
||||
hideView: function () { |
||||
this._hideView(); |
||||
}, |
||||
|
||||
getView: function () { |
||||
return this.popupView; |
||||
}, |
||||
|
||||
getAllLeaves: function () { |
||||
return this.popupView && this.popupView.getAllLeaves(); |
||||
}, |
||||
|
||||
getNodeById: function (id) { |
||||
if (this.expander.options.id === id) { |
||||
return this.expander; |
||||
} |
||||
return this.popupView && this.popupView.getNodeById(id); |
||||
}, |
||||
|
||||
getNodeByValue: function (value) { |
||||
if (this.expander.getValue() === value) { |
||||
return this.expander; |
||||
} |
||||
return this.popupView && this.popupView.getNodeByValue(value); |
||||
}, |
||||
|
||||
destroy: function () { |
||||
BI.Expander.superclass.destroy.apply(this, arguments); |
||||
} |
||||
}); |
||||
BI.Expander.EVENT_EXPAND = "EVENT_EXPAND"; |
||||
BI.Expander.EVENT_COLLAPSE = "EVENT_COLLAPSE"; |
||||
BI.Expander.EVENT_TRIGGER_CHANGE = "EVENT_TRIGGER_CHANGE"; |
||||
BI.Expander.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
BI.Expander.EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; |
||||
|
||||
|
||||
BI.Expander.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; |
||||
BI.Expander.EVENT_AFTER_POPUPVIEW = "EVENT_AFTER_POPUPVIEW"; |
||||
BI.Expander.EVENT_BEFORE_HIDEVIEW = "EVENT_BEFORE_HIDEVIEW"; |
||||
BI.Expander.EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; |
||||
|
||||
BI.shortcut("bi.expander", BI.Expander); |
@ -0,0 +1,329 @@
|
||||
/** |
||||
* Created by GUY on 2015/6/26. |
||||
* @class BI.ButtonGroup |
||||
* @extends BI.Widget |
||||
*/ |
||||
|
||||
BI.ButtonGroup = BI.inherit(BI.Widget, { |
||||
_defaultConfig: function () { |
||||
return BI.extend(BI.ButtonGroup.superclass._defaultConfig.apply(this, arguments), { |
||||
baseCls: "bi-button-group", |
||||
behaviors: {}, |
||||
items: [], |
||||
value: "", |
||||
chooseType: BI.Selection.Single, |
||||
layouts: [{ |
||||
type: "bi.center", |
||||
hgap: 0, |
||||
vgap: 0 |
||||
}] |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var o = this.options; |
||||
var behaviors = {}; |
||||
BI.each(o.behaviors, function (key, rule) { |
||||
behaviors[key] = BI.BehaviorFactory.createBehavior(key, { |
||||
rule: rule |
||||
}); |
||||
}); |
||||
this.behaviors = behaviors; |
||||
this.populate(o.items); |
||||
if(BI.isKey(o.value) || BI.isNotEmptyArray(o.value)){ |
||||
this.setValue(o.value); |
||||
} |
||||
}, |
||||
|
||||
_createBtns: function (items) { |
||||
var o = this.options; |
||||
return BI.createWidgets(BI.createItems(items, { |
||||
type: "bi.text_button" |
||||
}), this); |
||||
}, |
||||
|
||||
_btnsCreator: function (items) { |
||||
var self = this, args = Array.prototype.slice.call(arguments), o = this.options; |
||||
var buttons = this._createBtns(items); |
||||
args[0] = buttons; |
||||
|
||||
BI.each(this.behaviors, function (i, behavior) { |
||||
behavior.doBehavior.apply(behavior, args); |
||||
}); |
||||
BI.each(buttons, function (i, btn) { |
||||
btn.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { |
||||
if (type === BI.Events.CLICK) { |
||||
switch (o.chooseType) { |
||||
case BI.ButtonGroup.CHOOSE_TYPE_SINGLE: |
||||
self.setValue(btn.getValue()); |
||||
break; |
||||
case BI.ButtonGroup.CHOOSE_TYPE_NONE: |
||||
self.setValue([]); |
||||
break; |
||||
} |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); |
||||
self.fireEvent(BI.ButtonGroup.EVENT_CHANGE, value, obj); |
||||
} else { |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); |
||||
} |
||||
}); |
||||
btn.on(BI.Events.DESTROY, function () { |
||||
BI.remove(self.buttons, btn); |
||||
}); |
||||
}); |
||||
|
||||
return buttons; |
||||
}, |
||||
|
||||
_packageBtns: function (btns) { |
||||
var o = this.options; |
||||
for (var i = o.layouts.length - 1; i > 0; i--) { |
||||
btns = BI.map(btns, function (k, it) { |
||||
return BI.extend({}, o.layouts[i], { |
||||
items: [ |
||||
BI.extend({}, o.layouts[i].el, { |
||||
el: it |
||||
}) |
||||
] |
||||
}); |
||||
}); |
||||
} |
||||
return btns; |
||||
}, |
||||
|
||||
_packageSimpleItems: function (btns) { |
||||
var o = this.options; |
||||
return BI.map(o.items, function (i, item) { |
||||
if (BI.stripEL(item) === item) { |
||||
return btns[i]; |
||||
} |
||||
return BI.extend({}, item, { |
||||
el: btns[i] |
||||
}); |
||||
}); |
||||
}, |
||||
|
||||
_packageItems: function (items, packBtns) { |
||||
return BI.createItems(BI.makeArrayByArray(items, {}), BI.clone(packBtns)); |
||||
}, |
||||
|
||||
_packageLayout: function (items) { |
||||
var o = this.options, layout = BI.deepClone(o.layouts[0]); |
||||
|
||||
var lay = BI.formatEL(layout).el; |
||||
while (lay && lay.items && !BI.isEmpty(lay.items)) { |
||||
lay = BI.formatEL(lay.items[0]).el; |
||||
} |
||||
lay.items = items; |
||||
return layout; |
||||
}, |
||||
|
||||
// 如果是一个简单的layout
|
||||
_isSimpleLayout: function () { |
||||
var o = this.options; |
||||
return o.layouts.length === 1 && !BI.isArray(o.items[0]); |
||||
}, |
||||
|
||||
doBehavior: function () { |
||||
var args = Array.prototype.slice.call(arguments); |
||||
args.unshift(this.buttons); |
||||
BI.each(this.behaviors, function (i, behavior) { |
||||
behavior.doBehavior.apply(behavior, args); |
||||
}); |
||||
}, |
||||
|
||||
prependItems: function (items) { |
||||
var o = this.options; |
||||
var btns = this._btnsCreator.apply(this, arguments); |
||||
this.buttons = BI.concat(btns, this.buttons); |
||||
|
||||
if (this._isSimpleLayout() && this.layouts && this.layouts.prependItems) { |
||||
this.layouts.prependItems(btns); |
||||
return; |
||||
} |
||||
|
||||
items = this._packageItems(items, this._packageBtns(btns)); |
||||
this.layouts.prependItems(this._packageLayout(items).items); |
||||
}, |
||||
|
||||
addItems: function (items) { |
||||
var o = this.options; |
||||
var btns = this._btnsCreator.apply(this, arguments); |
||||
this.buttons = BI.concat(this.buttons, btns); |
||||
|
||||
// 如果是一个简单的layout
|
||||
if (this._isSimpleLayout() && this.layouts && this.layouts.addItems) { |
||||
this.layouts.addItems(btns); |
||||
return; |
||||
} |
||||
|
||||
items = this._packageItems(items, this._packageBtns(btns)); |
||||
this.layouts.addItems(this._packageLayout(items).items); |
||||
}, |
||||
|
||||
removeItemAt: function (indexes) { |
||||
BI.removeAt(this.buttons, indexes); |
||||
this.layouts.removeItemAt(indexes); |
||||
}, |
||||
|
||||
removeItems: function (values) { |
||||
values = BI.isArray(values) ? values : [values]; |
||||
var deleted = []; |
||||
BI.each(this.buttons, function (i, button) { |
||||
if (BI.deepContains(values, button.getValue())) { |
||||
deleted.push(i); |
||||
} |
||||
}); |
||||
BI.removeAt(this.buttons, deleted); |
||||
this.layouts.removeItemAt(deleted); |
||||
}, |
||||
|
||||
populate: function (items) { |
||||
items = items || []; |
||||
this.empty(); |
||||
this.options.items = items; |
||||
|
||||
this.buttons = this._btnsCreator.apply(this, arguments); |
||||
if (this._isSimpleLayout()) { |
||||
items = this._packageSimpleItems(this.buttons); |
||||
} else { |
||||
items = this._packageItems(items, this._packageBtns(this.buttons)); |
||||
} |
||||
|
||||
this.layouts = BI.createWidget(BI.extend({element: this}, this._packageLayout(items))); |
||||
}, |
||||
|
||||
setNotSelectedValue: function (v) { |
||||
v = BI.isArray(v) ? v : [v]; |
||||
BI.each(this.buttons, function (i, item) { |
||||
if (BI.deepContains(v, item.getValue())) { |
||||
item.setSelected && item.setSelected(false); |
||||
} else { |
||||
item.setSelected && item.setSelected(true); |
||||
} |
||||
}); |
||||
}, |
||||
|
||||
setEnabledValue: function (v) { |
||||
v = BI.isArray(v) ? v : [v]; |
||||
BI.each(this.buttons, function (i, item) { |
||||
if (BI.deepContains(v, item.getValue())) { |
||||
item.setEnable(true); |
||||
} else { |
||||
item.setEnable(false); |
||||
} |
||||
}); |
||||
}, |
||||
|
||||
setValue: function (v) { |
||||
v = BI.isArray(v) ? v : [v]; |
||||
BI.each(this.buttons, function (i, item) { |
||||
if (BI.deepContains(v, item.getValue())) { |
||||
item.setSelected && item.setSelected(true); |
||||
} else { |
||||
item.setSelected && item.setSelected(false); |
||||
} |
||||
}); |
||||
}, |
||||
|
||||
getNotSelectedValue: function () { |
||||
var v = []; |
||||
BI.each(this.buttons, function (i, item) { |
||||
if (item.isEnabled() && !(item.isSelected && item.isSelected())) { |
||||
v.push(item.getValue()); |
||||
} |
||||
}); |
||||
return v; |
||||
}, |
||||
|
||||
getValue: function () { |
||||
var v = []; |
||||
BI.each(this.buttons, function (i, item) { |
||||
if (item.isEnabled() && item.isSelected && item.isSelected()) { |
||||
v.push(item.getValue()); |
||||
} |
||||
}); |
||||
return v; |
||||
}, |
||||
|
||||
getAllButtons: function () { |
||||
return this.buttons; |
||||
}, |
||||
|
||||
getAllLeaves: function () { |
||||
return this.buttons; |
||||
}, |
||||
|
||||
getSelectedButtons: function () { |
||||
var btns = []; |
||||
BI.each(this.buttons, function (i, item) { |
||||
if (item.isSelected && item.isSelected()) { |
||||
btns.push(item); |
||||
} |
||||
}); |
||||
return btns; |
||||
}, |
||||
|
||||
getNotSelectedButtons: function () { |
||||
var btns = []; |
||||
BI.each(this.buttons, function (i, item) { |
||||
if (item.isSelected && !item.isSelected()) { |
||||
btns.push(item); |
||||
} |
||||
}); |
||||
return btns; |
||||
}, |
||||
|
||||
getIndexByValue: function (value) { |
||||
var index = -1; |
||||
BI.any(this.buttons, function (i, item) { |
||||
if (item.isEnabled() && item.getValue() === value) { |
||||
index = i; |
||||
return true; |
||||
} |
||||
}); |
||||
return index; |
||||
}, |
||||
|
||||
getNodeById: function (id) { |
||||
var node; |
||||
BI.any(this.buttons, function (i, item) { |
||||
if (item.isEnabled() && item.options.id === id) { |
||||
node = item; |
||||
return true; |
||||
} |
||||
}); |
||||
return node; |
||||
}, |
||||
|
||||
getNodeByValue: function (value) { |
||||
var node; |
||||
BI.any(this.buttons, function (i, item) { |
||||
if (item.isEnabled() && item.getValue() === value) { |
||||
node = item; |
||||
return true; |
||||
} |
||||
}); |
||||
return node; |
||||
}, |
||||
|
||||
empty: function () { |
||||
BI.ButtonGroup.superclass.empty.apply(this, arguments); |
||||
this.options.items = []; |
||||
}, |
||||
|
||||
destroy: function () { |
||||
BI.ButtonGroup.superclass.destroy.apply(this, arguments); |
||||
this.options.items = []; |
||||
} |
||||
}); |
||||
BI.extend(BI.ButtonGroup, { |
||||
CHOOSE_TYPE_SINGLE: BI.Selection.Single, |
||||
CHOOSE_TYPE_MULTI: BI.Selection.Multi, |
||||
CHOOSE_TYPE_ALL: BI.Selection.All, |
||||
CHOOSE_TYPE_NONE: BI.Selection.None, |
||||
CHOOSE_TYPE_DEFAULT: BI.Selection.Default |
||||
}); |
||||
BI.ButtonGroup.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
|
||||
BI.shortcut("bi.button_group", BI.ButtonGroup); |
@ -0,0 +1,96 @@
|
||||
/** |
||||
* Created by GUY on 2015/8/10. |
||||
*/ |
||||
|
||||
BI.ComboGroup = BI.inherit(BI.Widget, { |
||||
_defaultConfig: function () { |
||||
return BI.extend(BI.ComboGroup.superclass._defaultConfig.apply(this, arguments), { |
||||
baseCls: "bi-combo-group bi-list-item", |
||||
|
||||
// 以下这些属性对每一个combo都是公用的
|
||||
trigger: "click,hover", |
||||
direction: "right", |
||||
adjustLength: 0, |
||||
isDefaultInit: false, |
||||
isNeedAdjustHeight: false, |
||||
isNeedAdjustWidth: false, |
||||
|
||||
el: {type: "bi.text_button", text: "", value: ""}, |
||||
children: [], |
||||
|
||||
popup: { |
||||
el: { |
||||
type: "bi.button_tree", |
||||
chooseType: 0, |
||||
layouts: [{ |
||||
type: "bi.vertical" |
||||
}] |
||||
} |
||||
} |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
this._populate(this.options.el); |
||||
}, |
||||
|
||||
_populate: function (item) { |
||||
var self = this, o = this.options; |
||||
var children = o.children; |
||||
if (BI.isEmpty(children)) { |
||||
throw new Error("ComboGroup构造错误"); |
||||
} |
||||
BI.each(children, function (i, ch) { |
||||
var son = BI.formatEL(ch).el.children; |
||||
ch = BI.formatEL(ch).el; |
||||
if (!BI.isEmpty(son)) { |
||||
ch.el = BI.clone(ch); |
||||
ch.children = son; |
||||
ch.type = "bi.combo_group"; |
||||
ch.action = o.action; |
||||
ch.height = o.height; |
||||
ch.direction = o.direction; |
||||
ch.isDefaultInit = o.isDefaultInit; |
||||
ch.isNeedAdjustHeight = o.isNeedAdjustHeight; |
||||
ch.isNeedAdjustWidth = o.isNeedAdjustWidth; |
||||
ch.adjustLength = o.adjustLength; |
||||
ch.popup = o.popup; |
||||
} |
||||
}); |
||||
this.combo = BI.createWidget({ |
||||
type: "bi.combo", |
||||
element: this, |
||||
container: o.container, |
||||
height: o.height, |
||||
trigger: o.trigger, |
||||
direction: o.direction, |
||||
isDefaultInit: o.isDefaultInit, |
||||
isNeedAdjustWidth: o.isNeedAdjustWidth, |
||||
isNeedAdjustHeight: o.isNeedAdjustHeight, |
||||
adjustLength: o.adjustLength, |
||||
el: item, |
||||
popup: BI.extend({}, o.popup, { |
||||
el: BI.extend({ |
||||
items: children |
||||
}, o.popup.el) |
||||
}) |
||||
}); |
||||
this.combo.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); |
||||
if (type === BI.Events.CLICK) { |
||||
self.fireEvent(BI.ComboGroup.EVENT_CHANGE, obj); |
||||
} |
||||
}); |
||||
}, |
||||
|
||||
getValue: function () { |
||||
return this.combo.getValue(); |
||||
}, |
||||
|
||||
setValue: function (v) { |
||||
this.combo.setValue(v); |
||||
} |
||||
}); |
||||
BI.ComboGroup.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
|
||||
BI.shortcut("bi.combo_group", BI.ComboGroup); |
@ -0,0 +1,116 @@
|
||||
BI.VirtualGroup = BI.inherit(BI.Widget, { |
||||
_defaultConfig: function () { |
||||
return BI.extend(BI.VirtualGroup.superclass._defaultConfig.apply(this, arguments), { |
||||
baseCls: "bi-virtual-group", |
||||
items: [], |
||||
layouts: [{ |
||||
type: "bi.center", |
||||
hgap: 0, |
||||
vgap: 0 |
||||
}] |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var o = this.options; |
||||
this.populate(o.items); |
||||
if (BI.isKey(o.value)) { |
||||
this.setValue(o.value); |
||||
} |
||||
}, |
||||
|
||||
_packageBtns: function (items) { |
||||
var o = this.options; |
||||
var map = this.buttonMap = {}; |
||||
for (var i = o.layouts.length - 1; i > 0; i--) { |
||||
items = BI.map(items, function (k, it) { |
||||
var el = BI.stripEL(it); |
||||
return BI.extend({}, o.layouts[i], { |
||||
items: [ |
||||
BI.extend({}, o.layouts[i].el, { |
||||
el: BI.extend({ |
||||
ref: function (_ref) { |
||||
if (BI.isKey(map[el.value])) { |
||||
map[el.value] = _ref; |
||||
} |
||||
} |
||||
}, el) |
||||
}) |
||||
] |
||||
}); |
||||
}); |
||||
} |
||||
return items; |
||||
}, |
||||
|
||||
_packageLayout: function (items) { |
||||
var o = this.options, layout = BI.deepClone(o.layouts[0]); |
||||
|
||||
var lay = BI.formatEL(layout).el; |
||||
while (lay && lay.items && !BI.isEmpty(lay.items)) { |
||||
lay = BI.formatEL(lay.items[0]).el; |
||||
} |
||||
lay.items = items; |
||||
return layout; |
||||
}, |
||||
|
||||
addItems: function (items) { |
||||
this.layouts.addItems(items); |
||||
}, |
||||
|
||||
prependItems: function (items) { |
||||
this.layouts.prependItems(items); |
||||
}, |
||||
|
||||
setValue: function (v) { |
||||
v = BI.isArray(v) ? v : [v]; |
||||
BI.each(this.buttonMap, function (key, item) { |
||||
if (item) { |
||||
if (v.deepContains(key)) { |
||||
item.setSelected && item.setSelected(true); |
||||
} else { |
||||
item.setSelected && item.setSelected(false); |
||||
} |
||||
} |
||||
}); |
||||
}, |
||||
|
||||
getNotSelectedValue: function () { |
||||
var v = []; |
||||
BI.each(this.buttonMap, function (i, item) { |
||||
if (item) { |
||||
if (item.isEnabled() && !(item.isSelected && item.isSelected())) { |
||||
v.push(item.getValue()); |
||||
} |
||||
} |
||||
}); |
||||
return v; |
||||
}, |
||||
|
||||
getValue: function () { |
||||
var v = []; |
||||
BI.each(this.buttonMap, function (i, item) { |
||||
if (item) { |
||||
if (item.isEnabled() && item.isSelected && item.isSelected()) { |
||||
v.push(item.getValue()); |
||||
} |
||||
} |
||||
}); |
||||
return v; |
||||
}, |
||||
|
||||
populate: function (items) { |
||||
var self = this; |
||||
items = items || []; |
||||
this.options.items = items; |
||||
items = this._packageBtns(items); |
||||
if (!this.layouts) { |
||||
this.layouts = BI.createWidget(BI.extend({element: this}, this._packageLayout(items))); |
||||
} else { |
||||
this.layouts.populate(items); |
||||
} |
||||
} |
||||
}); |
||||
BI.VirtualGroup.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
|
||||
BI.shortcut("bi.virtual_group", BI.VirtualGroup); |
@ -0,0 +1,259 @@
|
||||
/** |
||||
* 加载控件 |
||||
* |
||||
* Created by GUY on 2015/8/31. |
||||
* @class BI.Loader |
||||
* @extends BI.Widget |
||||
*/ |
||||
BI.Loader = BI.inherit(BI.Widget, { |
||||
_defaultConfig: function () { |
||||
return BI.extend(BI.Loader.superclass._defaultConfig.apply(this, arguments), { |
||||
baseCls: "bi-loader", |
||||
|
||||
direction: "top", |
||||
isDefaultInit: true, // 是否默认初始化数据
|
||||
logic: { |
||||
dynamic: true, |
||||
scrolly: true |
||||
}, |
||||
|
||||
// 下面是button_group的属性
|
||||
el: { |
||||
type: "bi.button_group" |
||||
}, |
||||
|
||||
items: [], |
||||
itemsCreator: BI.emptyFn, |
||||
onLoaded: BI.emptyFn, |
||||
|
||||
// 下面是分页信息
|
||||
count: false, |
||||
prev: false, |
||||
next: {}, |
||||
hasPrev: BI.emptyFn, |
||||
hasNext: BI.emptyFn |
||||
}); |
||||
}, |
||||
|
||||
_prevLoad: function () { |
||||
var self = this, o = this.options; |
||||
this.prev.setLoading(); |
||||
o.itemsCreator.apply(this, [{times: --this.times}, function () { |
||||
self.prev.setLoaded(); |
||||
self.prependItems.apply(self, arguments); |
||||
}]); |
||||
}, |
||||
|
||||
_nextLoad: function () { |
||||
var self = this, o = this.options; |
||||
this.next.setLoading(); |
||||
o.itemsCreator.apply(this, [{times: ++this.times}, function () { |
||||
self.next.setLoaded(); |
||||
self.addItems.apply(self, arguments); |
||||
}]); |
||||
}, |
||||
|
||||
render: function () { |
||||
var self = this, o = this.options; |
||||
if (o.itemsCreator === false) { |
||||
o.prev = false; |
||||
o.next = false; |
||||
} |
||||
if (o.prev !== false) { |
||||
this.prev = BI.createWidget(BI.extend({ |
||||
type: "bi.loading_bar" |
||||
}, o.prev)); |
||||
this.prev.on(BI.Controller.EVENT_CHANGE, function (type) { |
||||
if (type === BI.Events.CLICK) { |
||||
self._prevLoad(); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
this.button_group = BI.createWidget(o.el, { |
||||
type: "bi.button_group", |
||||
chooseType: 0, |
||||
items: o.items, |
||||
behaviors: {}, |
||||
layouts: [{ |
||||
type: "bi.vertical" |
||||
}], |
||||
value: o.value |
||||
}); |
||||
this.button_group.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); |
||||
if (type === BI.Events.CLICK) { |
||||
self.fireEvent(BI.Loader.EVENT_CHANGE, obj); |
||||
} |
||||
}); |
||||
|
||||
if (o.next !== false) { |
||||
this.next = BI.createWidget(BI.extend({ |
||||
type: "bi.loading_bar" |
||||
}, o.next)); |
||||
this.next.on(BI.Controller.EVENT_CHANGE, function (type) { |
||||
if (type === BI.Events.CLICK) { |
||||
self._nextLoad(); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
BI.createWidget(BI.extend({ |
||||
element: this |
||||
}, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(o.direction), BI.extend({ |
||||
scrolly: true |
||||
}, o.logic, { |
||||
items: BI.LogicFactory.createLogicItemsByDirection(o.direction, this.prev, this.button_group, this.next) |
||||
})))); |
||||
|
||||
o.isDefaultInit && BI.isEmpty(o.items) && BI.nextTick(BI.bind(function () { |
||||
o.isDefaultInit && BI.isEmpty(o.items) && this._populate(); |
||||
}, this)); |
||||
if (BI.isNotEmptyArray(o.items)) { |
||||
this._populate(o.items); |
||||
} |
||||
}, |
||||
|
||||
hasPrev: function () { |
||||
var o = this.options; |
||||
if (BI.isNumber(o.count)) { |
||||
return this.count < o.count; |
||||
} |
||||
return !!o.hasPrev.apply(this, [{ |
||||
times: this.times, |
||||
count: this.count |
||||
}]); |
||||
}, |
||||
|
||||
hasNext: function () { |
||||
var o = this.options; |
||||
if (BI.isNumber(o.count)) { |
||||
return this.count < o.count; |
||||
} |
||||
return !!o.hasNext.apply(this, [{ |
||||
times: this.times, |
||||
count: this.count |
||||
}]); |
||||
}, |
||||
|
||||
prependItems: function (items) { |
||||
this.count += items.length; |
||||
if (this.next !== false) { |
||||
if (this.hasPrev()) { |
||||
this.options.items = this.options.items.concat(items); |
||||
this.prev.setLoaded(); |
||||
} else { |
||||
this.prev.setEnd(); |
||||
} |
||||
} |
||||
this.button_group.prependItems.apply(this.button_group, arguments); |
||||
}, |
||||
|
||||
addItems: function (items) { |
||||
this.count += items.length; |
||||
if (BI.isObject(this.next)) { |
||||
if (this.hasNext()) { |
||||
this.options.items = this.options.items.concat(items); |
||||
this.next.setLoaded(); |
||||
} else { |
||||
this.next.setEnd(); |
||||
} |
||||
} |
||||
this.button_group.addItems.apply(this.button_group, arguments); |
||||
}, |
||||
|
||||
|
||||
_populate: function (items) { |
||||
var self = this, o = this.options; |
||||
if (arguments.length === 0 && (BI.isFunction(o.itemsCreator))) { |
||||
o.itemsCreator.apply(this, [{times: 1}, function () { |
||||
if (arguments.length === 0) { |
||||
throw new Error("参数不能为空"); |
||||
} |
||||
self.populate.apply(self, arguments); |
||||
o.onLoaded(); |
||||
}]); |
||||
return false; |
||||
} |
||||
this.options.items = items; |
||||
this.times = 1; |
||||
this.count = 0; |
||||
this.count += items.length; |
||||
if (BI.isObject(this.next)) { |
||||
if (this.hasNext()) { |
||||
this.next.setLoaded(); |
||||
} else { |
||||
this.next.invisible(); |
||||
} |
||||
} |
||||
if (BI.isObject(this.prev)) { |
||||
if (this.hasPrev()) { |
||||
this.prev.setLoaded(); |
||||
} else { |
||||
this.prev.invisible(); |
||||
} |
||||
} |
||||
return true; |
||||
}, |
||||
|
||||
populate: function () { |
||||
this._populate.apply(this, arguments) && this.button_group.populate.apply(this.button_group, arguments); |
||||
}, |
||||
|
||||
setNotSelectedValue: function () { |
||||
this.button_group.setNotSelectedValue.apply(this.button_group, arguments); |
||||
}, |
||||
|
||||
getNotSelectedValue: function () { |
||||
return this.button_group.getNotSelectedValue(); |
||||
}, |
||||
|
||||
setValue: function () { |
||||
this.button_group.setValue.apply(this.button_group, arguments); |
||||
}, |
||||
|
||||
getValue: function () { |
||||
return this.button_group.getValue.apply(this.button_group, arguments); |
||||
}, |
||||
|
||||
getAllButtons: function () { |
||||
return this.button_group.getAllButtons(); |
||||
}, |
||||
|
||||
getAllLeaves: function () { |
||||
return this.button_group.getAllLeaves(); |
||||
}, |
||||
|
||||
getSelectedButtons: function () { |
||||
return this.button_group.getSelectedButtons(); |
||||
}, |
||||
|
||||
getNotSelectedButtons: function () { |
||||
return this.button_group.getNotSelectedButtons(); |
||||
}, |
||||
|
||||
getIndexByValue: function (value) { |
||||
return this.button_group.getIndexByValue(value); |
||||
}, |
||||
|
||||
getNodeById: function (id) { |
||||
return this.button_group.getNodeById(id); |
||||
}, |
||||
|
||||
getNodeByValue: function (value) { |
||||
return this.button_group.getNodeByValue(value); |
||||
}, |
||||
|
||||
empty: function () { |
||||
this.button_group.empty(); |
||||
BI.each([this.prev, this.next], function (i, ob) { |
||||
ob && ob.setVisible(false); |
||||
}); |
||||
}, |
||||
|
||||
destroy: function () { |
||||
BI.Loader.superclass.destroy.apply(this, arguments); |
||||
} |
||||
}); |
||||
BI.Loader.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
BI.shortcut("bi.loader", BI.Loader); |
@ -0,0 +1,162 @@
|
||||
/** |
||||
* Created by GUY on 2015/6/26. |
||||
*/ |
||||
|
||||
BI.Navigation = BI.inherit(BI.Widget, { |
||||
_defaultConfig: function () { |
||||
return BI.extend(BI.Navigation.superclass._defaultConfig.apply(this, arguments), { |
||||
direction: "bottom", // top, bottom, left, right, custom
|
||||
logic: { |
||||
dynamic: false |
||||
}, |
||||
single: false, |
||||
showIndex: false, |
||||
tab: false, |
||||
cardCreator: function (v) { |
||||
return BI.createWidget(); |
||||
}, |
||||
|
||||
afterCardCreated: BI.emptyFn, |
||||
afterCardShow: BI.emptyFn |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var self = this, o = this.options; |
||||
this.tab = BI.createWidget(this.options.tab, {type: "bi.button_group"}); |
||||
this.cardMap = {}; |
||||
this.showIndex = 0; |
||||
this.layout = BI.createWidget({ |
||||
type: "bi.card" |
||||
}); |
||||
BI.createWidget(BI.extend({ |
||||
element: this |
||||
}, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(o.direction), BI.extend({}, o.logic, { |
||||
items: BI.LogicFactory.createLogicItemsByDirection(o.direction, this.tab, this.layout) |
||||
})))); |
||||
|
||||
|
||||
new BI.ShowListener({ |
||||
eventObj: this.tab, |
||||
cardLayout: this.layout, |
||||
cardNameCreator: function (v) { |
||||
return self.showIndex + v; |
||||
}, |
||||
cardCreator: function (v) { |
||||
var card = o.cardCreator(v); |
||||
self.cardMap[v] = card; |
||||
return card; |
||||
}, |
||||
afterCardCreated: BI.bind(this.afterCardCreated, this), |
||||
afterCardShow: BI.bind(this.afterCardShow, this) |
||||
}); |
||||
}, |
||||
|
||||
created: function () { |
||||
var o = this.options; |
||||
if (o.showIndex !== false) { |
||||
this.setSelect(o.showIndex); |
||||
} |
||||
}, |
||||
|
||||
_deleteOtherCards: function (currCardName) { |
||||
var self = this, o = this.options; |
||||
if (o.single === true) { |
||||
BI.each(this.cardMap, function (name, card) { |
||||
if (name !== (currCardName + "")) { |
||||
self.layout.deleteCardByName(name); |
||||
delete self.cardMap[name]; |
||||
} |
||||
}); |
||||
} |
||||
}, |
||||
|
||||
afterCardCreated: function (v) { |
||||
var self = this; |
||||
this.cardMap[v].on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); |
||||
if (type === BI.Events.CLICK) { |
||||
self.fireEvent(BI.Navigation.EVENT_CHANGE, obj); |
||||
} |
||||
}); |
||||
this.options.afterCardCreated.apply(this, arguments); |
||||
}, |
||||
|
||||
afterCardShow: function (v) { |
||||
this.showIndex = v; |
||||
this._deleteOtherCards(v); |
||||
this.options.afterCardShow.apply(this, arguments); |
||||
}, |
||||
|
||||
populate: function () { |
||||
var card = this.layout.getShowingCard(); |
||||
if (card) { |
||||
return card.populate.apply(card, arguments); |
||||
} |
||||
}, |
||||
|
||||
_assertCard: function (v) { |
||||
if (!this.layout.isCardExisted(v)) { |
||||
var card = this.options.cardCreator(v); |
||||
this.cardMap[v] = card; |
||||
this.layout.addCardByName(v, card); |
||||
this.afterCardCreated(v); |
||||
} |
||||
}, |
||||
|
||||
setSelect: function (v) { |
||||
this._assertCard(v); |
||||
this.layout.showCardByName(v); |
||||
this._deleteOtherCards(v); |
||||
if (this.showIndex !== v) { |
||||
this.showIndex = v; |
||||
BI.nextTick(BI.bind(this.afterCardShow, this, v)); |
||||
} |
||||
}, |
||||
|
||||
getSelect: function () { |
||||
return this.showIndex; |
||||
}, |
||||
|
||||
getSelectedCard: function () { |
||||
if (BI.isKey(this.showIndex)) { |
||||
return this.cardMap[this.showIndex]; |
||||
} |
||||
}, |
||||
|
||||
getAllCard: function() { |
||||
return BI.values(this.cardMap); |
||||
}, |
||||
|
||||
/** |
||||
* @override |
||||
*/ |
||||
setValue: function (v) { |
||||
var card = this.layout.getShowingCard(); |
||||
if (card) { |
||||
card.setValue(v); |
||||
} |
||||
}, |
||||
|
||||
/** |
||||
* @override |
||||
*/ |
||||
getValue: function () { |
||||
var card = this.layout.getShowingCard(); |
||||
if (card) { |
||||
return card.getValue(); |
||||
} |
||||
}, |
||||
|
||||
empty: function () { |
||||
this.layout.deleteAllCard(); |
||||
this.cardMap = {}; |
||||
}, |
||||
|
||||
destroy: function () { |
||||
BI.Navigation.superclass.destroy.apply(this, arguments); |
||||
} |
||||
}); |
||||
BI.Navigation.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
|
||||
BI.shortcut("bi.navigation", BI.Navigation); |
@ -0,0 +1,319 @@
|
||||
/** |
||||
* 搜索逻辑控件 |
||||
* |
||||
* Created by GUY on 2015/9/28. |
||||
* @class BI.Searcher |
||||
* @extends BI.Widget |
||||
*/ |
||||
|
||||
BI.Searcher = BI.inherit(BI.Widget, { |
||||
_defaultConfig: function () { |
||||
return BI.extend(BI.Searcher.superclass._defaultConfig.apply(this, arguments), { |
||||
baseCls: "bi-searcher", |
||||
lgap: 0, |
||||
rgap: 0, |
||||
tgap: 0, |
||||
bgap: 0, |
||||
vgap: 0, |
||||
hgap: 0, |
||||
|
||||
isDefaultInit: false, |
||||
isAutoSearch: true, // 是否自动搜索
|
||||
isAutoSync: true, // 是否自动同步数据, 即是否保持搜索面板和adapter面板状态值的统一
|
||||
chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE, |
||||
|
||||
// isAutoSearch为false时启用
|
||||
onSearch: function (op, callback) { |
||||
callback([]); |
||||
}, |
||||
|
||||
el: { |
||||
type: "bi.search_editor" |
||||
}, |
||||
|
||||
popup: { |
||||
type: "bi.searcher_view" |
||||
}, |
||||
|
||||
adapter: null, |
||||
masker: { // masker层
|
||||
offset: {} |
||||
} |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var self = this, o = this.options; |
||||
|
||||
this.editor = BI.createWidget(o.el, { |
||||
type: "bi.search_editor" |
||||
}); |
||||
|
||||
BI.createWidget({ |
||||
type: "bi.vertical", |
||||
element: this, |
||||
lgap: o.lgap, |
||||
rgap: o.rgap, |
||||
tgap: o.tgap, |
||||
bgap: o.bgap, |
||||
vgap: o.vgap, |
||||
hgap: o.hgap, |
||||
items: [this.editor] |
||||
}); |
||||
o.isDefaultInit && (this._assertPopupView()); |
||||
|
||||
var search = BI.debounce(BI.bind(this._search, this), BI.EVENT_RESPONSE_TIME, { |
||||
"leading": true, |
||||
"trailing": false |
||||
}); |
||||
this.editor.on(BI.Controller.EVENT_CHANGE, function (type) { |
||||
switch (type) { |
||||
case BI.Events.STARTEDIT: |
||||
self._startSearch(); |
||||
break; |
||||
case BI.Events.EMPTY: |
||||
self._stopSearch(); |
||||
break; |
||||
case BI.Events.CHANGE: |
||||
search(); |
||||
break; |
||||
case BI.Events.PAUSE: |
||||
if (BI.endWith(this.getValue(), BI.BlankSplitChar)) { |
||||
self._pauseSearch(); |
||||
} |
||||
break; |
||||
} |
||||
}); |
||||
}, |
||||
|
||||
_assertPopupView: function () { |
||||
var self = this, o = this.options; |
||||
if ((o.masker && !BI.Maskers.has(this.getName())) || (o.masker === false && !this.popupView)) { |
||||
this.popupView = BI.createWidget(o.popup, { |
||||
type: "bi.searcher_view", |
||||
chooseType: o.chooseType |
||||
}); |
||||
this.popupView.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); |
||||
if (type === BI.Events.CLICK) { |
||||
if (o.isAutoSync) { |
||||
var values = o.adapter && o.adapter.getValue(); |
||||
switch (o.chooseType) { |
||||
case BI.ButtonGroup.CHOOSE_TYPE_SINGLE: |
||||
o.adapter && o.adapter.setValue([obj.getValue()]); |
||||
break; |
||||
case BI.ButtonGroup.CHOOSE_TYPE_MULTI: |
||||
if (!obj.isSelected()) { |
||||
o.adapter && o.adapter.setValue(BI.deepWithout(values, obj.getValue())); |
||||
} |
||||
values.push(obj.getValue()); |
||||
o.adapter && o.adapter.setValue(values); |
||||
break; |
||||
} |
||||
} |
||||
self.fireEvent(BI.Searcher.EVENT_CHANGE, value, obj); |
||||
} |
||||
}); |
||||
BI.nextTick(function () { |
||||
self.fireEvent(BI.Searcher.EVENT_AFTER_INIT); |
||||
}); |
||||
} |
||||
if (o.masker && !BI.Maskers.has(this.getName())) { |
||||
BI.Maskers.create(this.getName(), o.adapter, BI.extend({ |
||||
container: this, |
||||
render: this.popupView |
||||
}, o.masker), this); |
||||
} |
||||
}, |
||||
|
||||
_startSearch: function () { |
||||
this._assertPopupView(); |
||||
this._stop = false; |
||||
this._isSearching = true; |
||||
this.fireEvent(BI.Searcher.EVENT_START); |
||||
this.popupView.startSearch && this.popupView.startSearch(); |
||||
// 搜索前先清空dom
|
||||
// BI.Maskers.get(this.getName()).empty();
|
||||
BI.nextTick(function (name) { |
||||
BI.Maskers.show(name); |
||||
}, this.getName()); |
||||
}, |
||||
|
||||
_pauseSearch: function () { |
||||
var o = this.options, name = this.getName(); |
||||
this._stop = true; |
||||
BI.nextTick(function (name) { |
||||
BI.Maskers.hide(name); |
||||
}, this.getName()); |
||||
if (this._isSearching === true) { |
||||
this.popupView && this.popupView.pauseSearch && this.popupView.pauseSearch(); |
||||
this.fireEvent(BI.Searcher.EVENT_PAUSE); |
||||
} |
||||
this._isSearching = false; |
||||
}, |
||||
|
||||
_stopSearch: function () { |
||||
var o = this.options, name = this.getName(); |
||||
this._stop = true; |
||||
BI.Maskers.hide(name); |
||||
if (this._isSearching === true) { |
||||
this.popupView && this.popupView.stopSearch && this.popupView.stopSearch(); |
||||
this.fireEvent(BI.Searcher.EVENT_STOP); |
||||
} |
||||
this._isSearching = false; |
||||
}, |
||||
|
||||
_search: function () { |
||||
var self = this, o = this.options, keyword = this.editor.getValue(); |
||||
if (keyword === "" || this._stop) { |
||||
return; |
||||
} |
||||
if (o.isAutoSearch) { |
||||
var items = (o.adapter && ((o.adapter.getItems && o.adapter.getItems()) || o.adapter.attr("items"))) || []; |
||||
var finding = BI.Func.getSearchResult(items, keyword); |
||||
var match = finding.match, find = finding.find; |
||||
this.popupView.populate(find, match, keyword); |
||||
o.isAutoSync && o.adapter && o.adapter.getValue && this.popupView.setValue(o.adapter.getValue()); |
||||
self.fireEvent(BI.Searcher.EVENT_SEARCHING); |
||||
return; |
||||
} |
||||
this.popupView.loading && this.popupView.loading(); |
||||
o.onSearch({ |
||||
times: 1, |
||||
keyword: keyword, |
||||
selectedValues: o.adapter && o.adapter.getValue() |
||||
}, function (searchResult, matchResult) { |
||||
if (!self._stop) { |
||||
var args = [].slice.call(arguments); |
||||
if (args.length > 0) { |
||||
args.push(keyword); |
||||
} |
||||
BI.Maskers.show(self.getName()); |
||||
self.popupView.populate.apply(self.popupView, args); |
||||
o.isAutoSync && o.adapter && o.adapter.getValue && self.popupView.setValue(o.adapter.getValue()); |
||||
self.popupView.loaded && self.popupView.loaded(); |
||||
self.fireEvent(BI.Searcher.EVENT_SEARCHING); |
||||
} |
||||
}); |
||||
}, |
||||
|
||||
_getLastSearchKeyword: function () { |
||||
if (this.isValid()) { |
||||
var res = this.editor.getValue().split(/\u200b\s\u200b/); |
||||
if (BI.isEmptyString(res[res.length - 1])) { |
||||
res = res.slice(0, res.length - 1); |
||||
} |
||||
return BI.isNull(res) ? "" : res[res.length - 1]; |
||||
} |
||||
}, |
||||
|
||||
setAdapter: function (adapter) { |
||||
this.options.adapter = adapter; |
||||
BI.Maskers.remove(this.getName()); |
||||
}, |
||||
|
||||
doSearch: function () { |
||||
if (this.isSearching()) { |
||||
this._search(); |
||||
} |
||||
}, |
||||
|
||||
stopSearch: function () { |
||||
this._stopSearch();// 先停止搜索,然后再去设置editor为空
|
||||
// important:停止搜索必须退出编辑状态,这里必须加上try(input框不显示时blur会抛异常)
|
||||
try { |
||||
this.editor.blur(); |
||||
} catch (e) { |
||||
if (!this.editor.blur) { |
||||
throw new Error("editor没有实现blur方法"); |
||||
} |
||||
} finally { |
||||
this.editor.setValue(""); |
||||
} |
||||
}, |
||||
|
||||
isSearching: function () { |
||||
return this._isSearching; |
||||
}, |
||||
|
||||
isViewVisible: function () { |
||||
return this.editor.isEnabled() && BI.Maskers.isVisible(this.getName()); |
||||
}, |
||||
|
||||
getView: function () { |
||||
return this.popupView; |
||||
}, |
||||
|
||||
hasMatched: function () { |
||||
this._assertPopupView(); |
||||
return this.popupView.hasMatched(); |
||||
}, |
||||
|
||||
adjustHeight: function () { |
||||
if (BI.Maskers.has(this.getName()) && BI.Maskers.get(this.getName()).isVisible()) { |
||||
BI.Maskers.show(this.getName()); |
||||
} |
||||
}, |
||||
|
||||
adjustView: function () { |
||||
this.isViewVisible() && BI.Maskers.show(this.getName()); |
||||
}, |
||||
|
||||
setValue: function (v) { |
||||
if (BI.isNull(this.popupView)) { |
||||
this.options.popup.value = v; |
||||
} else { |
||||
this.popupView.setValue(v); |
||||
} |
||||
}, |
||||
|
||||
getKeyword: function () { |
||||
return this._getLastSearchKeyword(); |
||||
}, |
||||
|
||||
getKeywords: function () { |
||||
return this.editor.getKeywords(); |
||||
}, |
||||
|
||||
getValue: function () { |
||||
var o = this.options; |
||||
if (o.isAutoSync && o.adapter && o.adapter.getValue) { |
||||
return o.adapter.getValue(); |
||||
} |
||||
if (this.isSearching()) { |
||||
return this.popupView.getValue(); |
||||
} else if (o.adapter && o.adapter.getValue) { |
||||
return o.adapter.getValue(); |
||||
} |
||||
if (BI.isNull(this.popupView)) { |
||||
return o.popup.value; |
||||
} |
||||
return this.popupView.getValue(); |
||||
|
||||
}, |
||||
|
||||
populate: function (result, searchResult, keyword) { |
||||
var o = this.options; |
||||
this._assertPopupView(); |
||||
this.popupView.populate.apply(this.popupView, arguments); |
||||
if (o.isAutoSync && o.adapter && o.adapter.getValue) { |
||||
this.popupView.setValue(o.adapter.getValue()); |
||||
} |
||||
}, |
||||
|
||||
empty: function () { |
||||
this.popupView && this.popupView.empty(); |
||||
}, |
||||
|
||||
destroyed: function () { |
||||
BI.Maskers.remove(this.getName()); |
||||
} |
||||
}); |
||||
BI.Searcher.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
BI.Searcher.EVENT_START = "EVENT_START"; |
||||
BI.Searcher.EVENT_STOP = "EVENT_STOP"; |
||||
BI.Searcher.EVENT_PAUSE = "EVENT_PAUSE"; |
||||
BI.Searcher.EVENT_SEARCHING = "EVENT_SEARCHING"; |
||||
BI.Searcher.EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; |
||||
|
||||
BI.shortcut("bi.searcher", BI.Searcher); |
@ -0,0 +1,291 @@
|
||||
/** |
||||
* |
||||
* 切换显示或隐藏面板 |
||||
* |
||||
* Created by GUY on 2015/11/2. |
||||
* @class BI.Switcher |
||||
* @extends BI.Widget |
||||
*/ |
||||
BI.Switcher = BI.inherit(BI.Widget, { |
||||
_defaultConfig: function () { |
||||
return BI.extend(BI.Switcher.superclass._defaultConfig.apply(this, arguments), { |
||||
baseCls: "bi-switcher", |
||||
direction: BI.Direction.Top, |
||||
trigger: "click", |
||||
toggle: true, |
||||
el: {}, |
||||
popup: {}, |
||||
adapter: null, |
||||
masker: {}, |
||||
switcherClass: "bi-switcher-popup", |
||||
hoverClass: "bi-switcher-hover" |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var self = this, o = this.options; |
||||
this._initSwitcher(); |
||||
this._initPullDownAction(); |
||||
this.switcher.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { |
||||
if (self.isEnabled() && self.isValid()) { |
||||
if (type === BI.Events.EXPAND) { |
||||
self._popupView(); |
||||
} |
||||
if (type === BI.Events.COLLAPSE) { |
||||
self._hideView(); |
||||
} |
||||
if (type === BI.Events.EXPAND) { |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); |
||||
self.fireEvent(BI.Switcher.EVENT_EXPAND); |
||||
} |
||||
if (type === BI.Events.COLLAPSE) { |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); |
||||
self.isViewVisible() && self.fireEvent(BI.Switcher.EVENT_COLLAPSE); |
||||
} |
||||
if (type === BI.Events.CLICK) { |
||||
self.fireEvent(BI.Switcher.EVENT_TRIGGER_CHANGE, value, obj); |
||||
} |
||||
} |
||||
}); |
||||
|
||||
this.element.hover(function () { |
||||
if (self.isEnabled() && self.switcher.isEnabled()) { |
||||
self.element.addClass(o.hoverClass); |
||||
} |
||||
}, function () { |
||||
if (self.isEnabled() && self.switcher.isEnabled()) { |
||||
self.element.removeClass(o.hoverClass); |
||||
} |
||||
}); |
||||
BI.createWidget({ |
||||
type: "bi.vertical", |
||||
scrolly: false, |
||||
element: this, |
||||
items: [ |
||||
{el: this.switcher} |
||||
] |
||||
}); |
||||
o.isDefaultInit && (this._assertPopupView()); |
||||
}, |
||||
|
||||
_toggle: function () { |
||||
this._assertPopupView(); |
||||
if (this.isExpanded()) { |
||||
this._hideView(); |
||||
} else { |
||||
if (this.isEnabled()) { |
||||
this._popupView(); |
||||
} |
||||
} |
||||
}, |
||||
|
||||
_initPullDownAction: function () { |
||||
var self = this, o = this.options; |
||||
var evs = this.options.trigger.split(","); |
||||
BI.each(evs, function (i, e) { |
||||
switch (e) { |
||||
case "hover": |
||||
self.element[e](function (e) { |
||||
if (self.isEnabled() && self.switcher.isEnabled()) { |
||||
self._popupView(); |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.switcher); |
||||
self.fireEvent(BI.Switcher.EVENT_EXPAND); |
||||
} |
||||
}, function () { |
||||
if (self.isEnabled() && self.switcher.isEnabled() && o.toggle) { |
||||
self._hideView(); |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", self.switcher); |
||||
self.fireEvent(BI.Switcher.EVENT_COLLAPSE); |
||||
} |
||||
}); |
||||
break; |
||||
default : |
||||
if (e) { |
||||
self.element.off(e + "." + self.getName()).on(e + "." + self.getName(), BI.debounce(function (e) { |
||||
if (self.switcher.element.__isMouseInBounds__(e)) { |
||||
if (self.isEnabled() && self.switcher.isEnabled()) { |
||||
o.toggle ? self._toggle() : self._popupView(); |
||||
if (self.isExpanded()) { |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.switcher); |
||||
self.fireEvent(BI.Switcher.EVENT_EXPAND); |
||||
} else { |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", self.switcher); |
||||
self.fireEvent(BI.Switcher.EVENT_COLLAPSE); |
||||
} |
||||
} |
||||
} |
||||
}, BI.EVENT_RESPONSE_TIME, { |
||||
"leading": true, |
||||
"trailing": false |
||||
})); |
||||
} |
||||
break; |
||||
} |
||||
}); |
||||
}, |
||||
|
||||
_initSwitcher: function () { |
||||
this.switcher = BI.createWidget(this.options.el, { |
||||
value: this.options.value |
||||
}); |
||||
}, |
||||
|
||||
_assertPopupView: function () { |
||||
var self = this, o = this.options; |
||||
if (!this._created) { |
||||
this.popupView = BI.createWidget(o.popup, { |
||||
type: "bi.button_group", |
||||
element: o.adapter && BI.Maskers.create(this.getName(), o.adapter, BI.extend({container: this}, o.masker)), |
||||
cls: "switcher-popup", |
||||
layouts: [{ |
||||
type: "bi.vertical", |
||||
hgap: 0, |
||||
vgap: 0 |
||||
}], |
||||
value: o.value |
||||
}, this); |
||||
this.popupView.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); |
||||
if (type === BI.Events.CLICK) { |
||||
self.fireEvent(BI.Switcher.EVENT_CHANGE, value, obj); |
||||
} |
||||
}); |
||||
if (o.direction !== BI.Direction.Custom && !o.adapter) { |
||||
BI.createWidget({ |
||||
type: "bi.vertical", |
||||
scrolly: false, |
||||
element: this, |
||||
items: [ |
||||
{el: this.popupView} |
||||
] |
||||
}); |
||||
} |
||||
this._created = true; |
||||
BI.nextTick(function () { |
||||
self.fireEvent(BI.Switcher.EVENT_AFTER_INIT); |
||||
}); |
||||
} |
||||
}, |
||||
|
||||
_hideView: function () { |
||||
this.fireEvent(BI.Switcher.EVENT_BEFORE_HIDEVIEW); |
||||
var self = this, o = this.options; |
||||
o.adapter ? BI.Maskers.hide(self.getName()) : (self.popupView && self.popupView.setVisible(false)); |
||||
BI.nextTick(function () { |
||||
o.adapter ? BI.Maskers.hide(self.getName()) : (self.popupView && self.popupView.setVisible(false)); |
||||
self.element.removeClass(o.switcherClass); |
||||
self.fireEvent(BI.Switcher.EVENT_AFTER_HIDEVIEW); |
||||
}); |
||||
}, |
||||
|
||||
_popupView: function () { |
||||
var self = this, o = this.options; |
||||
this._assertPopupView(); |
||||
this.fireEvent(BI.Switcher.EVENT_BEFORE_POPUPVIEW); |
||||
o.adapter ? BI.Maskers.show(this.getName()) : self.popupView.setVisible(true); |
||||
BI.nextTick(function (name) { |
||||
o.adapter ? BI.Maskers.show(name) : self.popupView.setVisible(true); |
||||
self.element.addClass(o.switcherClass); |
||||
self.fireEvent(BI.Switcher.EVENT_AFTER_POPUPVIEW); |
||||
}, this.getName()); |
||||
}, |
||||
|
||||
_populate: function () { |
||||
this._assertPopupView(); |
||||
this.popupView.populate.apply(this.popupView, arguments); |
||||
}, |
||||
|
||||
populate: function (items) { |
||||
this._populate.apply(this, arguments); |
||||
this.switcher.populate && this.switcher.populate.apply(this.switcher, arguments); |
||||
}, |
||||
|
||||
_setEnable: function (arg) { |
||||
BI.Switcher.superclass._setEnable.apply(this, arguments); |
||||
!arg && this.isViewVisible() && this._hideView(); |
||||
}, |
||||
|
||||
setValue: function (v) { |
||||
this.switcher.setValue(v); |
||||
if (BI.isNull(this.popupView)) { |
||||
this.options.popup.value = v; |
||||
} else { |
||||
this.popupView.setValue(v); |
||||
} |
||||
}, |
||||
|
||||
getValue: function () { |
||||
if (BI.isNull(this.popupView)) { |
||||
return this.options.popup.value; |
||||
} else { |
||||
return this.popupView.getValue(); |
||||
} |
||||
}, |
||||
|
||||
setAdapter: function (adapter) { |
||||
this.options.adapter = adapter; |
||||
BI.Maskers.remove(this.getName()); |
||||
}, |
||||
|
||||
isViewVisible: function () { |
||||
return this.isEnabled() && this.switcher.isEnabled() && |
||||
(this.options.adapter ? BI.Maskers.isVisible(this.getName()) : (this.popupView && this.popupView.isVisible())); |
||||
}, |
||||
|
||||
isExpanded: function () { |
||||
return this.isViewVisible(); |
||||
}, |
||||
|
||||
showView: function () { |
||||
if (this.isEnabled() && this.switcher.isEnabled()) { |
||||
this._popupView(); |
||||
} |
||||
}, |
||||
|
||||
hideView: function () { |
||||
this._hideView(); |
||||
}, |
||||
|
||||
getView: function () { |
||||
return this.popupView; |
||||
}, |
||||
|
||||
adjustView: function () { |
||||
this.isViewVisible() && BI.Maskers.show(this.getName()); |
||||
}, |
||||
|
||||
getAllLeaves: function () { |
||||
return this.popupView && this.popupView.getAllLeaves(); |
||||
}, |
||||
|
||||
getNodeById: function (id) { |
||||
if (this.switcher.attr("id") === id) { |
||||
return this.switcher; |
||||
} |
||||
return this.popupView && this.popupView.getNodeById(id); |
||||
}, |
||||
|
||||
getNodeByValue: function (value) { |
||||
if (this.switcher.getValue() === value) { |
||||
return this.switcher; |
||||
} |
||||
return this.popupView && this.popupView.getNodeByValue(value); |
||||
}, |
||||
|
||||
empty: function () { |
||||
this.popupView && this.popupView.empty(); |
||||
} |
||||
}); |
||||
BI.Switcher.EVENT_EXPAND = "EVENT_EXPAND"; |
||||
BI.Switcher.EVENT_COLLAPSE = "EVENT_COLLAPSE"; |
||||
BI.Switcher.EVENT_TRIGGER_CHANGE = "EVENT_TRIGGER_CHANGE"; |
||||
BI.Switcher.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
BI.Switcher.EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; |
||||
|
||||
|
||||
BI.Switcher.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; |
||||
BI.Switcher.EVENT_AFTER_POPUPVIEW = "EVENT_AFTER_POPUPVIEW"; |
||||
BI.Switcher.EVENT_BEFORE_HIDEVIEW = "EVENT_BEFORE_HIDEVIEW"; |
||||
BI.Switcher.EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; |
||||
|
||||
BI.shortcut("bi.switcher", BI.Switcher); |
@ -0,0 +1,157 @@
|
||||
/** |
||||
* Created by GUY on 2015/6/26. |
||||
*/ |
||||
|
||||
BI.Tab = BI.inherit(BI.Widget, { |
||||
_defaultConfig: function () { |
||||
return BI.extend(BI.Tab.superclass._defaultConfig.apply(this, arguments), { |
||||
baseCls: "bi-tab", |
||||
direction: "top", // top, bottom, left, right, custom
|
||||
single: false, // 是不是单页面
|
||||
logic: { |
||||
dynamic: false |
||||
}, |
||||
showIndex: false, |
||||
tab: false, |
||||
cardCreator: function (v) { |
||||
return BI.createWidget(); |
||||
} |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var self = this, o = this.options; |
||||
if (BI.isObject(o.tab)) { |
||||
this.tab = BI.createWidget(this.options.tab, {type: "bi.button_group"}); |
||||
this.tab.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); |
||||
}); |
||||
} |
||||
this.cardMap = {}; |
||||
this.layout = BI.createWidget({ |
||||
type: "bi.card" |
||||
}); |
||||
|
||||
BI.createWidget(BI.extend({ |
||||
element: this |
||||
}, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(o.direction), BI.extend({}, o.logic, { |
||||
items: BI.LogicFactory.createLogicItemsByDirection(o.direction, this.tab, this.layout) |
||||
})))); |
||||
|
||||
var listener = new BI.ShowListener({ |
||||
eventObj: this.tab, |
||||
cardLayout: this.layout, |
||||
cardCreator: function (v) { |
||||
var card = o.cardCreator.apply(self, arguments); |
||||
self.cardMap[v] = card; |
||||
return card; |
||||
}, |
||||
afterCardShow: function (v) { |
||||
self._deleteOtherCards(v); |
||||
self.curr = v; |
||||
} |
||||
}); |
||||
listener.on(BI.ShowListener.EVENT_CHANGE, function (value) { |
||||
self.fireEvent(BI.Tab.EVENT_CHANGE, value, self); |
||||
}); |
||||
}, |
||||
|
||||
_deleteOtherCards: function (currCardName) { |
||||
var self = this, o = this.options; |
||||
if (o.single === true) { |
||||
BI.each(this.cardMap, function (name, card) { |
||||
if (name !== (currCardName + "")) { |
||||
self.layout.deleteCardByName(name); |
||||
delete self.cardMap[name]; |
||||
} |
||||
}); |
||||
} |
||||
}, |
||||
|
||||
_assertCard: function (v) { |
||||
if (!this.layout.isCardExisted(v)) { |
||||
var card = this.options.cardCreator(v); |
||||
this.cardMap[v] = card; |
||||
this.layout.addCardByName(v, card); |
||||
} |
||||
}, |
||||
|
||||
created: function () { |
||||
var o = this.options; |
||||
if (o.showIndex !== false) { |
||||
this.setSelect(o.showIndex); |
||||
} |
||||
}, |
||||
|
||||
setSelect: function (v, action, callback) { |
||||
this.tab && this.tab.setValue(v); |
||||
this._assertCard(v); |
||||
this.layout.showCardByName(v, action, callback); |
||||
this._deleteOtherCards(v); |
||||
if (this.curr !== v) { |
||||
this.curr = v; |
||||
} |
||||
}, |
||||
|
||||
removeTab: function (cardname) { |
||||
var self = this, o = this.options; |
||||
BI.any(this.cardMap, function (name, card) { |
||||
if (BI.isEqual(name, (cardname + ""))) { |
||||
self.layout.deleteCardByName(name); |
||||
delete self.cardMap[name]; |
||||
return true; |
||||
} |
||||
}); |
||||
}, |
||||
|
||||
isCardExisted: function (cardName) { |
||||
return this.layout.isCardExisted(cardName); |
||||
}, |
||||
|
||||
getSelect: function () { |
||||
return this.curr; |
||||
}, |
||||
|
||||
getSelectedTab: function () { |
||||
return this.layout.getShowingCard(); |
||||
}, |
||||
|
||||
getTab: function (v) { |
||||
this._assertCard(v); |
||||
return this.layout.getCardByName(v); |
||||
}, |
||||
|
||||
setValue: function (v) { |
||||
var card = this.layout.getShowingCard(); |
||||
if (card) { |
||||
card.setValue(v); |
||||
} |
||||
}, |
||||
|
||||
getValue: function () { |
||||
var card = this.layout.getShowingCard(); |
||||
if (card) { |
||||
return card.getValue(); |
||||
} |
||||
}, |
||||
|
||||
populate: function () { |
||||
var card = this.layout.getShowingCard(); |
||||
if (card) { |
||||
return card.populate && card.populate.apply(card, arguments); |
||||
} |
||||
}, |
||||
|
||||
empty: function () { |
||||
this.layout.deleteAllCard(); |
||||
this.cardMap = {}; |
||||
}, |
||||
|
||||
destroy: function () { |
||||
this.cardMap = {}; |
||||
BI.Tab.superclass.destroy.apply(this, arguments); |
||||
} |
||||
}); |
||||
BI.Tab.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
|
||||
BI.shortcut("bi.tab", BI.Tab); |
@ -0,0 +1,178 @@
|
||||
/** |
||||
* Created by GUY on 2015/8/10. |
||||
* @class BI.ButtonTree |
||||
* @extends BI.ButtonGroup |
||||
*/ |
||||
|
||||
BI.ButtonTree = BI.inherit(BI.ButtonGroup, { |
||||
_defaultConfig: function () { |
||||
return BI.extend(BI.ButtonTree.superclass._defaultConfig.apply(this, arguments), { |
||||
baseCls: "bi-button-tree" |
||||
}); |
||||
}, |
||||
|
||||
setNotSelectedValue: function (v) { |
||||
v = BI.isArray(v) ? v : [v]; |
||||
BI.each(this.buttons, function (i, item) { |
||||
if (!BI.isFunction(item.setSelected)) { |
||||
item.setNotSelectedValue(v); |
||||
return; |
||||
} |
||||
if (BI.deepContains(v, item.getValue())) { |
||||
item.setSelected(false); |
||||
} else { |
||||
item.setSelected(true); |
||||
} |
||||
}); |
||||
}, |
||||
|
||||
setEnabledValue: function (v) { |
||||
v = BI.isArray(v) ? v : [v]; |
||||
BI.each(this.buttons, function (i, item) { |
||||
if (BI.isFunction(item.setEnabledValue)) { |
||||
item.setEnabledValue(v); |
||||
return; |
||||
} |
||||
if (BI.deepContains(v, item.getValue())) { |
||||
item.setEnable(true); |
||||
} else { |
||||
item.setEnable(false); |
||||
} |
||||
}); |
||||
}, |
||||
|
||||
setValue: function (v) { |
||||
v = BI.isArray(v) ? v : [v]; |
||||
BI.each(this.buttons, function (i, item) { |
||||
if (!BI.isFunction(item.setSelected)) { |
||||
item.setValue(v); |
||||
return; |
||||
} |
||||
if (BI.deepContains(v, item.getValue())) { |
||||
item.setSelected(true); |
||||
} else { |
||||
item.setSelected(false); |
||||
} |
||||
}); |
||||
}, |
||||
|
||||
getNotSelectedValue: function () { |
||||
var v = []; |
||||
BI.each(this.buttons, function (i, item) { |
||||
if (item.isEnabled() && !BI.isFunction(item.setSelected)) { |
||||
v = BI.concat(v, item.getNotSelectedValue()); |
||||
return; |
||||
} |
||||
if (item.isEnabled() && item.isSelected && !item.isSelected()) { |
||||
v.push(item.getValue()); |
||||
} |
||||
}); |
||||
return v; |
||||
}, |
||||
|
||||
getValue: function () { |
||||
var v = []; |
||||
BI.each(this.buttons, function (i, item) { |
||||
if (item.isEnabled() && !BI.isFunction(item.setSelected)) { |
||||
v = BI.concat(v, item.getValue()); |
||||
return; |
||||
} |
||||
if (item.isEnabled() && item.isSelected && item.isSelected()) { |
||||
v.push(item.getValue()); |
||||
} |
||||
}); |
||||
return v; |
||||
}, |
||||
|
||||
getSelectedButtons: function () { |
||||
var btns = []; |
||||
BI.each(this.buttons, function (i, item) { |
||||
if (item.isEnabled() && !BI.isFunction(item.setSelected)) { |
||||
btns = btns.concat(item.getSelectedButtons()); |
||||
return; |
||||
} |
||||
if (item.isSelected && item.isSelected()) { |
||||
btns.push(item); |
||||
} |
||||
}); |
||||
return btns; |
||||
}, |
||||
|
||||
getNotSelectedButtons: function () { |
||||
var btns = []; |
||||
BI.each(this.buttons, function (i, item) { |
||||
if (item.isEnabled() && !BI.isFunction(item.setSelected)) { |
||||
btns = btns.concat(item.getNotSelectedButtons()); |
||||
return; |
||||
} |
||||
if (item.isSelected && !item.isSelected()) { |
||||
btns.push(item); |
||||
} |
||||
}); |
||||
return btns; |
||||
}, |
||||
|
||||
// 获取所有的叶子节点
|
||||
getAllLeaves: function () { |
||||
var leaves = []; |
||||
BI.each(this.buttons, function (i, item) { |
||||
if (item.isEnabled() && !BI.isFunction(item.setSelected)) { |
||||
leaves = leaves.concat(item.getAllLeaves()); |
||||
return; |
||||
} |
||||
if (item.isEnabled()) { |
||||
leaves.push(item); |
||||
} |
||||
}); |
||||
return leaves; |
||||
}, |
||||
|
||||
getIndexByValue: function (value) { |
||||
var index = -1; |
||||
BI.any(this.buttons, function (i, item) { |
||||
var vs = item.getValue(); |
||||
if (item.isEnabled() && (vs === value || BI.contains(vs, value))) { |
||||
index = i; |
||||
return true; |
||||
} |
||||
}); |
||||
return index; |
||||
}, |
||||
|
||||
getNodeById: function (id) { |
||||
var node; |
||||
BI.any(this.buttons, function (i, item) { |
||||
if (item.isEnabled()) { |
||||
if (item.attr("id") === id) { |
||||
node = item; |
||||
return true; |
||||
} else if (BI.isFunction(item.getNodeById)) { |
||||
if (node = item.getNodeById(id)) { |
||||
return true; |
||||
} |
||||
} |
||||
} |
||||
}); |
||||
return node; |
||||
}, |
||||
|
||||
getNodeByValue: function (value) { |
||||
var node; |
||||
BI.any(this.buttons, function (i, item) { |
||||
if (item.isEnabled()) { |
||||
if (BI.isFunction(item.getNodeByValue)) { |
||||
if (node = item.getNodeByValue(value)) { |
||||
return true; |
||||
} |
||||
} else if (item.attr("value") === value) { |
||||
node = item; |
||||
return true; |
||||
} |
||||
} |
||||
}); |
||||
return node; |
||||
} |
||||
}); |
||||
BI.ButtonTree.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
|
||||
BI.shortcut("bi.button_tree", BI.ButtonTree); |
@ -0,0 +1,38 @@
|
||||
/** |
||||
* 表示当前对象 |
||||
* |
||||
* Created by GUY on 2015/9/7. |
||||
* @class BI.EL |
||||
* @extends BI.Widget |
||||
*/ |
||||
BI.EL = BI.inherit(BI.Widget, { |
||||
_defaultConfig: function () { |
||||
return BI.extend(BI.EL.superclass._defaultConfig.apply(this, arguments), { |
||||
baseCls: "bi-el", |
||||
el: {} |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var self = this, o = this.options; |
||||
this.ele = BI.createWidget(o.el, { |
||||
element: this |
||||
}); |
||||
this.ele.on(BI.Controller.EVENT_CHANGE, function () { |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); |
||||
}); |
||||
}, |
||||
|
||||
setValue: function (v) { |
||||
this.ele.setValue(v); |
||||
}, |
||||
|
||||
getValue: function () { |
||||
return this.ele.getValue(); |
||||
}, |
||||
|
||||
populate: function () { |
||||
this.ele.populate.apply(this, arguments); |
||||
} |
||||
}); |
||||
BI.shortcut("bi.el", BI.EL); |
@ -0,0 +1,47 @@
|
||||
/** |
||||
* @author windy |
||||
* @version 2.0 |
||||
* Created by windy on 2020/3/9 |
||||
*/ |
||||
describe("MessageTest", function () { |
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("alert", function (done) { |
||||
BI.Msg.alert("message", "ASASASASA"); |
||||
var body = BI.Widget._renderEngine.createElement("body"); |
||||
expect(body.find(".bi-message-depend").length).to.equal(1); |
||||
BI.nextTick(function () { |
||||
body.find(".bi-message-depend .bi-button").click(); |
||||
expect(body.find(".bi-message-depend").length).to.equal(0); |
||||
done(); |
||||
}); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("toast_hand_close", function (done) { |
||||
BI.Msg.toast("message", { |
||||
autoClose: false |
||||
}); |
||||
var body = BI.Widget._renderEngine.createElement("body"); |
||||
expect(body.find(".bi-toast").length).to.equal(1); |
||||
BI.nextTick(function () { |
||||
body.find(".bi-toast .bi-icon-button").click(); |
||||
expect(body.find(".bi-toast").length).to.equal(0); |
||||
done(); |
||||
}); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("toast_auto_close", function () { |
||||
BI.Msg.toast("message"); |
||||
var body = BI.Widget._renderEngine.createElement("body"); |
||||
expect(body.find(".bi-toast").length).to.equal(1); |
||||
}); |
||||
}); |
||||
|
@ -0,0 +1,203 @@
|
||||
/** |
||||
* z-index在1亿层级 |
||||
* 弹出提示消息框,用于模拟阻塞操作(通过回调函数实现) |
||||
* @class BI.Msg |
||||
*/ |
||||
BI.Msg = function () { |
||||
|
||||
var $mask, $pop; |
||||
|
||||
var messageShows = []; |
||||
|
||||
var toastStack = []; |
||||
|
||||
return { |
||||
alert: function (title, message, callback) { |
||||
this._show(false, title, message, callback); |
||||
}, |
||||
confirm: function (title, message, callback) { |
||||
this._show(true, title, message, callback); |
||||
}, |
||||
prompt: function (title, message, value, callback, min_width) { |
||||
// BI.Msg.prompt(title, message, value, callback, min_width);
|
||||
}, |
||||
toast: function (message, options, context) { |
||||
options = options || {}; |
||||
context = context || BI.Widget._renderEngine.createElement("body"); |
||||
var level = options.level || "common"; |
||||
var autoClose = BI.isNull(options.autoClose) ? true : options.autoClose; |
||||
var callback = BI.isFunction(options.callback) ? options.callback : BI.emptyFn; |
||||
var toast = BI.createWidget({ |
||||
type: "bi.toast", |
||||
cls: "bi-message-animate bi-message-leave", |
||||
level: level, |
||||
autoClose: autoClose, |
||||
text: message, |
||||
listeners: [{ |
||||
eventName: BI.Toast.EVENT_DESTORY, |
||||
action: function () { |
||||
BI.remove(toastStack, toast.element); |
||||
var _height = BI.SIZE_CONSANTS.TOAST_TOP; |
||||
BI.each(toastStack, function (i, element) { |
||||
element.css({"top": _height}); |
||||
_height += element.outerHeight() + 10; |
||||
}); |
||||
callback(); |
||||
} |
||||
}] |
||||
}); |
||||
var height = BI.SIZE_CONSANTS.TOAST_TOP; |
||||
BI.each(toastStack, function (i, element) { |
||||
height += element.outerHeight() + 10; |
||||
}); |
||||
BI.createWidget({ |
||||
type: "bi.absolute", |
||||
element: context, |
||||
items: [{ |
||||
el: toast, |
||||
left: "50%", |
||||
top: height |
||||
}] |
||||
}); |
||||
toastStack.push(toast.element); |
||||
toast.element.css({"margin-left": -1 * toast.element.outerWidth() / 2}); |
||||
toast.element.removeClass("bi-message-leave").addClass("bi-message-enter"); |
||||
|
||||
autoClose && BI.delay(function () { |
||||
toast.element.removeClass("bi-message-enter").addClass("bi-message-leave"); |
||||
toast.destroy(); |
||||
}, 5000); |
||||
}, |
||||
_show: function (hasCancel, title, message, callback) { |
||||
BI.isNull($mask) && ($mask = BI.Widget._renderEngine.createElement("<div class=\"bi-z-index-mask\">").css({ |
||||
position: "absolute", |
||||
zIndex: BI.zIndex_tip - 2, |
||||
top: 0, |
||||
left: 0, |
||||
right: 0, |
||||
bottom: 0, |
||||
opacity: 0.5 |
||||
}).appendTo("body")); |
||||
$pop = BI.Widget._renderEngine.createElement("<div class=\"bi-message-depend\">").css({ |
||||
position: "absolute", |
||||
zIndex: BI.zIndex_tip - 1, |
||||
top: 0, |
||||
left: 0, |
||||
right: 0, |
||||
bottom: 0 |
||||
}).appendTo("body"); |
||||
var close = function () { |
||||
messageShows[messageShows.length - 1].destroy(); |
||||
messageShows.pop(); |
||||
if (messageShows.length === 0) { |
||||
$mask.remove(); |
||||
$mask = null; |
||||
} |
||||
}; |
||||
var controlItems = []; |
||||
if (hasCancel === true) { |
||||
controlItems.push({ |
||||
el: { |
||||
type: "bi.button", |
||||
text: BI.i18nText("BI-Basic_Cancel"), |
||||
level: "ignore", |
||||
handler: function () { |
||||
close(); |
||||
if (BI.isFunction(callback)) { |
||||
callback.apply(null, [false]); |
||||
} |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
controlItems.push({ |
||||
el: { |
||||
type: "bi.button", |
||||
text: BI.i18nText("BI-Basic_OK"), |
||||
handler: function () { |
||||
close(); |
||||
if (BI.isFunction(callback)) { |
||||
callback.apply(null, [true]); |
||||
} |
||||
} |
||||
} |
||||
}); |
||||
var conf = { |
||||
element: $pop, |
||||
type: "bi.center_adapt", |
||||
items: [ |
||||
{ |
||||
type: "bi.border", |
||||
cls: "bi-card", |
||||
items: { |
||||
north: { |
||||
el: { |
||||
type: "bi.border", |
||||
cls: "bi-message-title bi-background", |
||||
items: { |
||||
center: { |
||||
el: { |
||||
type: "bi.label", |
||||
cls: "bi-font-bold", |
||||
text: title || BI.i18nText("BI-Basic_Prompt"), |
||||
textAlign: "left", |
||||
hgap: 20, |
||||
height: 40 |
||||
} |
||||
}, |
||||
east: { |
||||
el: { |
||||
type: "bi.icon_button", |
||||
cls: "bi-message-close close-font", |
||||
// height: 50,
|
||||
handler: function () { |
||||
close(); |
||||
if (BI.isFunction(callback)) { |
||||
callback.apply(null, [false]); |
||||
} |
||||
} |
||||
}, |
||||
width: 60 |
||||
} |
||||
} |
||||
}, |
||||
height: 40 |
||||
}, |
||||
center: { |
||||
el: { |
||||
type: "bi.label", |
||||
vgap: 10, |
||||
hgap: 20, |
||||
whiteSpace: "normal", |
||||
text: message |
||||
} |
||||
}, |
||||
south: { |
||||
el: { |
||||
type: "bi.absolute", |
||||
items: [{ |
||||
el: { |
||||
type: "bi.right_vertical_adapt", |
||||
lgap: 10, |
||||
items: controlItems |
||||
}, |
||||
top: 0, |
||||
left: 20, |
||||
right: 20, |
||||
bottom: 0 |
||||
}] |
||||
|
||||
}, |
||||
height: 44 |
||||
} |
||||
}, |
||||
width: 450, |
||||
height: 200 |
||||
} |
||||
] |
||||
}; |
||||
|
||||
messageShows[messageShows.length] = BI.createWidget(conf); |
||||
} |
||||
}; |
||||
}(); |
@ -0,0 +1,41 @@
|
||||
/** |
||||
* @author windy |
||||
* @version 2.0 |
||||
* Created by windy on 2020/3/20 |
||||
*/ |
||||
describe("GridTest", function () { |
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("grid", function () { |
||||
var items = []; |
||||
var rowCount = 1000, columnCount = 100; |
||||
for (var i = 0; i < rowCount; i++) { |
||||
items[i] = []; |
||||
for (var j = 0; j < columnCount; j++) { |
||||
items[i][j] = { |
||||
type: "bi.label", |
||||
text: i + "-" + j |
||||
}; |
||||
} |
||||
} |
||||
var grid = BI.createWidget({ |
||||
type: "bi.grid_view", |
||||
width: 400, |
||||
height: 300, |
||||
estimatedRowSize: 30, |
||||
estimatedColumnSize: 100, |
||||
items: items, |
||||
scrollTop: 100, |
||||
rowHeightGetter: function () { |
||||
return 30; |
||||
}, |
||||
columnWidthGetter: function () { |
||||
return 100; |
||||
} |
||||
}); |
||||
// TODO 性能展示类控件,不知道要测啥,标记一下
|
||||
grid.destroy(); |
||||
}); |
||||
}); |
@ -0,0 +1,381 @@
|
||||
/** |
||||
* GridView |
||||
* |
||||
* Created by GUY on 2016/1/11. |
||||
* @class BI.GridView |
||||
* @extends BI.Widget |
||||
*/ |
||||
BI.GridView = BI.inherit(BI.Widget, { |
||||
_defaultConfig: function () { |
||||
return BI.extend(BI.GridView.superclass._defaultConfig.apply(this, arguments), { |
||||
baseCls: "bi-grid-view", |
||||
// width: 400, //必设
|
||||
// height: 300, //必设
|
||||
overflowX: true, |
||||
overflowY: true, |
||||
overscanColumnCount: 0, |
||||
overscanRowCount: 0, |
||||
rowHeightGetter: BI.emptyFn, // number类型或function类型
|
||||
columnWidthGetter: BI.emptyFn, // number类型或function类型
|
||||
// estimatedColumnSize: 100, //columnWidthGetter为function时必设
|
||||
// estimatedRowSize: 30, //rowHeightGetter为function时必设
|
||||
scrollLeft: 0, |
||||
scrollTop: 0, |
||||
items: [] |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var self = this, o = this.options; |
||||
this.renderedCells = []; |
||||
this.renderedKeys = []; |
||||
this.renderRange = {}; |
||||
this._scrollLock = false; |
||||
this._debounceRelease = BI.debounce(function () { |
||||
self._scrollLock = false; |
||||
}, 1000 / 60); |
||||
this.container = BI._lazyCreateWidget({ |
||||
type: "bi.absolute" |
||||
}); |
||||
this.element.scroll(function () { |
||||
if (self._scrollLock === true) { |
||||
return; |
||||
} |
||||
o.scrollLeft = self.element.scrollLeft(); |
||||
o.scrollTop = self.element.scrollTop(); |
||||
self._calculateChildrenToRender(); |
||||
self.fireEvent(BI.GridView.EVENT_SCROLL, { |
||||
scrollLeft: o.scrollLeft, |
||||
scrollTop: o.scrollTop |
||||
}); |
||||
}); |
||||
BI._lazyCreateWidget({ |
||||
type: "bi.vertical", |
||||
element: this, |
||||
scrollable: o.overflowX === true && o.overflowY === true, |
||||
scrolly: o.overflowX === false && o.overflowY === true, |
||||
scrollx: o.overflowX === true && o.overflowY === false, |
||||
items: [this.container] |
||||
}); |
||||
if (o.items.length > 0) { |
||||
this._calculateSizeAndPositionData(); |
||||
this._populate(); |
||||
} |
||||
}, |
||||
|
||||
// mounted之后绑定事件
|
||||
mounted: function () { |
||||
var o = this.options; |
||||
if (o.scrollLeft !== 0 || o.scrollTop !== 0) { |
||||
this.element.scrollTop(o.scrollTop); |
||||
this.element.scrollLeft(o.scrollLeft); |
||||
} |
||||
}, |
||||
|
||||
_calculateSizeAndPositionData: function () { |
||||
var o = this.options; |
||||
this.rowCount = 0; |
||||
this.columnCount = 0; |
||||
if (BI.isNumber(o.columnCount)) { |
||||
this.columnCount = o.columnCount; |
||||
} else if (o.items.length > 0) { |
||||
this.columnCount = o.items[0].length; |
||||
} |
||||
if (BI.isNumber(o.rowCount)) { |
||||
this.rowCount = o.rowCount; |
||||
} else { |
||||
this.rowCount = o.items.length; |
||||
} |
||||
this._columnSizeAndPositionManager = new BI.ScalingCellSizeAndPositionManager(this.columnCount, o.columnWidthGetter, o.estimatedColumnSize); |
||||
this._rowSizeAndPositionManager = new BI.ScalingCellSizeAndPositionManager(this.rowCount, o.rowHeightGetter, o.estimatedRowSize); |
||||
}, |
||||
|
||||
_getOverscanIndices: function (cellCount, overscanCellsCount, startIndex, stopIndex) { |
||||
return { |
||||
overscanStartIndex: Math.max(0, startIndex - overscanCellsCount), |
||||
overscanStopIndex: Math.min(cellCount - 1, stopIndex + overscanCellsCount) |
||||
}; |
||||
}, |
||||
|
||||
_calculateChildrenToRender: function () { |
||||
var self = this, o = this.options; |
||||
|
||||
var width = o.width, height = o.height, scrollLeft = BI.clamp(o.scrollLeft, 0, this._getMaxScrollLeft()), |
||||
scrollTop = BI.clamp(o.scrollTop, 0, this._getMaxScrollTop()), |
||||
overscanColumnCount = o.overscanColumnCount, overscanRowCount = o.overscanRowCount; |
||||
|
||||
if (height > 0 && width > 0) { |
||||
var visibleColumnIndices = this._columnSizeAndPositionManager.getVisibleCellRange(width, scrollLeft); |
||||
var visibleRowIndices = this._rowSizeAndPositionManager.getVisibleCellRange(height, scrollTop); |
||||
|
||||
if (BI.isEmpty(visibleColumnIndices) || BI.isEmpty(visibleRowIndices)) { |
||||
return; |
||||
} |
||||
var horizontalOffsetAdjustment = this._columnSizeAndPositionManager.getOffsetAdjustment(width, scrollLeft); |
||||
var verticalOffsetAdjustment = this._rowSizeAndPositionManager.getOffsetAdjustment(height, scrollTop); |
||||
|
||||
this._renderedColumnStartIndex = visibleColumnIndices.start; |
||||
this._renderedColumnStopIndex = visibleColumnIndices.stop; |
||||
this._renderedRowStartIndex = visibleRowIndices.start; |
||||
this._renderedRowStopIndex = visibleRowIndices.stop; |
||||
|
||||
var overscanColumnIndices = this._getOverscanIndices(this.columnCount, overscanColumnCount, this._renderedColumnStartIndex, this._renderedColumnStopIndex); |
||||
|
||||
var overscanRowIndices = this._getOverscanIndices(this.rowCount, overscanRowCount, this._renderedRowStartIndex, this._renderedRowStopIndex); |
||||
|
||||
var columnStartIndex = overscanColumnIndices.overscanStartIndex; |
||||
var columnStopIndex = overscanColumnIndices.overscanStopIndex; |
||||
var rowStartIndex = overscanRowIndices.overscanStartIndex; |
||||
var rowStopIndex = overscanRowIndices.overscanStopIndex; |
||||
|
||||
// 算区间size
|
||||
var minRowDatum = this._rowSizeAndPositionManager.getSizeAndPositionOfCell(rowStartIndex); |
||||
var minColumnDatum = this._columnSizeAndPositionManager.getSizeAndPositionOfCell(columnStartIndex); |
||||
var maxRowDatum = this._rowSizeAndPositionManager.getSizeAndPositionOfCell(rowStopIndex); |
||||
var maxColumnDatum = this._columnSizeAndPositionManager.getSizeAndPositionOfCell(columnStopIndex); |
||||
var top = minRowDatum.offset + verticalOffsetAdjustment; |
||||
var left = minColumnDatum.offset + horizontalOffsetAdjustment; |
||||
var bottom = maxRowDatum.offset + verticalOffsetAdjustment + maxRowDatum.size; |
||||
var right = maxColumnDatum.offset + horizontalOffsetAdjustment + maxColumnDatum.size; |
||||
// 如果滚动的区间并没有超出渲染的范围
|
||||
if (top >= this.renderRange.minY && bottom <= this.renderRange.maxY && left >= this.renderRange.minX && right <= this.renderRange.maxX) { |
||||
return; |
||||
} |
||||
|
||||
var renderedCells = [], renderedKeys = {}, renderedWidgets = {}; |
||||
var minX = this._getMaxScrollLeft(), minY = this._getMaxScrollTop(), maxX = 0, maxY = 0; |
||||
var count = 0; |
||||
for (var rowIndex = rowStartIndex; rowIndex <= rowStopIndex; rowIndex++) { |
||||
var rowDatum = this._rowSizeAndPositionManager.getSizeAndPositionOfCell(rowIndex); |
||||
|
||||
for (var columnIndex = columnStartIndex; columnIndex <= columnStopIndex; columnIndex++) { |
||||
var key = rowIndex + "-" + columnIndex; |
||||
var columnDatum = this._columnSizeAndPositionManager.getSizeAndPositionOfCell(columnIndex); |
||||
|
||||
var index = this.renderedKeys[key] && this.renderedKeys[key][2]; |
||||
var child; |
||||
if (index >= 0) { |
||||
// if (columnDatum.size !== this.renderedCells[index]._width) {
|
||||
// this.renderedCells[index]._width = columnDatum.size;
|
||||
this.renderedCells[index].el.setWidth(columnDatum.size); |
||||
// }
|
||||
// if (rowDatum.size !== this.renderedCells[index]._height) {
|
||||
// this.renderedCells[index]._height = rowDatum.size;
|
||||
this.renderedCells[index].el.setHeight(rowDatum.size); |
||||
// }
|
||||
// if (this.renderedCells[index]._left !== columnDatum.offset + horizontalOffsetAdjustment) {
|
||||
this.renderedCells[index].el.element.css("left", (columnDatum.offset + horizontalOffsetAdjustment) / BI.pixRatio + BI.pixUnit); |
||||
// }
|
||||
// if (this.renderedCells[index]._top !== rowDatum.offset + verticalOffsetAdjustment) {
|
||||
this.renderedCells[index].el.element.css("top", (rowDatum.offset + verticalOffsetAdjustment) / BI.pixRatio + BI.pixUnit); |
||||
// }
|
||||
child = this.renderedCells[index].el; |
||||
renderedCells.push(this.renderedCells[index]); |
||||
} else { |
||||
child = BI._lazyCreateWidget(BI.extend({ |
||||
type: "bi.label", |
||||
width: columnDatum.size, |
||||
height: rowDatum.size |
||||
}, o.items[rowIndex][columnIndex], { |
||||
cls: (o.items[rowIndex][columnIndex].cls || "") + " grid-cell" + (rowIndex === 0 ? " first-row" : "") + (columnIndex === 0 ? " first-col" : ""), |
||||
_rowIndex: rowIndex, |
||||
_columnIndex: columnIndex, |
||||
_left: columnDatum.offset + horizontalOffsetAdjustment, |
||||
_top: rowDatum.offset + verticalOffsetAdjustment |
||||
}), this); |
||||
renderedCells.push({ |
||||
el: child, |
||||
left: columnDatum.offset + horizontalOffsetAdjustment, |
||||
top: rowDatum.offset + verticalOffsetAdjustment, |
||||
_left: columnDatum.offset + horizontalOffsetAdjustment, |
||||
_top: rowDatum.offset + verticalOffsetAdjustment |
||||
// _width: columnDatum.size,
|
||||
// _height: rowDatum.size
|
||||
}); |
||||
} |
||||
minX = Math.min(minX, columnDatum.offset + horizontalOffsetAdjustment); |
||||
maxX = Math.max(maxX, columnDatum.offset + horizontalOffsetAdjustment + columnDatum.size); |
||||
minY = Math.min(minY, rowDatum.offset + verticalOffsetAdjustment); |
||||
maxY = Math.max(maxY, rowDatum.offset + verticalOffsetAdjustment + rowDatum.size); |
||||
renderedKeys[key] = [rowIndex, columnIndex, count]; |
||||
renderedWidgets[count] = child; |
||||
count++; |
||||
} |
||||
} |
||||
// 已存在的, 需要添加的和需要删除的
|
||||
var existSet = {}, addSet = {}, deleteArray = []; |
||||
BI.each(renderedKeys, function (i, key) { |
||||
if (self.renderedKeys[i]) { |
||||
existSet[i] = key; |
||||
} else { |
||||
addSet[i] = key; |
||||
} |
||||
}); |
||||
BI.each(this.renderedKeys, function (i, key) { |
||||
if (existSet[i]) { |
||||
return; |
||||
} |
||||
if (addSet[i]) { |
||||
return; |
||||
} |
||||
deleteArray.push(key[2]); |
||||
}); |
||||
BI.each(deleteArray, function (i, index) { |
||||
// 性能优化,不调用destroy方法防止触发destroy事件
|
||||
self.renderedCells[index].el._destroy(); |
||||
}); |
||||
var addedItems = []; |
||||
BI.each(addSet, function (index, key) { |
||||
addedItems.push(renderedCells[key[2]]); |
||||
}); |
||||
// 与listview一样, 给上下文
|
||||
this.container.addItems(addedItems, this); |
||||
// 拦截父子级关系
|
||||
this.container._children = renderedWidgets; |
||||
this.container.attr("items", renderedCells); |
||||
this.renderedCells = renderedCells; |
||||
this.renderedKeys = renderedKeys; |
||||
this.renderRange = {minX: minX, minY: minY, maxX: maxX, maxY: maxY}; |
||||
} |
||||
}, |
||||
|
||||
_getMaxScrollLeft: function () { |
||||
return Math.max(0, this._getContainerWidth() - this.options.width + (this.options.overflowX ? BI.DOM.getScrollWidth() : 0)); |
||||
}, |
||||
|
||||
_getMaxScrollTop: function () { |
||||
return Math.max(0, this._getContainerHeight() - this.options.height + (this.options.overflowY ? BI.DOM.getScrollWidth() : 0)); |
||||
}, |
||||
|
||||
_getContainerWidth: function () { |
||||
return this.columnCount * this.options.estimatedColumnSize; |
||||
}, |
||||
|
||||
_getContainerHeight: function () { |
||||
return this.rowCount * this.options.estimatedRowSize; |
||||
}, |
||||
|
||||
_populate: function (items) { |
||||
var self = this, o = this.options; |
||||
this._reRange(); |
||||
if (items && items !== this.options.items) { |
||||
this.options.items = items; |
||||
this._calculateSizeAndPositionData(); |
||||
} |
||||
this.container.setWidth(this._getContainerWidth()); |
||||
this.container.setHeight(this._getContainerHeight()); |
||||
|
||||
// 元素未挂载时不能设置scrollTop
|
||||
this._debounceRelease(); |
||||
try { |
||||
this.element.scrollTop(o.scrollTop); |
||||
this.element.scrollLeft(o.scrollLeft); |
||||
} catch (e) { |
||||
} |
||||
this._calculateChildrenToRender(); |
||||
}, |
||||
|
||||
setScrollLeft: function (scrollLeft) { |
||||
if (this.options.scrollLeft === scrollLeft) { |
||||
return; |
||||
} |
||||
this._scrollLock = true; |
||||
this.options.scrollLeft = BI.clamp(scrollLeft || 0, 0, this._getMaxScrollLeft()); |
||||
this._debounceRelease(); |
||||
this.element.scrollLeft(this.options.scrollLeft); |
||||
this._calculateChildrenToRender(); |
||||
}, |
||||
|
||||
setScrollTop: function (scrollTop) { |
||||
if (this.options.scrollTop === scrollTop) { |
||||
return; |
||||
} |
||||
this._scrollLock = true; |
||||
this.options.scrollTop = BI.clamp(scrollTop || 0, 0, this._getMaxScrollTop()); |
||||
this._debounceRelease(); |
||||
this.element.scrollTop(this.options.scrollTop); |
||||
this._calculateChildrenToRender(); |
||||
}, |
||||
|
||||
setColumnCount: function (columnCount) { |
||||
this.options.columnCount = columnCount; |
||||
}, |
||||
|
||||
setRowCount: function (rowCount) { |
||||
this.options.rowCount = rowCount; |
||||
}, |
||||
|
||||
setOverflowX: function (b) { |
||||
var self = this; |
||||
if (this.options.overflowX !== !!b) { |
||||
this.options.overflowX = !!b; |
||||
BI.nextTick(function () { |
||||
self.element.css({overflowX: b ? "auto" : "hidden"}); |
||||
}); |
||||
} |
||||
}, |
||||
|
||||
setOverflowY: function (b) { |
||||
var self = this; |
||||
if (this.options.overflowY !== !!b) { |
||||
this.options.overflowY = !!b; |
||||
BI.nextTick(function () { |
||||
self.element.css({overflowY: b ? "auto" : "hidden"}); |
||||
}); |
||||
} |
||||
}, |
||||
|
||||
getScrollLeft: function () { |
||||
return this.options.scrollLeft; |
||||
}, |
||||
|
||||
getScrollTop: function () { |
||||
return this.options.scrollTop; |
||||
}, |
||||
|
||||
getMaxScrollLeft: function () { |
||||
return this._getMaxScrollLeft(); |
||||
}, |
||||
|
||||
getMaxScrollTop: function () { |
||||
return this._getMaxScrollTop(); |
||||
}, |
||||
|
||||
setEstimatedColumnSize: function (width) { |
||||
this.options.estimatedColumnSize = width; |
||||
}, |
||||
|
||||
setEstimatedRowSize: function (height) { |
||||
this.options.estimatedRowSize = height; |
||||
}, |
||||
|
||||
// 重新计算children
|
||||
_reRange: function () { |
||||
this.renderRange = {}; |
||||
}, |
||||
|
||||
_clearChildren: function () { |
||||
this.container._children = {}; |
||||
this.container.attr("items", []); |
||||
}, |
||||
|
||||
restore: function () { |
||||
BI.each(this.renderedCells, function (i, cell) { |
||||
cell.el._destroy(); |
||||
}); |
||||
this._clearChildren(); |
||||
this.renderedCells = []; |
||||
this.renderedKeys = []; |
||||
this.renderRange = {}; |
||||
this._scrollLock = false; |
||||
}, |
||||
|
||||
populate: function (items) { |
||||
if (items && items !== this.options.items) { |
||||
this.restore(); |
||||
} |
||||
this._populate(items); |
||||
} |
||||
}); |
||||
BI.GridView.EVENT_SCROLL = "EVENT_SCROLL"; |
||||
BI.shortcut("bi.grid_view", BI.GridView); |
@ -0,0 +1,33 @@
|
||||
/** |
||||
* @author windy |
||||
* @version 2.0 |
||||
* Created by windy on 2020/3/17 |
||||
*/ |
||||
|
||||
describe("PopoverTest", function () { |
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("BarPopover", function (done) { |
||||
var id = BI.UUID(); |
||||
BI.Popovers.remove(id); |
||||
BI.Popovers.create(id, { |
||||
type: "bi.bar_popover", |
||||
size: "normal", |
||||
header: { |
||||
type: "bi.label", |
||||
text: "这个是header" |
||||
}, |
||||
body: { |
||||
type: "bi.label", |
||||
text: "这个是body" |
||||
} |
||||
}).open(id); |
||||
BI.delay(function () { |
||||
expect(BI.Widget._renderEngine.createElement("body").find(".bi-popup-view .bi-z-index-mask").length).to.equal(1); |
||||
BI.Popovers.remove(id); |
||||
done(); |
||||
}, 100); |
||||
}); |
||||
}); |
@ -0,0 +1,272 @@
|
||||
/** |
||||
* Popover弹出层, |
||||
* @class BI.Popover |
||||
* @extends BI.Widget |
||||
*/ |
||||
BI.Popover = BI.inherit(BI.Widget, { |
||||
_constant: { |
||||
SIZE: { |
||||
SMALL: "small", |
||||
NORMAL: "normal", |
||||
BIG: "big", |
||||
}, |
||||
MAX_HEIGHT: 600 |
||||
}, |
||||
|
||||
props: { |
||||
baseCls: "bi-popover bi-card bi-border-radius", |
||||
size: "normal", // small, normal, big
|
||||
logic: { |
||||
dynamic: false, |
||||
}, |
||||
header: null, |
||||
headerHeight: 40, |
||||
body: null, |
||||
footer: null, |
||||
footerHeight: 44, |
||||
closable: true, // BI-40839 是否显示右上角的关闭按钮
|
||||
bodyHgap: 20, |
||||
bodyTgap: 10 |
||||
}, |
||||
|
||||
render: function () { |
||||
var self = this; var o = this.options; |
||||
var c = this._constant; |
||||
this.startX = 0; |
||||
this.startY = 0; |
||||
var size = this._calculateSize(); |
||||
this.tracker = new BI.MouseMoveTracker(function (deltaX, deltaY) { |
||||
var W = BI.Widget._renderEngine.createElement("body").width(); |
||||
var H = BI.Widget._renderEngine.createElement("body").height(); |
||||
self.startX += deltaX; |
||||
self.startY += deltaY; |
||||
self.element.css({ |
||||
left: BI.clamp(self.startX, 0, W - self.element.width()) + "px", |
||||
top: BI.clamp(self.startY, 0, H - self.element.height()) + "px", |
||||
}); |
||||
// BI-12134 没有什么特别好的方法
|
||||
BI.Resizers._resize({ |
||||
target: self.element[0], |
||||
}); |
||||
}, function () { |
||||
self.tracker.releaseMouseMoves(); |
||||
}, _global); |
||||
var items = [{ |
||||
el: { |
||||
type: "bi.htape", |
||||
cls: "bi-message-title bi-header-background", |
||||
ref: function (_ref) { |
||||
self.dragger = _ref; |
||||
}, |
||||
items: [{ |
||||
type: "bi.absolute", |
||||
items: [{ |
||||
el: BI.isPlainObject(o.header) ? BI.extend({}, o.header, { |
||||
extraCls: "bi-font-bold", |
||||
}) : { |
||||
type: "bi.label", |
||||
cls: "bi-font-bold", |
||||
height: o.headerHeight, |
||||
text: o.header, |
||||
title: o.header, |
||||
textAlign: "left", |
||||
}, |
||||
left: 20, |
||||
top: 0, |
||||
right: 0, |
||||
bottom: 0, |
||||
}], |
||||
}, { |
||||
el: o.closable ? { |
||||
type: "bi.icon_button", |
||||
cls: "bi-message-close close-font", |
||||
height: o.headerHeight, |
||||
handler: function () { |
||||
self.close(); |
||||
}, |
||||
} : { |
||||
type: "bi.layout", |
||||
}, |
||||
width: 56, |
||||
}], |
||||
height: o.headerHeight, |
||||
}, |
||||
height: o.headerHeight, |
||||
}, o.logic.dynamic ? { |
||||
el: { |
||||
type: "bi.vertical", |
||||
scrolly: true, |
||||
cls: "popover-body", |
||||
ref: function () { |
||||
self.body = this; |
||||
}, |
||||
css: { |
||||
"max-height": this._getSuitableBodyHeight(c.MAX_HEIGHT - o.headerHeight - (o.footer ? o.footerHeight : 0) - o.bodyTgap), |
||||
"min-height": this._getSuitableBodyHeight(size.height - o.headerHeight - (o.footer ? o.footerHeight : 0) - o.bodyTgap), |
||||
}, |
||||
items: [{ |
||||
el: o.body, |
||||
}], |
||||
}, |
||||
hgap: o.bodyHgap, |
||||
tgap: o.bodyTgap, |
||||
} : { |
||||
el: { |
||||
type: "bi.absolute", |
||||
items: [{ |
||||
el: o.body, |
||||
left: o.bodyHgap, |
||||
top: o.bodyTgap, |
||||
right: o.bodyHgap, |
||||
bottom: 0, |
||||
}], |
||||
}, |
||||
}]; |
||||
if (o.footer) { |
||||
items.push({ |
||||
el: { |
||||
type: "bi.absolute", |
||||
items: [{ |
||||
el: o.footer, |
||||
left: 20, |
||||
top: 0, |
||||
right: 20, |
||||
bottom: 0, |
||||
}], |
||||
height: o.footerHeight, |
||||
}, |
||||
height: o.footerHeight, |
||||
}); |
||||
} |
||||
|
||||
return BI.extend({ |
||||
type: o.logic.dynamic ? "bi.vertical" : "bi.vtape", |
||||
items: items, |
||||
width: this._getSuitableWidth(size.width), |
||||
}, o.logic.dynamic ? { |
||||
type: "bi.vertical", |
||||
scrolly: false, |
||||
} : { |
||||
type: "bi.vtape", |
||||
height: this._getSuitableHeight(size.height), |
||||
}); |
||||
}, |
||||
|
||||
// mounted之后绑定事件
|
||||
mounted: function () { |
||||
var self = this; var o = this.options; |
||||
this.dragger.element.mousedown(function (e) { |
||||
var pos = self.element.offset(); |
||||
self.startX = pos.left; |
||||
self.startY = pos.top; |
||||
self.tracker.captureMouseMoves(e); |
||||
}); |
||||
}, |
||||
|
||||
_getSuitableBodyHeight: function (height) { |
||||
var o = this.options; |
||||
var c = this._constant; |
||||
return BI.clamp(height, 0, BI.Widget._renderEngine.createElement("body")[0].clientHeight - o.headerHeight - (o.footer ? o.footerHeight : 0) - o.bodyTgap); |
||||
}, |
||||
|
||||
_getSuitableHeight: function (height) { |
||||
return BI.clamp(height, 0, BI.Widget._renderEngine.createElement("body")[0].clientHeight); |
||||
}, |
||||
|
||||
_getSuitableWidth: function (width) { |
||||
return BI.clamp(width, 0, BI.Widget._renderEngine.createElement("body").width()); |
||||
}, |
||||
|
||||
_calculateSize: function () { |
||||
var o = this.options; |
||||
var size = {}; |
||||
if (BI.isNotNull(o.size)) { |
||||
switch (o.size) { |
||||
case this._constant.SIZE.SMALL: |
||||
size.width = 450; |
||||
size.height = 200; |
||||
size.type = "small"; |
||||
break; |
||||
case this._constant.SIZE.BIG: |
||||
size.width = 900; |
||||
size.height = 500; |
||||
size.type = "big"; |
||||
break; |
||||
default: |
||||
size.width = 550; |
||||
size.height = 500; |
||||
size.type = "default"; |
||||
} |
||||
} |
||||
|
||||
return { |
||||
width: o.width || size.width, |
||||
height: o.height || size.height, |
||||
type: size.type || "default", |
||||
}; |
||||
}, |
||||
|
||||
hide: function () { |
||||
|
||||
}, |
||||
|
||||
open: function () { |
||||
this.show(); |
||||
this.fireEvent(BI.Popover.EVENT_OPEN, arguments); |
||||
}, |
||||
|
||||
close: function () { |
||||
this.hide(); |
||||
this.fireEvent(BI.Popover.EVENT_CLOSE, arguments); |
||||
}, |
||||
|
||||
setZindex: function (zindex) { |
||||
this.element.css({ "z-index": zindex }); |
||||
}, |
||||
|
||||
destroyed: function () {}, |
||||
}); |
||||
|
||||
BI.shortcut("bi.popover", BI.Popover); |
||||
|
||||
BI.BarPopover = BI.inherit(BI.Popover, { |
||||
_defaultConfig: function () { |
||||
return BI.extend(BI.BarPopover.superclass._defaultConfig.apply(this, arguments), { |
||||
btns: [BI.i18nText("BI-Basic_Sure"), BI.i18nText("BI-Basic_Cancel")], |
||||
}); |
||||
}, |
||||
|
||||
beforeCreate: function () { |
||||
var self = this; var o = this.options; |
||||
o.footer || (o.footer = { |
||||
type: "bi.right_vertical_adapt", |
||||
lgap: 10, |
||||
items: [{ |
||||
type: "bi.button", |
||||
text: this.options.btns[1], |
||||
value: 1, |
||||
level: "ignore", |
||||
handler: function (v) { |
||||
self.fireEvent(BI.Popover.EVENT_CANCEL, v); |
||||
self.close(v); |
||||
}, |
||||
}, { |
||||
type: "bi.button", |
||||
text: this.options.btns[0], |
||||
warningTitle: o.warningTitle, |
||||
value: 0, |
||||
handler: function (v) { |
||||
self.fireEvent(BI.Popover.EVENT_CONFIRM, v); |
||||
self.close(v); |
||||
}, |
||||
}], |
||||
}); |
||||
}, |
||||
}); |
||||
|
||||
BI.shortcut("bi.bar_popover", BI.BarPopover); |
||||
|
||||
BI.Popover.EVENT_CLOSE = "EVENT_CLOSE"; |
||||
BI.Popover.EVENT_OPEN = "EVENT_OPEN"; |
||||
BI.Popover.EVENT_CANCEL = "EVENT_CANCEL"; |
||||
BI.Popover.EVENT_CONFIRM = "EVENT_CONFIRM"; |
@ -0,0 +1,180 @@
|
||||
/** |
||||
* 下拉框弹出层, zIndex在1000w |
||||
* @class BI.PopupView |
||||
* @extends BI.Widget |
||||
*/ |
||||
BI.PopupView = BI.inherit(BI.Widget, { |
||||
_defaultConfig: function () { |
||||
return BI.extend(BI.PopupView.superclass._defaultConfig.apply(this, arguments), { |
||||
_baseCls: "bi-popup-view", |
||||
maxWidth: "auto", |
||||
minWidth: 100, |
||||
// maxHeight: 200,
|
||||
minHeight: 24, |
||||
lgap: 0, |
||||
rgap: 0, |
||||
tgap: 0, |
||||
bgap: 0, |
||||
vgap: 0, |
||||
hgap: 0, |
||||
innerVGap: 0, |
||||
innerHGap: 0, |
||||
direction: BI.Direction.Top, // 工具栏的方向
|
||||
stopEvent: false, // 是否停止mousedown、mouseup事件
|
||||
stopPropagation: false, // 是否停止mousedown、mouseup向上冒泡
|
||||
logic: { |
||||
dynamic: true |
||||
}, |
||||
|
||||
tool: false, // 自定义工具栏
|
||||
tabs: [], // 导航栏
|
||||
buttons: [], // toolbar栏
|
||||
|
||||
el: { |
||||
type: "bi.button_group", |
||||
items: [], |
||||
chooseType: 0, |
||||
behaviors: {}, |
||||
layouts: [{ |
||||
type: "bi.vertical" |
||||
}] |
||||
} |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var self = this, o = this.options; |
||||
var fn = function (e) { |
||||
e.stopPropagation(); |
||||
}, stop = function (e) { |
||||
e.stopEvent(); |
||||
return false; |
||||
}; |
||||
this.element.css({ |
||||
"z-index": BI.zIndex_popup, |
||||
"min-width": BI.isNumeric(o.minWidth) ? (o.minWidth / BI.pixRatio + BI.pixUnit) : o.minWidth, |
||||
"max-width": BI.isNumeric(o.maxWidth) ? (o.maxWidth / BI.pixRatio + BI.pixUnit) : o.maxWidth |
||||
}).bind({ click: fn }); |
||||
|
||||
this.element.bind("mousewheel", fn); |
||||
|
||||
o.stopPropagation && this.element.bind({ mousedown: fn, mouseup: fn, mouseover: fn }); |
||||
o.stopEvent && this.element.bind({ mousedown: stop, mouseup: stop, mouseover: stop }); |
||||
this.tool = this._createTool(); |
||||
this.tab = this._createTab(); |
||||
this.view = this._createView(); |
||||
this.toolbar = this._createToolBar(); |
||||
|
||||
this.view.on(BI.Controller.EVENT_CHANGE, function (type) { |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); |
||||
if (type === BI.Events.CLICK) { |
||||
self.fireEvent(BI.PopupView.EVENT_CHANGE); |
||||
} |
||||
}); |
||||
|
||||
BI.createWidget(BI.extend({ |
||||
element: this |
||||
}, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(o.direction), BI.extend({}, o.logic, { |
||||
scrolly: false, |
||||
lgap: o.lgap, |
||||
rgap: o.rgap, |
||||
tgap: o.tgap, |
||||
bgap: o.bgap, |
||||
vgap: o.vgap, |
||||
hgap: o.hgap, |
||||
items: BI.LogicFactory.createLogicItemsByDirection(o.direction, |
||||
BI.extend({ |
||||
cls: "list-view-outer bi-card list-view-shadow" |
||||
}, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(o.direction), BI.extend({}, o.logic, { |
||||
items: BI.LogicFactory.createLogicItemsByDirection(o.direction, this.tool, this.tab, this.view, this.toolbar) |
||||
}))) |
||||
) |
||||
})))); |
||||
}, |
||||
|
||||
_createView: function () { |
||||
var o = this.options; |
||||
this.button_group = BI.createWidget(o.el, { type: "bi.button_group", value: o.value }); |
||||
this.button_group.element.css({ |
||||
"min-height": BI.isNumeric(o.minHeight) ? (o.minHeight / BI.pixRatio + BI.pixUnit) : o.minHeight, |
||||
"padding-top": o.innerVGap / BI.pixRatio + BI.pixUnit, |
||||
"padding-bottom": o.innerVGap / BI.pixRatio + BI.pixUnit, |
||||
"padding-left": o.innerHGap / BI.pixRatio + BI.pixUnit, |
||||
"padding-right": o.innerHGap / BI.pixRatio + BI.pixUnit, |
||||
}); |
||||
return this.button_group; |
||||
}, |
||||
|
||||
_createTool: function () { |
||||
var o = this.options; |
||||
if (false === o.tool) { |
||||
return; |
||||
} |
||||
return BI.createWidget(o.tool); |
||||
}, |
||||
|
||||
_createTab: function () { |
||||
var o = this.options; |
||||
if (o.tabs.length === 0) { |
||||
return; |
||||
} |
||||
return BI.createWidget({ |
||||
type: "bi.center", |
||||
cls: "list-view-tab", |
||||
height: 25, |
||||
items: o.tabs, |
||||
value: o.value |
||||
}); |
||||
}, |
||||
|
||||
_createToolBar: function () { |
||||
var o = this.options; |
||||
if (o.buttons.length === 0) { |
||||
return; |
||||
} |
||||
|
||||
return BI.createWidget({ |
||||
type: "bi.center", |
||||
cls: "list-view-toolbar bi-high-light bi-split-top", |
||||
height: 24, |
||||
items: BI.createItems(o.buttons, { |
||||
once: false, |
||||
shadow: true, |
||||
isShadowShowingOnSelected: true |
||||
}) |
||||
}); |
||||
}, |
||||
|
||||
getView: function () { |
||||
return this.view; |
||||
}, |
||||
|
||||
populate: function (items) { |
||||
this.view.populate.apply(this.view, arguments); |
||||
}, |
||||
|
||||
resetWidth: function (w) { |
||||
this.options.width = w; |
||||
this.element.width(w); |
||||
}, |
||||
|
||||
resetHeight: function (h) { |
||||
var tbHeight = this.toolbar ? (this.toolbar.attr("height") || 24) : 0, |
||||
tabHeight = this.tab ? (this.tab.attr("height") || 24) : 0, |
||||
toolHeight = ((this.tool && this.tool.attr("height")) || 24) * ((this.tool && this.tool.isVisible()) ? 1 : 0); |
||||
var resetHeight = h - tbHeight - tabHeight - toolHeight - 2 * this.options.innerVGap; |
||||
this.view.resetHeight ? this.view.resetHeight(resetHeight) : |
||||
this.view.element.css({ "max-height": resetHeight / BI.pixRatio + BI.pixUnit }); |
||||
}, |
||||
|
||||
setValue: function (selectedValues) { |
||||
this.tab && this.tab.setValue(selectedValues); |
||||
this.view.setValue(selectedValues); |
||||
}, |
||||
|
||||
getValue: function () { |
||||
return this.view.getValue(); |
||||
} |
||||
}); |
||||
BI.PopupView.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
BI.shortcut("bi.popup_view", BI.PopupView); |
@ -0,0 +1,140 @@
|
||||
/** |
||||
* 搜索面板 |
||||
* |
||||
* Created by GUY on 2015/9/28. |
||||
* @class BI.SearcherView |
||||
* @extends BI.Pane |
||||
*/ |
||||
|
||||
BI.SearcherView = BI.inherit(BI.Pane, { |
||||
_defaultConfig: function () { |
||||
var conf = BI.SearcherView.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend(conf, { |
||||
baseCls: (conf.baseCls || "") + " bi-searcher-view bi-card", |
||||
tipText: BI.i18nText("BI-No_Select"), |
||||
chooseType: BI.Selection.Single, |
||||
|
||||
matcher: {// 完全匹配的构造器
|
||||
type: "bi.button_group", |
||||
behaviors: { |
||||
redmark: function () { |
||||
return true; |
||||
} |
||||
}, |
||||
items: [], |
||||
layouts: [{ |
||||
type: "bi.vertical" |
||||
}] |
||||
}, |
||||
searcher: { |
||||
type: "bi.button_group", |
||||
behaviors: { |
||||
redmark: function () { |
||||
return true; |
||||
} |
||||
}, |
||||
items: [], |
||||
layouts: [{ |
||||
type: "bi.vertical" |
||||
}] |
||||
} |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var self = this, o = this.options; |
||||
|
||||
this.matcher = BI.createWidget(o.matcher, { |
||||
type: "bi.button_group", |
||||
chooseType: o.chooseType, |
||||
behaviors: { |
||||
redmark: function () { |
||||
return true; |
||||
} |
||||
}, |
||||
layouts: [{ |
||||
type: "bi.vertical" |
||||
}], |
||||
value: o.value |
||||
}); |
||||
this.matcher.on(BI.Controller.EVENT_CHANGE, function (type, val, ob) { |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); |
||||
if (type === BI.Events.CLICK) { |
||||
self.fireEvent(BI.SearcherView.EVENT_CHANGE, val, ob); |
||||
} |
||||
}); |
||||
this.spliter = BI.createWidget({ |
||||
type: "bi.vertical", |
||||
height: 1, |
||||
hgap: 10, |
||||
items: [{ |
||||
type: "bi.layout", |
||||
height: 1, |
||||
cls: "searcher-view-spliter bi-background" |
||||
}] |
||||
}); |
||||
this.searcher = BI.createWidget(o.searcher, { |
||||
type: "bi.button_group", |
||||
chooseType: o.chooseType, |
||||
behaviors: { |
||||
redmark: function () { |
||||
return true; |
||||
} |
||||
}, |
||||
layouts: [{ |
||||
type: "bi.vertical" |
||||
}], |
||||
value: o.value |
||||
}); |
||||
this.searcher.on(BI.Controller.EVENT_CHANGE, function (type, val, ob) { |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); |
||||
if (type === BI.Events.CLICK) { |
||||
self.fireEvent(BI.SearcherView.EVENT_CHANGE, val, ob); |
||||
} |
||||
}); |
||||
|
||||
BI.createWidget({ |
||||
type: "bi.vertical", |
||||
element: this, |
||||
items: [this.matcher, this.spliter, this.searcher] |
||||
}); |
||||
}, |
||||
|
||||
startSearch: function () { |
||||
|
||||
}, |
||||
|
||||
stopSearch: function () { |
||||
|
||||
}, |
||||
|
||||
setValue: function (v) { |
||||
this.matcher.setValue(v); |
||||
this.searcher.setValue(v); |
||||
}, |
||||
|
||||
getValue: function () { |
||||
return this.matcher.getValue().concat(this.searcher.getValue()); |
||||
}, |
||||
|
||||
populate: function (searchResult, matchResult, keyword) { |
||||
searchResult || (searchResult = []); |
||||
matchResult || (matchResult = []); |
||||
this.setTipVisible(searchResult.length + matchResult.length === 0); |
||||
this.spliter.setVisible(BI.isNotEmptyArray(matchResult) && BI.isNotEmptyArray(searchResult)); |
||||
this.matcher.populate(matchResult, keyword); |
||||
this.searcher.populate(searchResult, keyword); |
||||
}, |
||||
|
||||
empty: function () { |
||||
this.searcher.empty(); |
||||
this.matcher.empty(); |
||||
}, |
||||
|
||||
hasMatched: function () { |
||||
return this.matcher.getAllButtons().length > 0; |
||||
} |
||||
}); |
||||
BI.SearcherView.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
|
||||
BI.shortcut("bi.searcher_view", BI.SearcherView); |
@ -0,0 +1,48 @@
|
||||
/** |
||||
* @author windy |
||||
* @version 2.0 |
||||
* Created by windy on 2020/3/24 |
||||
*/ |
||||
|
||||
// TODO 展示类控件测什么没想好标记一下
|
||||
describe("ListView && VirtualList", function () { |
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("ListView初始化测试", function () { |
||||
var a = BI.Test.createWidget({ |
||||
type: "bi.list_view", |
||||
el: { |
||||
type: "bi.left" |
||||
}, |
||||
items: BI.map(BI.range(0, 100), function (i, item) { |
||||
return BI.extend({}, item, { |
||||
type: "bi.label", |
||||
width: 200, |
||||
height: 200, |
||||
text: (i + 1) |
||||
}); |
||||
}) |
||||
}); |
||||
a.destroy(); |
||||
}); |
||||
|
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("VirtualList初始化测试", function () { |
||||
var a = BI.Test.createWidget({ |
||||
type: "bi.virtual_list", |
||||
items: BI.map(BI.range(0, 100), function (i, item) { |
||||
return BI.extend({}, item, { |
||||
type: "bi.label", |
||||
height: 30, |
||||
text: (i + 1) + "." + item.text |
||||
}); |
||||
}) |
||||
}); |
||||
a.destroy(); |
||||
}); |
||||
}); |
@ -0,0 +1,119 @@
|
||||
/** |
||||
* 表示当前对象 |
||||
* |
||||
* Created by GUY on 2017/5/23. |
||||
* @class BI.ListView |
||||
* @extends BI.Widget |
||||
*/ |
||||
BI.ListView = BI.inherit(BI.Widget, { |
||||
props: function () { |
||||
return { |
||||
baseCls: "bi-list-view", |
||||
overscanHeight: 100, |
||||
blockSize: 10, |
||||
scrollTop: 0, |
||||
el: {}, |
||||
items: [] |
||||
}; |
||||
}, |
||||
|
||||
init: function () { |
||||
var self = this; |
||||
this.renderedIndex = -1; |
||||
this.cache = {}; |
||||
}, |
||||
|
||||
render: function () { |
||||
var self = this, o = this.options; |
||||
return { |
||||
type: "bi.vertical", |
||||
items: [BI.extend({ |
||||
type: "bi.vertical", |
||||
scrolly: false, |
||||
ref: function () { |
||||
self.container = this; |
||||
} |
||||
}, o.el)], |
||||
element: this |
||||
}; |
||||
}, |
||||
|
||||
// mounted之后绑定事件
|
||||
mounted: function () { |
||||
var self = this, o = this.options; |
||||
this._populate(); |
||||
this.element.scroll(function (e) { |
||||
o.scrollTop = self.element.scrollTop(); |
||||
self._calculateBlocksToRender(); |
||||
}); |
||||
var lastWidth = this.element.width(), |
||||
lastHeight = this.element.height(); |
||||
BI.ResizeDetector.addResizeListener(this, function () { |
||||
var width = self.element.width(), |
||||
height = self.element.height(); |
||||
if (width !== lastWidth || height !== lastHeight) { |
||||
lastWidth = width; |
||||
lastHeight = height; |
||||
self._calculateBlocksToRender(); |
||||
} |
||||
}); |
||||
}, |
||||
|
||||
_renderMoreIf: function () { |
||||
var self = this, o = this.options; |
||||
var height = this.element.height(); |
||||
var minContentHeight = o.scrollTop + height + o.overscanHeight; |
||||
var index = (this.cache[this.renderedIndex] && (this.cache[this.renderedIndex].index + o.blockSize)) || 0, |
||||
cnt = this.renderedIndex + 1; |
||||
var lastHeight; |
||||
var getElementHeight = function () { |
||||
return self.container.element.height(); |
||||
}; |
||||
while ((lastHeight = getElementHeight()) < minContentHeight && index < o.items.length) { |
||||
var items = o.items.slice(index, index + o.blockSize); |
||||
this.container.addItems(items, this); |
||||
var addedHeight = getElementHeight() - lastHeight; |
||||
this.cache[cnt] = { |
||||
index: index, |
||||
scrollTop: lastHeight, |
||||
height: addedHeight |
||||
}; |
||||
this.renderedIndex = cnt; |
||||
cnt++; |
||||
index += o.blockSize; |
||||
} |
||||
}, |
||||
|
||||
_calculateBlocksToRender: function () { |
||||
var o = this.options; |
||||
this._renderMoreIf(); |
||||
}, |
||||
|
||||
_populate: function (items) { |
||||
var o = this.options; |
||||
if (items && this.options.items !== items) { |
||||
this.options.items = items; |
||||
} |
||||
this._calculateBlocksToRender(); |
||||
this.element.scrollTop(o.scrollTop); |
||||
}, |
||||
|
||||
restore: function () { |
||||
this.renderedIndex = -1; |
||||
this.container.empty(); |
||||
this.cache = {}; |
||||
}, |
||||
|
||||
populate: function (items) { |
||||
if (items && this.options.items !== items) { |
||||
this.restore(); |
||||
} |
||||
this._populate(items); |
||||
}, |
||||
|
||||
destroyed: function () { |
||||
this.restore(); |
||||
} |
||||
}); |
||||
BI.shortcut("bi.list_view", BI.ListView); |
||||
|
@ -0,0 +1,158 @@
|
||||
/** |
||||
* 同时用于virtualGroup和virtualList特性的虚拟列表 |
||||
* |
||||
* Created by GUY on 2017/5/22. |
||||
* @class BI.VirtualList |
||||
* @extends BI.Widget |
||||
*/ |
||||
BI.VirtualGroupList = BI.inherit(BI.Widget, { |
||||
props: function () { |
||||
return { |
||||
baseCls: "bi-virtual-group-list", |
||||
overscanHeight: 100, |
||||
blockSize: 10, |
||||
scrollTop: 0, |
||||
rowHeight: "auto", |
||||
items: [] |
||||
}; |
||||
}, |
||||
|
||||
init: function () { |
||||
var self = this; |
||||
this.renderedIndex = -1; |
||||
}, |
||||
|
||||
render: function () { |
||||
var self = this, o = this.options; |
||||
return { |
||||
type: "bi.vertical", |
||||
items: [{ |
||||
type: "bi.layout", |
||||
ref: function () { |
||||
self.topBlank = this; |
||||
} |
||||
}, { |
||||
type: "bi.virtual_group", |
||||
height: o.rowHeight * o.items.length, |
||||
ref: function () { |
||||
self.container = this; |
||||
}, |
||||
layouts: [{ |
||||
type: "bi.vertical", |
||||
scrolly: false |
||||
}] |
||||
}, { |
||||
type: "bi.layout", |
||||
ref: function () { |
||||
self.bottomBlank = this; |
||||
} |
||||
}], |
||||
element: this |
||||
}; |
||||
}, |
||||
|
||||
// mounted之后绑定事件
|
||||
mounted: function () { |
||||
var self = this, o = this.options; |
||||
this._populate(); |
||||
this._debounceRelease = BI.debounce(function () { |
||||
self._scrollLock = false; |
||||
}, 30); |
||||
this.element.scroll(function (e) { |
||||
if (self._scrollLock === true) { |
||||
return; |
||||
} |
||||
self._scrollLock = true; |
||||
o.scrollTop = self.element.scrollTop(); |
||||
self._debounceRelease(); |
||||
self._calculateBlocksToRender(); |
||||
}); |
||||
BI.ResizeDetector.addResizeListener(this, function () { |
||||
self._calculateBlocksToRender(); |
||||
}); |
||||
}, |
||||
|
||||
_isAutoHeight: function () { |
||||
return this.options.rowHeight === "auto"; |
||||
}, |
||||
|
||||
_renderMoreIf: function () { |
||||
var self = this, o = this.options; |
||||
var height = this.element.height(); |
||||
var minContentHeight = o.scrollTop + height + o.overscanHeight; |
||||
var index = (this.renderedIndex + 1) * o.blockSize, cnt = this.renderedIndex + 1; |
||||
var lastHeight; |
||||
var getElementHeight = function () { |
||||
return self.container.element.height() + self.topBlank.element.height() + self.bottomBlank.element.height(); |
||||
}; |
||||
while ((lastHeight = getElementHeight()) < minContentHeight && index < o.items.length) { |
||||
var items = o.items.slice(index, index + o.blockSize); |
||||
this.container.addItems(items, this); |
||||
var addedHeight = getElementHeight() - lastHeight; |
||||
this.tree.set(cnt, addedHeight); |
||||
this.renderedIndex = cnt; |
||||
cnt++; |
||||
index += o.blockSize; |
||||
} |
||||
}, |
||||
|
||||
_calculateBlocksToRender: function () { |
||||
var o = this.options; |
||||
this._isAutoHeight() && this._renderMoreIf(); |
||||
var height = this.element.height(); |
||||
var minContentHeightFrom = o.scrollTop - o.overscanHeight; |
||||
var minContentHeightTo = o.scrollTop + height + o.overscanHeight; |
||||
var start = this.tree.greatestLowerBound(minContentHeightFrom); |
||||
var end = this.tree.leastUpperBound(minContentHeightTo); |
||||
var items = []; |
||||
var topHeight = this.tree.sumTo(Math.max(-1, start - 1)); |
||||
this.topBlank.setHeight(topHeight); |
||||
if (this._isAutoHeight()) { |
||||
for (var i = (start < 0 ? 0 : start); i <= end && i <= this.renderedIndex; i++) { |
||||
var index = i * o.blockSize; |
||||
for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { |
||||
items.push(o.items[j]); |
||||
} |
||||
} |
||||
this.bottomBlank.setHeight(this.tree.sumTo(this.renderedIndex) - this.tree.sumTo(Math.min(end, this.renderedIndex))); |
||||
this.container.populate(items); |
||||
} else { |
||||
for (var i = (start < 0 ? 0 : start); i <= end; i++) { |
||||
var index = i * o.blockSize; |
||||
for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { |
||||
items.push(o.items[j]); |
||||
} |
||||
} |
||||
this.container.element.height(o.rowHeight * o.items.length - topHeight); |
||||
this.container.populate(items); |
||||
} |
||||
}, |
||||
|
||||
_populate: function (items) { |
||||
var o = this.options; |
||||
if (items && this.options.items !== items) { |
||||
this.options.items = items; |
||||
} |
||||
this.tree = BI.PrefixIntervalTree.uniform(Math.ceil(o.items.length / o.blockSize), this._isAutoHeight() ? 0 : o.rowHeight * o.blockSize); |
||||
|
||||
this._calculateBlocksToRender(); |
||||
try { |
||||
this.element.scrollTop(o.scrollTop); |
||||
} catch (e) { |
||||
} |
||||
}, |
||||
|
||||
restore: function () { |
||||
this.renderedIndex = -1; |
||||
this.options.scrollTop = 0; |
||||
// 依赖于cache的占位元素也要初始化
|
||||
this.topBlank.setHeight(0); |
||||
this.bottomBlank.setHeight(0); |
||||
}, |
||||
|
||||
populate: function (items) { |
||||
this._populate(items); |
||||
} |
||||
}); |
||||
BI.shortcut("bi.virtual_group_list", BI.VirtualGroupList); |
||||
|
@ -0,0 +1,195 @@
|
||||
/** |
||||
* 虚拟列表 |
||||
* |
||||
* Created by GUY on 2017/5/22. |
||||
* @class BI.VirtualList |
||||
* @extends BI.Widget |
||||
*/ |
||||
BI.VirtualList = BI.inherit(BI.Widget, { |
||||
props: function () { |
||||
return { |
||||
baseCls: "bi-virtual-list", |
||||
overscanHeight: 100, |
||||
blockSize: 10, |
||||
scrollTop: 0, |
||||
items: [] |
||||
}; |
||||
}, |
||||
|
||||
init: function () { |
||||
var self = this; |
||||
this.renderedIndex = -1; |
||||
this.cache = {}; |
||||
}, |
||||
|
||||
render: function () { |
||||
var self = this, o = this.options; |
||||
return { |
||||
type: "bi.vertical", |
||||
items: [{ |
||||
type: "bi.layout", |
||||
ref: function () { |
||||
self.topBlank = this; |
||||
} |
||||
}, { |
||||
type: "bi.vertical", |
||||
scrolly: false, |
||||
ref: function () { |
||||
self.container = this; |
||||
} |
||||
}, { |
||||
type: "bi.layout", |
||||
ref: function () { |
||||
self.bottomBlank = this; |
||||
} |
||||
}], |
||||
element: this |
||||
}; |
||||
}, |
||||
|
||||
// mounted之后绑定事件
|
||||
mounted: function () { |
||||
var self = this, o = this.options; |
||||
this._populate(); |
||||
this.element.scroll(function (e) { |
||||
o.scrollTop = self.element.scrollTop(); |
||||
self._calculateBlocksToRender(); |
||||
}); |
||||
BI.ResizeDetector.addResizeListener(this, function () { |
||||
self._calculateBlocksToRender(); |
||||
}); |
||||
}, |
||||
|
||||
_renderMoreIf: function () { |
||||
var self = this, o = this.options; |
||||
var height = this.element.height(); |
||||
var minContentHeight = o.scrollTop + height + o.overscanHeight; |
||||
var index = (this.renderedIndex + 1) * o.blockSize, cnt = this.renderedIndex + 1; |
||||
var lastHeight; |
||||
var getElementHeight = function () { |
||||
return self.container.element.height() + self.topBlank.element.height() + self.bottomBlank.element.height(); |
||||
}; |
||||
while ((lastHeight = getElementHeight()) < minContentHeight && index < o.items.length) { |
||||
var items = o.items.slice(index, index + o.blockSize); |
||||
this.container.addItems(items, this); |
||||
var addedHeight = getElementHeight() - lastHeight; |
||||
this.tree.set(cnt, addedHeight); |
||||
this.renderedIndex = cnt; |
||||
cnt++; |
||||
index += o.blockSize; |
||||
} |
||||
}, |
||||
|
||||
_calculateBlocksToRender: function () { |
||||
var o = this.options; |
||||
this._renderMoreIf(); |
||||
var height = this.element.height(); |
||||
var minContentHeightFrom = o.scrollTop - o.overscanHeight; |
||||
var minContentHeightTo = o.scrollTop + height + o.overscanHeight; |
||||
var start = this.tree.greatestLowerBound(minContentHeightFrom); |
||||
var end = this.tree.leastUpperBound(minContentHeightTo); |
||||
var needDestroyed = [], needMount = []; |
||||
for (var i = 0; i < start; i++) { |
||||
var index = i * o.blockSize; |
||||
if (!this.cache[i]) { |
||||
this.cache[i] = {}; |
||||
} |
||||
if (!this.cache[i].destroyed) { |
||||
for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { |
||||
needDestroyed.push(this.container._children[j]); |
||||
this.container._children[j] = null; |
||||
} |
||||
this.cache[i].destroyed = true; |
||||
} |
||||
} |
||||
for (var i = end + 1; i <= this.renderedIndex; i++) { |
||||
var index = i * o.blockSize; |
||||
if (!this.cache[i]) { |
||||
this.cache[i] = {}; |
||||
} |
||||
if (!this.cache[i].destroyed) { |
||||
for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { |
||||
needDestroyed.push(this.container._children[j]); |
||||
this.container._children[j] = null; |
||||
} |
||||
this.cache[i].destroyed = true; |
||||
} |
||||
} |
||||
var firstFragment = BI.Widget._renderEngine.createFragment(), |
||||
lastFragment = BI.Widget._renderEngine.createFragment(); |
||||
var currentFragment = firstFragment; |
||||
for (var i = (start < 0 ? 0 : start); i <= end && i <= this.renderedIndex; i++) { |
||||
var index = i * o.blockSize; |
||||
if (!this.cache[i]) { |
||||
this.cache[i] = {}; |
||||
} |
||||
if (!this.cache[i].destroyed) { |
||||
currentFragment = lastFragment; |
||||
} |
||||
if (this.cache[i].destroyed === true) { |
||||
for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { |
||||
var w = this.container._addElement(j, o.items[j], this); |
||||
needMount.push(w); |
||||
currentFragment.appendChild(w.element[0]); |
||||
} |
||||
this.cache[i].destroyed = false; |
||||
} |
||||
} |
||||
this.container.element.prepend(firstFragment); |
||||
this.container.element.append(lastFragment); |
||||
this.topBlank.setHeight(this.tree.sumTo(Math.max(-1, start - 1))); |
||||
this.bottomBlank.setHeight(this.tree.sumTo(this.renderedIndex) - this.tree.sumTo(Math.min(end, this.renderedIndex))); |
||||
BI.each(needMount, function (i, child) { |
||||
child && child._mount(); |
||||
}); |
||||
BI.each(needDestroyed, function (i, child) { |
||||
child && child._destroy(); |
||||
}); |
||||
}, |
||||
|
||||
_populate: function (items) { |
||||
var o = this.options; |
||||
if (items && this.options.items !== items) { |
||||
this.options.items = items; |
||||
} |
||||
this.tree = BI.PrefixIntervalTree.empty(Math.ceil(o.items.length / o.blockSize)); |
||||
|
||||
this._calculateBlocksToRender(); |
||||
try { |
||||
this.element.scrollTop(o.scrollTop); |
||||
} catch (e) { |
||||
} |
||||
}, |
||||
|
||||
_clearChildren: function () { |
||||
BI.each(this.container._children, function (i, cell) { |
||||
cell && cell._destroy(); |
||||
}); |
||||
this.container._children = {}; |
||||
this.container.attr("items", []); |
||||
}, |
||||
|
||||
restore: function () { |
||||
this.renderedIndex = -1; |
||||
this._clearChildren(); |
||||
this.cache = {}; |
||||
this.options.scrollTop = 0; |
||||
// 依赖于cache的占位元素也要初始化
|
||||
this.topBlank.setHeight(0); |
||||
this.bottomBlank.setHeight(0); |
||||
}, |
||||
|
||||
populate: function (items) { |
||||
if (items && this.options.items !== items) { |
||||
this.restore(); |
||||
} |
||||
this._populate(items); |
||||
}, |
||||
|
||||
destroyed: function () { |
||||
this.cache = {}; |
||||
this.renderedIndex = -1; |
||||
} |
||||
}); |
||||
BI.shortcut("bi.virtual_list", BI.VirtualList); |
||||
|
@ -0,0 +1,289 @@
|
||||
/** |
||||
* 分页控件 |
||||
* |
||||
* Created by GUY on 2015/8/31. |
||||
* @class BI.Pager |
||||
* @extends BI.Widget |
||||
*/ |
||||
BI.Pager = BI.inherit(BI.Widget, { |
||||
_defaultConfig: function () { |
||||
return BI.extend(BI.Pager.superclass._defaultConfig.apply(this, arguments), { |
||||
baseCls: "bi-pager", |
||||
behaviors: {}, |
||||
layouts: [{ |
||||
type: "bi.horizontal", |
||||
hgap: 10, |
||||
vgap: 0 |
||||
}], |
||||
|
||||
dynamicShow: true, // 是否动态显示上一页、下一页、首页、尾页, 若为false,则指对其设置使能状态
|
||||
// dynamicShow为false时以下两个有用
|
||||
dynamicShowFirstLast: false, // 是否动态显示首页、尾页
|
||||
dynamicShowPrevNext: false, // 是否动态显示上一页、下一页
|
||||
pages: false, // 总页数
|
||||
curr: function () { |
||||
return 1; |
||||
}, // 初始化当前页
|
||||
groups: 0, // 连续显示分页数
|
||||
jump: BI.emptyFn, // 分页的回调函数
|
||||
|
||||
first: false, // 是否显示首页
|
||||
last: false, // 是否显示尾页
|
||||
prev: "上一页", |
||||
next: "下一页", |
||||
|
||||
firstPage: 1, |
||||
lastPage: function () { // 在万不得已时才会调用这个函数获取最后一页的页码, 主要作用于setValue方法
|
||||
return 1; |
||||
}, |
||||
hasPrev: BI.emptyFn, // pages不可用时有效
|
||||
hasNext: BI.emptyFn // pages不可用时有效
|
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var self = this; |
||||
this.currPage = BI.result(this.options, "curr"); |
||||
// 翻页太灵敏
|
||||
// this._lock = false;
|
||||
// this._debouce = BI.debounce(function () {
|
||||
// self._lock = false;
|
||||
// }, 300);
|
||||
this._populate(); |
||||
}, |
||||
|
||||
_populate: function () { |
||||
var self = this, o = this.options, view = [], dict = {}; |
||||
this.empty(); |
||||
var pages = BI.result(o, "pages"); |
||||
var curr = BI.result(this, "currPage"); |
||||
var groups = BI.result(o, "groups"); |
||||
var first = BI.result(o, "first"); |
||||
var last = BI.result(o, "last"); |
||||
var prev = BI.result(o, "prev"); |
||||
var next = BI.result(o, "next"); |
||||
|
||||
if (pages === false) { |
||||
groups = 0; |
||||
first = false; |
||||
last = false; |
||||
} else { |
||||
groups > pages && (groups = pages); |
||||
} |
||||
|
||||
// 计算当前组
|
||||
dict.index = Math.ceil((curr + ((groups > 1 && groups !== pages) ? 1 : 0)) / (groups === 0 ? 1 : groups)); |
||||
|
||||
// 当前页非首页,则输出上一页
|
||||
if (((!o.dynamicShow && !o.dynamicShowPrevNext) || curr > 1) && prev !== false) { |
||||
if (BI.isKey(prev)) { |
||||
view.push({ |
||||
text: prev, |
||||
value: "prev", |
||||
disabled: pages === false ? o.hasPrev(curr) === false : !(curr > 1 && prev !== false) |
||||
}); |
||||
} else { |
||||
view.push(BI.extend({ |
||||
disabled: pages === false ? o.hasPrev(curr) === false : !(curr > 1 && prev !== false) |
||||
}, prev)); |
||||
} |
||||
} |
||||
|
||||
// 当前组非首组,则输出首页
|
||||
if (((!o.dynamicShow && !o.dynamicShowFirstLast) || (dict.index > 1 && groups !== 0)) && first) { |
||||
view.push({ |
||||
text: first, |
||||
value: "first", |
||||
disabled: !(dict.index > 1 && groups !== 0) |
||||
}); |
||||
if (dict.index > 1 && groups !== 0) { |
||||
view.push({ |
||||
type: "bi.label", |
||||
cls: "page-ellipsis", |
||||
text: "\u2026" |
||||
}); |
||||
} |
||||
} |
||||
|
||||
// 输出当前页组
|
||||
dict.poor = Math.floor((groups - 1) / 2); |
||||
dict.start = dict.index > 1 ? curr - dict.poor : 1; |
||||
dict.end = dict.index > 1 ? (function () { |
||||
var max = curr + (groups - dict.poor - 1); |
||||
return max > pages ? pages : max; |
||||
}()) : groups; |
||||
if (dict.end - dict.start < groups - 1) { // 最后一组状态
|
||||
dict.start = dict.end - groups + 1; |
||||
} |
||||
var s = dict.start, e = dict.end; |
||||
if (first && last && (dict.index > 1 && groups !== 0) && (pages > groups && dict.end < pages && groups !== 0)) { |
||||
s++; |
||||
e--; |
||||
} |
||||
for (; s <= e; s++) { |
||||
if (s === curr) { |
||||
view.push({ |
||||
text: s, |
||||
value: s, |
||||
selected: true |
||||
}); |
||||
} else { |
||||
view.push({ |
||||
text: s, |
||||
value: s |
||||
}); |
||||
} |
||||
} |
||||
|
||||
// 总页数大于连续分页数,且当前组最大页小于总页,输出尾页
|
||||
if (((!o.dynamicShow && !o.dynamicShowFirstLast) || (pages > groups && dict.end < pages && groups !== 0)) && last) { |
||||
if (pages > groups && dict.end < pages && groups !== 0) { |
||||
view.push({ |
||||
type: "bi.label", |
||||
cls: "page-ellipsis", |
||||
text: "\u2026" |
||||
}); |
||||
} |
||||
view.push({ |
||||
text: last, |
||||
value: "last", |
||||
disabled: !(pages > groups && dict.end < pages && groups !== 0) |
||||
}); |
||||
} |
||||
|
||||
// 当前页不为尾页时,输出下一页
|
||||
dict.flow = !prev && groups === 0; |
||||
if (((!o.dynamicShow && !o.dynamicShowPrevNext) && next) || (curr !== pages && next || dict.flow)) { |
||||
view.push((function () { |
||||
if (BI.isKey(next)) { |
||||
if (pages === false) { |
||||
return {text: next, value: "next", disabled: o.hasNext(curr) === false}; |
||||
} |
||||
return (dict.flow && curr === pages) |
||||
? |
||||
{text: next, value: "next", disabled: true} |
||||
: |
||||
{text: next, value: "next", disabled: !(curr !== pages && next || dict.flow)}; |
||||
} |
||||
return BI.extend({ |
||||
disabled: pages === false ? o.hasNext(curr) === false : !(curr !== pages && next || dict.flow) |
||||
}, next); |
||||
|
||||
}())); |
||||
} |
||||
|
||||
this.button_group = BI.createWidget({ |
||||
type: "bi.button_group", |
||||
element: this, |
||||
items: BI.createItems(view, { |
||||
cls: "bi-list-item-select bi-border-radius", |
||||
height: 23, |
||||
hgap: 10, |
||||
stopPropagation: true |
||||
}), |
||||
behaviors: o.behaviors, |
||||
layouts: o.layouts |
||||
}); |
||||
this.button_group.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { |
||||
// if (self._lock === true) {
|
||||
// return;
|
||||
// }
|
||||
// self._lock = true;
|
||||
// self._debouce();
|
||||
if (type === BI.Events.CLICK) { |
||||
var v = self.button_group.getValue()[0]; |
||||
switch (v) { |
||||
case "first": |
||||
self.currPage = 1; |
||||
break; |
||||
case "last": |
||||
self.currPage = pages; |
||||
break; |
||||
case "prev": |
||||
self.currPage--; |
||||
break; |
||||
case "next": |
||||
self.currPage++; |
||||
break; |
||||
default: |
||||
self.currPage = v; |
||||
break; |
||||
} |
||||
o.jump.apply(self, [{ |
||||
pages: pages, |
||||
curr: self.currPage |
||||
}]); |
||||
self._populate(); |
||||
self.fireEvent(BI.Pager.EVENT_CHANGE, obj); |
||||
} |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); |
||||
}); |
||||
this.fireEvent(BI.Pager.EVENT_AFTER_POPULATE); |
||||
}, |
||||
|
||||
getCurrentPage: function () { |
||||
return this.currPage; |
||||
}, |
||||
|
||||
setAllPages: function (pages) { |
||||
this.options.pages = pages; |
||||
}, |
||||
|
||||
hasPrev: function (v) { |
||||
v || (v = 1); |
||||
var o = this.options; |
||||
var pages = this.options.pages; |
||||
return pages === false ? o.hasPrev(v) : v > 1; |
||||
}, |
||||
|
||||
hasNext: function (v) { |
||||
v || (v = 1); |
||||
var o = this.options; |
||||
var pages = this.options.pages; |
||||
return pages === false ? o.hasNext(v) : v < pages; |
||||
}, |
||||
|
||||
setValue: function (v) { |
||||
var o = this.options; |
||||
v = v || 0; |
||||
v = v < 1 ? 1 : v; |
||||
if (o.pages === false) { |
||||
var lastPage = BI.result(o, "lastPage"), firstPage = 1; |
||||
this.currPage = v > lastPage ? lastPage : ((firstPage = BI.result(o, "firstPage")), (v < firstPage ? firstPage : v)); |
||||
} else { |
||||
v = v > o.pages ? o.pages : v; |
||||
this.currPage = v; |
||||
} |
||||
this._populate(); |
||||
}, |
||||
|
||||
getValue: function () { |
||||
var val = this.button_group.getValue()[0]; |
||||
switch (val) { |
||||
case "prev": |
||||
return -1; |
||||
case "next": |
||||
return 1; |
||||
case "first": |
||||
return BI.MIN; |
||||
case "last": |
||||
return BI.MAX; |
||||
default : |
||||
return val; |
||||
} |
||||
}, |
||||
|
||||
attr: function (key, value) { |
||||
BI.Pager.superclass.attr.apply(this, arguments); |
||||
if (key === "curr") { |
||||
this.currPage = BI.result(this.options, "curr"); |
||||
} |
||||
}, |
||||
|
||||
populate: function () { |
||||
this._populate(); |
||||
} |
||||
}); |
||||
BI.Pager.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
BI.Pager.EVENT_AFTER_POPULATE = "EVENT_AFTER_POPULATE"; |
||||
BI.shortcut("bi.pager", BI.Pager); |
@ -0,0 +1,207 @@
|
||||
/** |
||||
* guy |
||||
* 这仅仅只是一个超类, 所有简单控件的基类 |
||||
* 1、类的控制, |
||||
* 2、title的控制 |
||||
* 3、文字超过边界显示3个点 |
||||
* 4、cursor默认pointor |
||||
* @class BI.Single |
||||
* @extends BI.Widget |
||||
* @abstract |
||||
*/ |
||||
BI.Single = BI.inherit(BI.Widget, { |
||||
_defaultConfig: function () { |
||||
var conf = BI.Single.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend(conf, { |
||||
readonly: false, |
||||
title: null, |
||||
warningTitle: null, |
||||
tipType: null, // success或warning
|
||||
belowMouse: false // title是否跟随鼠标
|
||||
}); |
||||
}, |
||||
|
||||
_showToolTip: function (e, opt) { |
||||
opt || (opt = {}); |
||||
var self = this, o = this.options; |
||||
var type = this.getTipType() || (this.isEnabled() ? "success" : "warning"); |
||||
var title = type === "success" ? this.getTitle() : (this.getWarningTitle() || this.getTitle()); |
||||
if (BI.isKey(title)) { |
||||
BI.Tooltips.show(e, this.getName(), title, type, this, opt); |
||||
if (o.action) { |
||||
BI.Actions.runAction(o.action, "hover", o, this); |
||||
} |
||||
BI.Actions.runGlobalAction("hover", o, this); |
||||
} |
||||
}, |
||||
|
||||
_hideTooltip: function () { |
||||
var self = this; |
||||
var tooltip = BI.Tooltips.get(this.getName()); |
||||
if (BI.isNotNull(tooltip)) { |
||||
tooltip.element.fadeOut(200, function () { |
||||
BI.Tooltips.remove(self.getName()); |
||||
}); |
||||
} |
||||
}, |
||||
|
||||
_init: function () { |
||||
BI.Single.superclass._init.apply(this, arguments); |
||||
var self = this, o = this.options; |
||||
if (BI.isKey(o.title) || BI.isKey(o.warningTitle) |
||||
|| BI.isFunction(o.title) || BI.isFunction(o.warningTitle)) { |
||||
this.enableHover({ |
||||
belowMouse: o.belowMouse, |
||||
container: o.container |
||||
}); |
||||
} |
||||
}, |
||||
|
||||
_clearTimeOut: function () { |
||||
if (BI.isNotNull(this.showTimeout)) { |
||||
clearTimeout(this.showTimeout); |
||||
this.showTimeout = null; |
||||
} |
||||
if (BI.isNotNull(this.hideTimeout)) { |
||||
clearTimeout(this.hideTimeout); |
||||
this.hideTimeout = null; |
||||
} |
||||
}, |
||||
|
||||
enableHover: function (opt) { |
||||
opt || (opt = {}); |
||||
var self = this; |
||||
if (!this._hoverBinded) { |
||||
this.element.on("mouseenter.title" + this.getName(), function (e) { |
||||
self._e = e; |
||||
if (self.getTipType() === "warning" || (BI.isKey(self.getWarningTitle()) && !self.isEnabled())) { |
||||
self.showTimeout = BI.delay(function () { |
||||
if (BI.isNotNull(self.showTimeout)) { |
||||
self._showToolTip(self._e || e, opt); |
||||
} |
||||
}, 200); |
||||
} else if (self.getTipType() === "success" || self.isEnabled()) { |
||||
self.showTimeout = BI.delay(function () { |
||||
if (BI.isNotNull(self.showTimeout)) { |
||||
self._showToolTip(self._e || e, opt); |
||||
} |
||||
}, 500); |
||||
} |
||||
}); |
||||
this.element.on("mousemove.title" + this.getName(), function (e) { |
||||
self._e = e; |
||||
if (BI.isNotNull(self.showTimeout)) { |
||||
clearTimeout(self.showTimeout); |
||||
self.showTimeout = null; |
||||
} |
||||
if (BI.isNull(self.hideTimeout)) { |
||||
self.hideTimeout = BI.delay(function () { |
||||
if (BI.isNotNull(self.hideTimeout)) { |
||||
self._hideTooltip(); |
||||
} |
||||
}, 500); |
||||
} |
||||
|
||||
self.showTimeout = BI.delay(function () { |
||||
// DEC-5321 IE下如果回调已经进入事件队列,clearTimeout将不会起作用
|
||||
if (BI.isNotNull(self.showTimeout)) { |
||||
if (BI.isNotNull(self.hideTimeout)) { |
||||
clearTimeout(self.hideTimeout); |
||||
self.hideTimeout = null; |
||||
} |
||||
// CHART-10611 在拖拽的情况下, 鼠标拖拽着元素离开了拖拽元素的容器,但是子元素在dom结构上仍然属于容器
|
||||
// 这样会认为鼠标仍然在容器中, 500ms内放开的话,会在容器之外显示鼠标停留处显示容器的title
|
||||
if (self.element.__isMouseInBounds__(self._e || e)) { |
||||
self._showToolTip(self._e || e, opt); |
||||
} |
||||
} |
||||
}, 500); |
||||
|
||||
}); |
||||
this.element.on("mouseleave.title" + this.getName(), function (e) { |
||||
self._e = null; |
||||
self._clearTimeOut(); |
||||
self._hideTooltip(); |
||||
}); |
||||
this._hoverBinded = true; |
||||
} |
||||
}, |
||||
|
||||
disabledHover: function () { |
||||
// 取消hover事件
|
||||
this._clearTimeOut(); |
||||
this._hideTooltip(); |
||||
this.element.unbind("mouseenter.title" + this.getName()) |
||||
.unbind("mousemove.title" + this.getName()) |
||||
.unbind("mouseleave.title" + this.getName()); |
||||
this._hoverBinded = false; |
||||
}, |
||||
|
||||
// opt: {container: '', belowMouse: false}
|
||||
setTitle: function (title, opt) { |
||||
this.options.title = title; |
||||
if (BI.isKey(title) || BI.isFunction(title)) { |
||||
this.enableHover(opt); |
||||
} else { |
||||
this.disabledHover(); |
||||
} |
||||
}, |
||||
|
||||
setWarningTitle: function (title, opt) { |
||||
this.options.warningTitle = title; |
||||
if (BI.isKey(title) || BI.isFunction(title)) { |
||||
this.enableHover(opt); |
||||
} else { |
||||
this.disabledHover(); |
||||
} |
||||
}, |
||||
|
||||
setTipType: function (type) { |
||||
this.options.tipType = type; |
||||
}, |
||||
|
||||
getTipType: function () { |
||||
return this.options.tipType; |
||||
}, |
||||
|
||||
isReadOnly: function () { |
||||
return !!this.options.readonly; |
||||
}, |
||||
|
||||
getTitle: function () { |
||||
var title = this.options.title; |
||||
if (BI.isFunction(title)) { |
||||
return title(); |
||||
} |
||||
return title; |
||||
}, |
||||
|
||||
getWarningTitle: function () { |
||||
var title = this.options.warningTitle; |
||||
if (BI.isFunction(title)) { |
||||
return title(); |
||||
} |
||||
return title; |
||||
}, |
||||
|
||||
setValue: function (val) { |
||||
if (!this.options.readonly) { |
||||
this.options.value = val; |
||||
this.options.setValue && this.options.setValue(val); |
||||
} |
||||
}, |
||||
|
||||
getValue: function () { |
||||
return this.options.value; |
||||
}, |
||||
|
||||
__d: function () { |
||||
BI.Single.superclass.__d.call(this); |
||||
if (BI.isNotNull(this.showTimeout)) { |
||||
clearTimeout(this.showTimeout); |
||||
this.showTimeout = null; |
||||
} |
||||
BI.Tooltips.remove(this.getName()); |
||||
} |
||||
}); |
||||
BI.shortcut("bi.single", BI.Single); |
@ -0,0 +1,170 @@
|
||||
/** |
||||
* guy 表示一行数据,通过position来定位位置的数据 |
||||
* @class BI.Text |
||||
* @extends BI.Single |
||||
*/ |
||||
!(function () { |
||||
BI.Text = BI.inherit(BI.Single, { |
||||
|
||||
props: { |
||||
baseCls: "bi-text", |
||||
textAlign: "left", |
||||
whiteSpace: "normal", |
||||
lineHeight: null, |
||||
handler: null, // 如果传入handler,表示处理文字的点击事件,不是区域的
|
||||
hgap: 0, |
||||
vgap: 0, |
||||
lgap: 0, |
||||
rgap: 0, |
||||
tgap: 0, |
||||
bgap: 0, |
||||
py: "", |
||||
highLight: false |
||||
}, |
||||
|
||||
render: function () { |
||||
var self = this, o = this.options; |
||||
if (o.hgap + o.lgap > 0) { |
||||
this.element.css({ |
||||
"padding-left": (o.hgap + o.lgap) / BI.pixRatio + BI.pixUnit |
||||
}); |
||||
} |
||||
if (o.hgap + o.rgap > 0) { |
||||
this.element.css({ |
||||
"padding-right": (o.hgap + o.rgap) / BI.pixRatio + BI.pixUnit |
||||
}); |
||||
} |
||||
if (o.vgap + o.tgap > 0) { |
||||
this.element.css({ |
||||
"padding-top": (o.vgap + o.tgap) / BI.pixRatio + BI.pixUnit |
||||
}); |
||||
} |
||||
if (o.vgap + o.bgap > 0) { |
||||
this.element.css({ |
||||
"padding-bottom": (o.vgap + o.bgap) / BI.pixRatio + BI.pixUnit |
||||
}); |
||||
} |
||||
if (BI.isWidthOrHeight(o.height)) { |
||||
this.element.css({lineHeight: BI.isNumber(o.height) ? (o.height / BI.pixRatio + BI.pixUnit) : o.height}); |
||||
} |
||||
if (BI.isWidthOrHeight(o.lineHeight)) { |
||||
this.element.css({lineHeight: BI.isNumber(o.lineHeight) ? (o.lineHeight / BI.pixRatio + BI.pixUnit) : o.lineHeight}); |
||||
} |
||||
if (BI.isWidthOrHeight(o.maxWidth)) { |
||||
this.element.css({maxWidth: BI.isNumber(o.maxWidth) ? (o.maxWidth / BI.pixRatio + BI.pixUnit) : o.maxWidth}); |
||||
} |
||||
this.element.css({ |
||||
textAlign: o.textAlign, |
||||
whiteSpace: this._getTextWrap(), |
||||
textOverflow: o.whiteSpace === "nowrap" ? "ellipsis" : "", |
||||
overflow: o.whiteSpace === "nowrap" ? "" : (BI.isWidthOrHeight(o.height) ? "auto" : "") |
||||
}); |
||||
if (o.handler && o.handler !== BI.emptyFn) { |
||||
this.text = BI.createWidget({ |
||||
type: "bi.layout", |
||||
tagName: "span" |
||||
}); |
||||
this.text.element.click(function (e) { |
||||
o.handler.call(self, self.getValue(), self, e); |
||||
}); |
||||
BI.createWidget({ |
||||
type: "bi.default", |
||||
element: this, |
||||
items: [this.text] |
||||
}); |
||||
} else { |
||||
this.text = this; |
||||
} |
||||
|
||||
var text = this._getShowText(); |
||||
// 只要不是undefined就可以显示text值,否则显示value
|
||||
if (!BI.isUndefined(text)) { |
||||
this.setText(text); |
||||
} else if (BI.isKey(o.value)) { |
||||
this.setText(o.value); |
||||
} |
||||
if (BI.isKey(o.keyword)) { |
||||
this.doRedMark(o.keyword); |
||||
} |
||||
if (o.highLight) { |
||||
this.doHighLight(); |
||||
} |
||||
}, |
||||
|
||||
_getTextWrap: function () { |
||||
var o = this.options; |
||||
switch (o.whiteSpace) { |
||||
case "nowrap": |
||||
return "pre"; |
||||
case "normal": |
||||
return "pre-wrap"; |
||||
default: |
||||
return o.whiteSpace; |
||||
} |
||||
}, |
||||
|
||||
_getShowText: function () { |
||||
var o = this.options; |
||||
var text = BI.isFunction(o.text) ? o.text() : o.text; |
||||
return BI.isKey(text) ? BI.Text.formatText(text + "") : text; |
||||
}, |
||||
|
||||
_doRedMark: function (keyword) { |
||||
var o = this.options; |
||||
// render之后做的doRedMark,这个时候虽然标红了,但是之后text mounted执行的时候并没有keyword
|
||||
o.keyword = keyword; |
||||
this.text.element.__textKeywordMarked__(this._getShowText(), keyword, o.py); |
||||
}, |
||||
|
||||
doRedMark: function (keyword) { |
||||
if (BI.isKey(keyword)) { |
||||
this._doRedMark(keyword); |
||||
} |
||||
}, |
||||
|
||||
unRedMark: function () { |
||||
var o = this.options; |
||||
o.keyword = ""; |
||||
this.text.element.__textKeywordMarked__(this._getShowText(), "", o.py); |
||||
}, |
||||
|
||||
doHighLight: function () { |
||||
this.text.element.addClass("bi-high-light"); |
||||
}, |
||||
|
||||
unHighLight: function () { |
||||
this.text.element.removeClass("bi-high-light"); |
||||
}, |
||||
|
||||
setValue: function (text) { |
||||
BI.Text.superclass.setValue.apply(this, arguments); |
||||
if (!this.isReadOnly()) { |
||||
this.setText(text); |
||||
} |
||||
}, |
||||
|
||||
setStyle: function (css) { |
||||
this.text.element.css(css); |
||||
}, |
||||
|
||||
setText: function (text) { |
||||
BI.Text.superclass.setText.apply(this, arguments); |
||||
this.options.text = text; |
||||
this._doRedMark(this.options.keyword); |
||||
} |
||||
}); |
||||
var formatters = []; |
||||
BI.Text.addTextFormatter = function (formatter) { |
||||
formatters.push(formatter); |
||||
}; |
||||
BI.Text.formatText = function (text) { |
||||
if (formatters.length > 0) { |
||||
for (var i = 0, len = formatters.length; i < len; i++) { |
||||
text = formatters[i](text); |
||||
} |
||||
} |
||||
return text; |
||||
}; |
||||
BI.shortcut("bi.text", BI.Text); |
||||
}()); |
||||
|
@ -0,0 +1,195 @@
|
||||
/** |
||||
* Created by windy on 2018/01/23. |
||||
*/ |
||||
describe("TextTest", function () { |
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("setText", function () { |
||||
var text = BI.Test.createWidget({ |
||||
type: "bi.text" |
||||
}); |
||||
text.setText("AAA"); |
||||
expect(text.element.text()).to.equal("AAA"); |
||||
text.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("setStyle", function () { |
||||
var text = BI.Test.createWidget({ |
||||
type: "bi.text" |
||||
}); |
||||
text.setStyle({"color": "red"}); |
||||
expect(text.element.getStyle("color")).to.equal("rgb(255, 0, 0)"); |
||||
text.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("高亮doHighlight", function () { |
||||
var text = BI.Test.createWidget({ |
||||
type: "bi.text", |
||||
text: "AAA", |
||||
highLight: true |
||||
}); |
||||
expect(text.element.getStyle("color")).to.equal("rgb(54, 133, 242)"); |
||||
text.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("标红doRedMark", function () { |
||||
var text = BI.Test.createWidget({ |
||||
type: "bi.text", |
||||
text: "我是要标红的A", |
||||
keyword: "A" |
||||
}); |
||||
expect(text.element.children(".bi-keyword-red-mark").length).to.not.equal(0); |
||||
text.destroy(); |
||||
}); |
||||
|
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("取消高亮undoHighlight", function () { |
||||
var text = BI.Test.createWidget({ |
||||
type: "bi.text", |
||||
text: "AAA", |
||||
highLight: true |
||||
}); |
||||
text.unHighLight(); |
||||
expect(text.element.getStyle("color")).to.not.equal("rgb(54, 133, 242)"); |
||||
text.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("取消标红undoRedMark", function () { |
||||
var text = BI.Test.createWidget({ |
||||
type: "bi.text", |
||||
text: "我是要标红的A", |
||||
keyword: "A" |
||||
}); |
||||
text.unRedMark(); |
||||
expect(text.element.children(".bi-keyword-red-mark").length).to.equal(0); |
||||
text.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("setValue", function () { |
||||
var text = BI.Test.createWidget({ |
||||
type: "bi.text", |
||||
value: "AAA", |
||||
}); |
||||
text.setValue("value"); |
||||
expect(text.element.text()).to.equal("value"); |
||||
text.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("gap测试", function () { |
||||
var text = BI.Test.createWidget({ |
||||
type: "bi.text", |
||||
text: "我是要标红的A", |
||||
vgap: 10, |
||||
hgap: 10 |
||||
}); |
||||
expect(text.element.css("padding")).to.equal("10px"); |
||||
text.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("空格测试", function () { |
||||
var text = BI.Test.createWidget({ |
||||
type: "bi.text", |
||||
text: "我是要标红的 A", |
||||
}); |
||||
expect(text.element.text()).to.equal("我是要标红的 A"); |
||||
text.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("lineHeight和height", function () { |
||||
var text = BI.Test.createWidget({ |
||||
type: "bi.text", |
||||
text: "我是A", |
||||
lineHeight: 12, |
||||
height: 24 |
||||
}); |
||||
expect(text.element.css("height")).to.equal("24px"); |
||||
expect(text.element.css("line-height")).to.equal("12px"); |
||||
text.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("handler", function (done) { |
||||
var text = BI.Test.createWidget({ |
||||
type: "bi.text", |
||||
text: "我是A", |
||||
handler: function () { |
||||
text.setText("handler"); |
||||
} |
||||
}); |
||||
BI.nextTick(function () { |
||||
text.text.element.click(); |
||||
expect(text.text.element.text()).to.equal("handler"); |
||||
text.destroy(); |
||||
done(); |
||||
}); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("text的value属性", function () { |
||||
var text = BI.Test.createWidget({ |
||||
type: "bi.text", |
||||
text: "", |
||||
value: "aaaa" |
||||
}); |
||||
expect(text.element.text()).to.equal(""); |
||||
text.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("text的value属性1", function () { |
||||
var text = BI.Test.createWidget({ |
||||
type: "bi.text", |
||||
value: "aaaa" |
||||
}); |
||||
expect(text.element.text()).to.equal("aaaa"); |
||||
text.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("text的value属性2", function () { |
||||
var text = BI.Test.createWidget({ |
||||
type: "bi.text", |
||||
text: null, |
||||
value: "aaaa" |
||||
}); |
||||
expect(text.element.text()).to.equal(""); |
||||
text.destroy(); |
||||
}); |
||||
}); |
@ -0,0 +1,32 @@
|
||||
/** |
||||
* Created by windy on 2018/01/23. |
||||
*/ |
||||
describe("ALinkTest", function () { |
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("A初始化测试", function () { |
||||
var a = BI.Test.createWidget({ |
||||
type: "bi.a", |
||||
text: "CCC" |
||||
}); |
||||
expect(a.element.is('a')).to.equal(true); |
||||
a.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("A的el测试", function () { |
||||
var a = BI.Test.createWidget({ |
||||
type: "bi.a", |
||||
text: "DDD", |
||||
el: { |
||||
type: "bi.label" |
||||
} |
||||
}); |
||||
expect(a.element.is('a') && a.element.hasClass("bi-label")).to.equal(true); |
||||
a.destroy(); |
||||
}); |
||||
}); |
@ -0,0 +1,33 @@
|
||||
/** |
||||
* 超链接 |
||||
* |
||||
* Created by GUY on 2015/9/9. |
||||
* @class BI.A |
||||
* @extends BI.Text |
||||
* @abstract |
||||
*/ |
||||
BI.A = BI.inherit(BI.Text, { |
||||
_defaultConfig: function () { |
||||
var conf = BI.A.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend(conf, { |
||||
baseCls: (conf.baseCls || "") + " bi-a display-block", |
||||
href: "", |
||||
target: "_blank", |
||||
el: null, |
||||
tagName: "a" |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var o = this.options; |
||||
BI.A.superclass.render.apply(this, arguments); |
||||
this.element.attr({href: o.href, target: o.target}); |
||||
if (o.el) { |
||||
BI.createWidget(o.el, { |
||||
element: this |
||||
}); |
||||
} |
||||
} |
||||
}); |
||||
|
||||
BI.shortcut("bi.a", BI.A); |
@ -0,0 +1,80 @@
|
||||
/** |
||||
* guy |
||||
* 加载条 |
||||
* @type {*|void|Object} |
||||
*/ |
||||
BI.LoadingBar = BI.inherit(BI.Single, { |
||||
_defaultConfig: function () { |
||||
var conf = BI.LoadingBar.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend( conf, { |
||||
baseCls: (conf.baseCls || "") + " bi-loading-bar bi-tips", |
||||
height: 30, |
||||
handler: BI.emptyFn |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var self = this; |
||||
this.loaded = BI.createWidget({ |
||||
type: "bi.text_button", |
||||
cls: "loading-text bi-list-item-simple", |
||||
text: BI.i18nText("BI-Load_More"), |
||||
width: 120, |
||||
handler: this.options.handler |
||||
}); |
||||
this.loaded.on(BI.Controller.EVENT_CHANGE, function (type) { |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); |
||||
}); |
||||
|
||||
this.loading = BI.createWidget({ |
||||
type: "bi.layout", |
||||
width: this.options.height, |
||||
height: this.options.height, |
||||
cls: "loading-background cursor-default" |
||||
}); |
||||
var loaded = BI.createWidget({ |
||||
type: "bi.center_adapt", |
||||
items: [this.loaded] |
||||
}); |
||||
var loading = BI.createWidget({ |
||||
type: "bi.center_adapt", |
||||
items: [this.loading] |
||||
}); |
||||
this.cardLayout = BI.createWidget({ |
||||
type: "bi.card", |
||||
element: this, |
||||
items: [{ |
||||
el: loaded, |
||||
cardName: "loaded" |
||||
}, { |
||||
el: loading, |
||||
cardName: "loading" |
||||
}] |
||||
}); |
||||
this.invisible(); |
||||
}, |
||||
|
||||
_reset: function () { |
||||
this.visible(); |
||||
this.loaded.setText(BI.i18nText("BI-Load_More")); |
||||
this.loaded.enable(); |
||||
}, |
||||
|
||||
setLoaded: function () { |
||||
this._reset(); |
||||
this.cardLayout.showCardByName("loaded"); |
||||
}, |
||||
|
||||
setEnd: function () { |
||||
this.setLoaded(); |
||||
this.loaded.setText(BI.i18nText("BI-No_More_Data")); |
||||
this.loaded.disable(); |
||||
}, |
||||
|
||||
setLoading: function () { |
||||
this._reset(); |
||||
this.cardLayout.showCardByName("loading"); |
||||
} |
||||
}); |
||||
|
||||
BI.shortcut("bi.loading_bar", BI.LoadingBar); |
@ -0,0 +1,412 @@
|
||||
/** |
||||
* guy |
||||
* @class BI.BasicButton |
||||
* @extends BI.Single |
||||
* |
||||
* 一般的button父级 |
||||
*/ |
||||
BI.BasicButton = BI.inherit(BI.Single, { |
||||
_defaultConfig: function () { |
||||
var conf = BI.BasicButton.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend(conf, { |
||||
_baseCls: (conf._baseCls || "") + " bi-basic-button" + (conf.invalid ? "" : " cursor-pointer") + ((BI.isIE() && BI.getIEVersion() < 10) ? " hack" : ""), |
||||
value: "", |
||||
stopEvent: false, |
||||
stopPropagation: false, |
||||
selected: false, |
||||
once: false, // 点击一次选中有效,再点无效
|
||||
forceSelected: false, // 点击即选中, 选中了就不会被取消,与once的区别是forceSelected不影响事件的触发
|
||||
forceNotSelected: false, // 无论怎么点击都不会被选中
|
||||
disableSelected: false, // 使能选中
|
||||
|
||||
shadow: false, |
||||
isShadowShowingOnSelected: false, // 选中状态下是否显示阴影
|
||||
trigger: null, |
||||
handler: BI.emptyFn, |
||||
bubble: null |
||||
}); |
||||
}, |
||||
_init: function () { |
||||
BI.BasicButton.superclass._init.apply(this, arguments); |
||||
var opts = this.options; |
||||
if (opts.selected === true) { |
||||
BI.nextTick(BI.bind(function () { |
||||
this.setSelected(opts.selected); |
||||
}, this)); |
||||
} |
||||
BI.nextTick(BI.bind(this.bindEvent, this)); |
||||
|
||||
if (opts.shadow) { |
||||
this._createShadow(); |
||||
} |
||||
if (opts.level) { |
||||
this.element.addClass("button-" + opts.level); |
||||
} |
||||
}, |
||||
|
||||
_createShadow: function () { |
||||
var self = this, o = this.options; |
||||
|
||||
var assertMask = function () { |
||||
if (!self.$mask) { |
||||
self.$mask = BI.createWidget(BI.isObject(o.shadow) ? o.shadow : {}, { |
||||
type: "bi.layout", |
||||
cls: "bi-button-mask" |
||||
}); |
||||
self.$mask.invisible(); |
||||
BI.createWidget({ |
||||
type: "bi.absolute", |
||||
element: self, |
||||
items: [{ |
||||
el: self.$mask, |
||||
left: 0, |
||||
right: 0, |
||||
top: 0, |
||||
bottom: 0 |
||||
}] |
||||
}); |
||||
} |
||||
}; |
||||
|
||||
this.element.mouseup(function () { |
||||
if (!self._hover && !o.isShadowShowingOnSelected) { |
||||
assertMask(); |
||||
self.$mask.invisible(); |
||||
} |
||||
}); |
||||
this.element.on("mouseenter." + this.getName(), function (e) { |
||||
if (self.element.__isMouseInBounds__(e)) { |
||||
if (self.isEnabled() && !self._hover && (o.isShadowShowingOnSelected || !self.isSelected())) { |
||||
assertMask(); |
||||
self.$mask.visible(); |
||||
} |
||||
} |
||||
}); |
||||
this.element.on("mousemove." + this.getName(), function (e) { |
||||
if (!self.element.__isMouseInBounds__(e)) { |
||||
if (self.isEnabled() && !self._hover) { |
||||
assertMask(); |
||||
self.$mask.invisible(); |
||||
} |
||||
} |
||||
}); |
||||
this.element.on("mouseleave." + this.getName(), function () { |
||||
if (self.isEnabled() && !self._hover) { |
||||
assertMask(); |
||||
self.$mask.invisible(); |
||||
} |
||||
}); |
||||
}, |
||||
|
||||
bindEvent: function () { |
||||
var self = this; |
||||
var o = this.options, hand = this.handle(); |
||||
if (!hand) { |
||||
return; |
||||
} |
||||
hand = hand.element; |
||||
var triggerArr = (o.trigger || "").split(","); |
||||
BI.each(triggerArr, function (idx, trigger) { |
||||
switch (trigger) { |
||||
case "mouseup": |
||||
var mouseDown = false; |
||||
hand.mousedown(function () { |
||||
mouseDown = true; |
||||
}); |
||||
hand.mouseup(function (e) { |
||||
if (mouseDown === true) { |
||||
clk(e); |
||||
} |
||||
mouseDown = false; |
||||
ev(e); |
||||
}); |
||||
break; |
||||
case "mousedown": |
||||
var mouseDown = false; |
||||
var selected = false; |
||||
hand.mousedown(function (e) { |
||||
// if (e.button === 0) {
|
||||
BI.Widget._renderEngine.createElement(document).bind("mouseup." + self.getName(), function (e) { |
||||
// if (e.button === 0) {
|
||||
if (BI.DOM.isExist(self) && !hand.__isMouseInBounds__(e) && mouseDown === true && !selected) { |
||||
// self.setSelected(!self.isSelected());
|
||||
self._trigger(); |
||||
} |
||||
mouseDown = false; |
||||
BI.Widget._renderEngine.createElement(document).unbind("mouseup." + self.getName()); |
||||
// }
|
||||
}); |
||||
if (mouseDown === true) { |
||||
return; |
||||
} |
||||
if (self.isSelected()) { |
||||
selected = true; |
||||
} else { |
||||
clk(e); |
||||
} |
||||
mouseDown = true; |
||||
ev(e); |
||||
// }
|
||||
}); |
||||
hand.mouseup(function (e) { |
||||
// if (e.button === 0) {
|
||||
if (BI.DOM.isExist(self) && mouseDown === true && selected === true) { |
||||
clk(e); |
||||
} |
||||
mouseDown = false; |
||||
selected = false; |
||||
BI.Widget._renderEngine.createElement(document).unbind("mouseup." + self.getName()); |
||||
// }
|
||||
}); |
||||
break; |
||||
case "dblclick": |
||||
hand.dblclick(clk); |
||||
break; |
||||
case "lclick": |
||||
var mouseDown = false; |
||||
var interval; |
||||
hand.mousedown(function (e) { |
||||
BI.Widget._renderEngine.createElement(document).bind("mouseup." + self.getName(), function (e) { |
||||
interval && clearInterval(interval); |
||||
interval = null; |
||||
mouseDown = false; |
||||
BI.Widget._renderEngine.createElement(document).unbind("mouseup." + self.getName()); |
||||
}); |
||||
if (mouseDown === true) { |
||||
return; |
||||
} |
||||
if (!self.isEnabled() || (self.isOnce() && self.isSelected())) { |
||||
return; |
||||
} |
||||
interval = setInterval(function () { |
||||
if (self.isEnabled()) { |
||||
self.doClick(); |
||||
} |
||||
}, 180); |
||||
mouseDown = true; |
||||
ev(e); |
||||
}); |
||||
break; |
||||
default: |
||||
if (o.stopEvent || o.stopPropagation) { |
||||
hand.mousedown(function (e) { |
||||
ev(e); |
||||
}); |
||||
} |
||||
hand.click(clk); |
||||
break; |
||||
} |
||||
}); |
||||
|
||||
// 之后的300ms点击无效
|
||||
var onClick = BI.debounce(this._doClick, BI.EVENT_RESPONSE_TIME, { |
||||
"leading": true, |
||||
"trailing": false |
||||
}); |
||||
|
||||
function ev (e) { |
||||
if (o.stopEvent) { |
||||
e.stopEvent(); |
||||
} |
||||
if (o.stopPropagation) { |
||||
e.stopPropagation(); |
||||
} |
||||
} |
||||
|
||||
function clk (e) { |
||||
ev(e); |
||||
if (!self.isEnabled() || (self.isOnce() && self.isSelected())) { |
||||
return; |
||||
} |
||||
if (BI.isKey(o.bubble) || BI.isFunction(o.bubble)) { |
||||
if (BI.isNull(self.combo)) { |
||||
var popup; |
||||
BI.createWidget({ |
||||
type: "bi.absolute", |
||||
element: self, |
||||
items: [{ |
||||
el: { |
||||
type: "bi.bubble_combo", |
||||
trigger: "", |
||||
// bubble的提示不需要一直存在在界面上
|
||||
destroyWhenHide: true, |
||||
ref: function () { |
||||
self.combo = this; |
||||
}, |
||||
el: { |
||||
type: "bi.layout", |
||||
height: "100%" |
||||
}, |
||||
popup: { |
||||
type: "bi.text_bubble_bar_popup_view", |
||||
text: getBubble(), |
||||
ref: function () { |
||||
popup = this; |
||||
}, |
||||
listeners: [{ |
||||
eventName: BI.BubblePopupBarView.EVENT_CLICK_TOOLBAR_BUTTON, |
||||
action: function (v) { |
||||
self.combo.hideView(); |
||||
if (v) { |
||||
onClick.apply(self, arguments); |
||||
} |
||||
} |
||||
}] |
||||
}, |
||||
listeners: [{ |
||||
eventName: BI.BubbleCombo.EVENT_BEFORE_POPUPVIEW, |
||||
action: function () { |
||||
popup.populate(getBubble()); |
||||
} |
||||
}] |
||||
}, |
||||
left: 0, |
||||
right: 0, |
||||
bottom: 0, |
||||
top: 0 |
||||
}] |
||||
}); |
||||
} |
||||
if (self.combo.isViewVisible()) { |
||||
self.combo.hideView(); |
||||
} else { |
||||
self.combo.showView(); |
||||
} |
||||
return; |
||||
} |
||||
onClick.apply(self, arguments); |
||||
} |
||||
|
||||
function getBubble () { |
||||
var bubble = self.options.bubble; |
||||
if (BI.isFunction(bubble)) { |
||||
return bubble(); |
||||
} |
||||
return bubble; |
||||
} |
||||
}, |
||||
|
||||
_trigger: function (e) { |
||||
var o = this.options; |
||||
if (!this.isEnabled()) { |
||||
return; |
||||
} |
||||
if (!this.isDisableSelected()) { |
||||
this.isForceSelected() ? this.setSelected(true) : |
||||
(this.isForceNotSelected() ? this.setSelected(false) : |
||||
this.setSelected(!this.isSelected())); |
||||
} |
||||
if (this.isValid()) { |
||||
var v = this.getValue(); |
||||
o.handler.call(this, v, this, e); |
||||
this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.CLICK, v, this, e); |
||||
this.fireEvent(BI.BasicButton.EVENT_CHANGE, v, this); |
||||
if (o.action) { |
||||
BI.Actions.runAction(o.action, "click", o, this); |
||||
} |
||||
BI.Actions.runGlobalAction("click", o, this); |
||||
} |
||||
}, |
||||
|
||||
_doClick: function (e) { |
||||
if (this.isValid()) { |
||||
this.beforeClick(e); |
||||
} |
||||
this._trigger(e); |
||||
if (this.isValid()) { |
||||
this.doClick(e); |
||||
} |
||||
}, |
||||
|
||||
beforeClick: function () { |
||||
|
||||
}, |
||||
|
||||
doClick: function () { |
||||
|
||||
}, |
||||
|
||||
handle: function () { |
||||
return this; |
||||
}, |
||||
|
||||
hover: function () { |
||||
this._hover = true; |
||||
this.handle().element.addClass("hover"); |
||||
if (this.options.shadow) { |
||||
this.$mask && this.$mask.setVisible(true); |
||||
} |
||||
}, |
||||
|
||||
dishover: function () { |
||||
this._hover = false; |
||||
this.handle().element.removeClass("hover"); |
||||
if (this.options.shadow) { |
||||
this.$mask && this.$mask.setVisible(false); |
||||
} |
||||
}, |
||||
|
||||
setSelected: function (b) { |
||||
var o = this.options; |
||||
o.selected = b; |
||||
if (b) { |
||||
this.handle().element.addClass("active"); |
||||
} else { |
||||
this.handle().element.removeClass("active"); |
||||
} |
||||
if (o.shadow && !o.isShadowShowingOnSelected) { |
||||
this.$mask && this.$mask.setVisible(false); |
||||
} |
||||
this.options.setSelected && this.options.setSelected.call(this, b); |
||||
}, |
||||
|
||||
isSelected: function () { |
||||
return this.options.selected; |
||||
}, |
||||
|
||||
isOnce: function () { |
||||
return this.options.once; |
||||
}, |
||||
|
||||
isForceSelected: function () { |
||||
return this.options.forceSelected; |
||||
}, |
||||
|
||||
isForceNotSelected: function () { |
||||
return this.options.forceNotSelected; |
||||
}, |
||||
|
||||
isDisableSelected: function () { |
||||
return this.options.disableSelected; |
||||
}, |
||||
|
||||
setText: function (text) { |
||||
this.options.text = text; |
||||
this.options.setText && this.options.setText.call(this, text); |
||||
}, |
||||
|
||||
getText: function () { |
||||
return this.options.text; |
||||
}, |
||||
|
||||
_setEnable: function (enable) { |
||||
BI.BasicButton.superclass._setEnable.apply(this, arguments); |
||||
if (enable === true) { |
||||
this.element.removeClass("base-disabled disabled"); |
||||
} else if (enable === false) { |
||||
this.element.addClass("base-disabled disabled"); |
||||
} |
||||
if (!enable) { |
||||
if (this.options.shadow) { |
||||
this.$mask && this.$mask.setVisible(false); |
||||
} |
||||
} |
||||
}, |
||||
|
||||
empty: function () { |
||||
BI.Widget._renderEngine.createElement(document).unbind("mouseup." + this.getName()); |
||||
BI.BasicButton.superclass.empty.apply(this, arguments); |
||||
} |
||||
}); |
||||
BI.BasicButton.EVENT_CHANGE = "BasicButton.EVENT_CHANGE"; |
||||
BI.shortcut("bi.basic_button", BI.BasicButton); |
@ -0,0 +1,57 @@
|
||||
/** |
||||
* 表示一个可以展开的节点, 不仅有选中状态而且有展开状态 |
||||
* |
||||
* Created by GUY on 2015/9/9. |
||||
* @class BI.NodeButton |
||||
* @extends BI.BasicButton |
||||
* @abstract |
||||
*/ |
||||
BI.NodeButton = BI.inherit(BI.BasicButton, { |
||||
_defaultConfig: function () { |
||||
var conf = BI.NodeButton.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend( conf, { |
||||
_baseCls: (conf._baseCls || "") + " bi-node", |
||||
open: false |
||||
}); |
||||
}, |
||||
|
||||
_init: function () { |
||||
BI.NodeButton.superclass._init.apply(this, arguments); |
||||
var self = this; |
||||
BI.nextTick(function () { |
||||
self.setOpened(self.isOpened()); |
||||
}); |
||||
}, |
||||
|
||||
doClick: function () { |
||||
BI.NodeButton.superclass.doClick.apply(this, arguments); |
||||
this.setOpened(!this.isOpened()); |
||||
}, |
||||
|
||||
isOnce: function () { |
||||
return false; |
||||
}, |
||||
|
||||
isOpened: function () { |
||||
return !!this.options.open; |
||||
}, |
||||
|
||||
setOpened: function (b) { |
||||
this.options.open = !!b; |
||||
}, |
||||
|
||||
triggerCollapse: function () { |
||||
if(this.isOpened()) { |
||||
this.setOpened(false); |
||||
this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, this.getValue(), this); |
||||
} |
||||
}, |
||||
|
||||
triggerExpand: function () { |
||||
if(!this.isOpened()) { |
||||
this.setOpened(true); |
||||
this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, this.getValue(), this); |
||||
} |
||||
} |
||||
}); |
||||
BI.shortcut("bi.node_button", BI.NodeButton); |
@ -0,0 +1,117 @@
|
||||
/** |
||||
* Created by windy on 2018/01/23. |
||||
*/ |
||||
describe("ButtonTest", function () { |
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("Click点击触发事件", function (done) { |
||||
var button = BI.Test.createWidget({ |
||||
type: "bi.button", |
||||
text: "CCC", |
||||
handler: function () { |
||||
this.setText("click"); |
||||
} |
||||
}); |
||||
BI.nextTick(function () { |
||||
button.element.click(); |
||||
expect(button.element.children(".bi-text").text()).to.equal("click"); |
||||
button.destroy(); |
||||
done(); |
||||
}); |
||||
|
||||
}); |
||||
|
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("MouseDown触发事件", function (done) { |
||||
var button = BI.Test.createWidget({ |
||||
type: "bi.button", |
||||
text: "CCC", |
||||
trigger: "mousedown", |
||||
handler: function () { |
||||
this.setText("click"); |
||||
} |
||||
}); |
||||
BI.nextTick(function () { |
||||
button.element.mousedown(); |
||||
expect(button.element.children(".bi-text").text()).to.equal("click"); |
||||
button.destroy(); |
||||
done(); |
||||
}); |
||||
|
||||
}); |
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("MouseUp触发事件", function (done) { |
||||
var button = BI.Test.createWidget({ |
||||
type: "bi.button", |
||||
text: "CCC", |
||||
trigger: "mouseup", |
||||
handler: function () { |
||||
this.setText("click"); |
||||
} |
||||
}); |
||||
BI.nextTick(function () { |
||||
button.element.mousedown(); |
||||
button.element.mouseup(); |
||||
expect(button.element.children(".bi-text").text()).to.equal("click"); |
||||
button.destroy(); |
||||
done(); |
||||
}); |
||||
|
||||
}); |
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("doubleClick触发事件", function (done) { |
||||
var button = BI.Test.createWidget({ |
||||
type: "bi.button", |
||||
text: "CCC", |
||||
trigger: "dblclick", |
||||
handler: function () { |
||||
this.setText("click"); |
||||
} |
||||
}); |
||||
BI.nextTick(function () { |
||||
button.element.dblclick(); |
||||
expect(button.element.children(".bi-text").text()).to.equal("click"); |
||||
button.destroy(); |
||||
done(); |
||||
}); |
||||
|
||||
}); |
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("LongClick触发事件", function (done) { |
||||
var clickNum = 0; |
||||
var button = BI.Test.createWidget({ |
||||
type: "bi.button", |
||||
text: "CCC", |
||||
trigger: "lclick", |
||||
listeners: [{ |
||||
eventName: BI.Button.EVENT_CHANGE, |
||||
action: function () { |
||||
clickNum++; |
||||
} |
||||
}] |
||||
}); |
||||
BI.nextTick(function () { |
||||
button.element.mousedown(); |
||||
BI.delay(function () { |
||||
expect(clickNum).to.equal(2); |
||||
button.destroy(); |
||||
done(); |
||||
}, 360); |
||||
}); |
||||
|
||||
}); |
||||
}); |
@ -0,0 +1,51 @@
|
||||
/** |
||||
* @class BI.IconButton |
||||
* @extends BI.BasicButton |
||||
* 图标的button |
||||
*/ |
||||
BI.IconButton = BI.inherit(BI.BasicButton, { |
||||
_defaultConfig: function () { |
||||
var conf = BI.IconButton.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend(conf, { |
||||
_baseCls: (conf._baseCls || "") + " bi-icon-button horizon-center", |
||||
iconWidth: null, |
||||
iconHeight: null |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var o = this.options; |
||||
this.element.css({ |
||||
textAlign: "center" |
||||
}); |
||||
this.icon = BI.createWidget({ |
||||
type: "bi.icon", |
||||
width: o.iconWidth, |
||||
height: o.iconHeight |
||||
}); |
||||
if (BI.isNumber(o.height) && o.height > 0 && BI.isNull(o.iconWidth) && BI.isNull(o.iconHeight)) { |
||||
this.element.css("lineHeight", o.height / BI.pixRatio + BI.pixUnit); |
||||
BI.createWidget({ |
||||
type: "bi.default", |
||||
element: this, |
||||
items: [this.icon] |
||||
}); |
||||
} else { |
||||
this.element.css("lineHeight", "1"); |
||||
BI.createWidget({ |
||||
element: this, |
||||
type: "bi.center_adapt", |
||||
items: [this.icon] |
||||
}); |
||||
} |
||||
}, |
||||
|
||||
doClick: function () { |
||||
BI.IconButton.superclass.doClick.apply(this, arguments); |
||||
if (this.isValid()) { |
||||
this.fireEvent(BI.IconButton.EVENT_CHANGE, this); |
||||
} |
||||
} |
||||
}); |
||||
BI.IconButton.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
BI.shortcut("bi.icon_button", BI.IconButton); |
@ -0,0 +1,86 @@
|
||||
/** |
||||
* 图片的button |
||||
* |
||||
* Created by GUY on 2016/1/27. |
||||
* @class BI.ImageButton |
||||
* @extends BI.BasicButton |
||||
*/ |
||||
BI.ImageButton = BI.inherit(BI.BasicButton, { |
||||
_defaultConfig: function () { |
||||
var conf = BI.ImageButton.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend(conf, { |
||||
baseCls: (conf.baseCls || "") + " bi-image-button", |
||||
src: "", |
||||
iconWidth: "100%", |
||||
iconHeight: "100%" |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var o = this.options; |
||||
this.image = BI.createWidget({ |
||||
type: "bi.img", |
||||
width: o.iconWidth, |
||||
height: o.iconHeight, |
||||
src: o.src |
||||
}); |
||||
if (BI.isNumber(o.iconWidth) || BI.isNumber(o.iconHeight)) { |
||||
BI.createWidget({ |
||||
type: "bi.center_adapt", |
||||
element: this, |
||||
items: [this.image] |
||||
}); |
||||
} else { |
||||
BI.createWidget({ |
||||
type: "bi.adaptive", |
||||
element: this, |
||||
items: [this.image], |
||||
scrollable: false |
||||
}); |
||||
} |
||||
}, |
||||
|
||||
setWidth: function (w) { |
||||
BI.ImageButton.superclass.setWidth.apply(this, arguments); |
||||
this.options.width = w; |
||||
}, |
||||
|
||||
setHeight: function (h) { |
||||
BI.ImageButton.superclass.setHeight.apply(this, arguments); |
||||
this.options.height = h; |
||||
}, |
||||
|
||||
setImageWidth: function (w) { |
||||
this.image.setWidth(w); |
||||
}, |
||||
|
||||
setImageHeight: function (h) { |
||||
this.image.setHeight(h); |
||||
}, |
||||
|
||||
getImageWidth: function () { |
||||
return this.image.element.width(); |
||||
}, |
||||
|
||||
getImageHeight: function () { |
||||
return this.image.element.height(); |
||||
}, |
||||
|
||||
setSrc: function (src) { |
||||
this.options.src = src; |
||||
this.image.setSrc(src); |
||||
}, |
||||
|
||||
getSrc: function () { |
||||
return this.image.getSrc(); |
||||
}, |
||||
|
||||
doClick: function () { |
||||
BI.ImageButton.superclass.doClick.apply(this, arguments); |
||||
if (this.isValid()) { |
||||
this.fireEvent(BI.ImageButton.EVENT_CHANGE, this); |
||||
} |
||||
} |
||||
}); |
||||
BI.ImageButton.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
BI.shortcut("bi.image_button", BI.ImageButton); |
@ -0,0 +1,157 @@
|
||||
/** |
||||
* 文字类型的按钮 |
||||
* @class BI.Button |
||||
* @extends BI.BasicButton |
||||
* |
||||
* @cfg {JSON} options 配置属性 |
||||
* @cfg {'common'/'success'/'warning'/'ignore'} [options.level='common'] 按钮类型,用不同颜色强调不同的场景 |
||||
*/ |
||||
BI.Button = BI.inherit(BI.BasicButton, { |
||||
|
||||
_const: { |
||||
iconWidth: 18 |
||||
}, |
||||
|
||||
_defaultConfig: function (props) { |
||||
var conf = BI.Button.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend(conf, { |
||||
baseCls: (conf.baseCls || "") + " bi-button" + ((BI.isIE() && BI.isIE9Below()) ? " hack" : ""), |
||||
minWidth: (props.block === true || props.clear === true) ? 0 : 80, |
||||
height: 24, |
||||
shadow: props.clear !== true, |
||||
isShadowShowingOnSelected: true, |
||||
readonly: true, |
||||
iconCls: "", |
||||
level: "common", |
||||
block: false, // 是否块状显示,即不显示边框,没有最小宽度的限制
|
||||
clear: false, // 是否去掉边框和背景
|
||||
ghost: false, // 是否幽灵显示, 即正常状态无背景
|
||||
textAlign: "center", |
||||
whiteSpace: "nowrap", |
||||
textWidth: null, |
||||
textHeight: null, |
||||
hgap: props.clear ? 0 : 10, |
||||
vgap: 0, |
||||
tgap: 0, |
||||
bgap: 0, |
||||
lgap: 0, |
||||
rgap: 0 |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var o = this.options, self = this; |
||||
|
||||
// 由于button默认情况下有个边框,所以要主动算行高
|
||||
var lineHeight, textHeight = o.textHeight; |
||||
if (BI.isNumber(o.height)) { |
||||
if (o.clear || o.block) { |
||||
lineHeight = o.height; |
||||
} else { |
||||
lineHeight = o.height - 2; |
||||
} |
||||
} |
||||
if (!textHeight) { |
||||
if (o.whiteSpace === "nowrap") { |
||||
textHeight = lineHeight; |
||||
} |
||||
} |
||||
if (BI.isKey(o.iconCls)) { |
||||
this.icon = BI.createWidget({ |
||||
type: "bi.icon_label", |
||||
cls: o.iconCls, |
||||
width: this._const.iconWidth, |
||||
height: o.height, |
||||
lineHeight: lineHeight, |
||||
iconWidth: o.iconWidth, |
||||
iconHeight: o.iconHeight |
||||
}); |
||||
this.text = BI.createWidget({ |
||||
type: "bi.label", |
||||
text: o.text, |
||||
textWidth: BI.isNotNull(o.textWidth) ? o.textWidth - this._const.iconWidth : null, |
||||
textHeight: textHeight, |
||||
height: o.height, |
||||
value: o.value |
||||
}); |
||||
BI.createWidget({ |
||||
type: "bi.center_adapt", |
||||
element: this, |
||||
hgap: o.hgap, |
||||
vgap: o.vgap, |
||||
items: [{ |
||||
type: "bi.horizontal", |
||||
columnSize: ["", "fill"], |
||||
items: [this.icon, this.text] |
||||
}] |
||||
}); |
||||
} else { |
||||
this.text = BI.createWidget({ |
||||
type: "bi.label", |
||||
height: o.height, |
||||
textAlign: o.textAlign, |
||||
whiteSpace: o.whiteSpace, |
||||
textWidth: o.textWidth, |
||||
textHeight: textHeight, |
||||
hgap: o.hgap, |
||||
vgap: o.vgap, |
||||
tgap: o.tgap, |
||||
bgap: o.bgap, |
||||
lgap: o.lgap, |
||||
rgap: o.rgap, |
||||
element: this, |
||||
text: o.text, |
||||
value: o.value |
||||
}); |
||||
} |
||||
if (o.block === true) { |
||||
this.element.addClass("block"); |
||||
} |
||||
if (o.clear === true) { |
||||
this.element.addClass("clear"); |
||||
} |
||||
if (o.ghost === true) { |
||||
this.element.addClass("ghost"); |
||||
} |
||||
if (o.minWidth > 0) { |
||||
this.element.css({"min-width": o.minWidth / BI.pixRatio + BI.pixUnit}); |
||||
} |
||||
}, |
||||
|
||||
doClick: function () { |
||||
BI.Button.superclass.doClick.apply(this, arguments); |
||||
if (this.isValid()) { |
||||
this.fireEvent(BI.Button.EVENT_CHANGE, this); |
||||
} |
||||
}, |
||||
|
||||
setText: function (text) { |
||||
BI.Button.superclass.setText.apply(this, arguments); |
||||
this.text.setText(text); |
||||
}, |
||||
|
||||
setValue: function (text) { |
||||
BI.Button.superclass.setValue.apply(this, arguments); |
||||
if (!this.isReadOnly()) { |
||||
this.text.setValue(text); |
||||
} |
||||
}, |
||||
|
||||
doRedMark: function () { |
||||
this.text.doRedMark.apply(this.text, arguments); |
||||
}, |
||||
|
||||
unRedMark: function () { |
||||
this.text.unRedMark.apply(this.text, arguments); |
||||
}, |
||||
|
||||
doHighLight: function () { |
||||
this.text.doHighLight.apply(this.text, arguments); |
||||
}, |
||||
|
||||
unHighLight: function () { |
||||
this.text.unHighLight.apply(this.text, arguments); |
||||
} |
||||
}); |
||||
BI.shortcut("bi.button", BI.Button); |
||||
BI.Button.EVENT_CHANGE = "EVENT_CHANGE"; |
@ -0,0 +1,89 @@
|
||||
/** |
||||
* guy |
||||
* 可以点击的一行文字 |
||||
* @class BI.TextButton |
||||
* @extends BI.BasicButton |
||||
* 文字button |
||||
*/ |
||||
BI.TextButton = BI.inherit(BI.BasicButton, { |
||||
_defaultConfig: function () { |
||||
var conf = BI.TextButton.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend(conf, { |
||||
baseCls: (conf.baseCls || "") + " bi-text-button", |
||||
textAlign: "center", |
||||
whiteSpace: "nowrap", |
||||
textWidth: null, |
||||
textHeight: null, |
||||
hgap: 0, |
||||
lgap: 0, |
||||
rgap: 0, |
||||
vgap: 0, |
||||
py: "" |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var o = this.options; |
||||
this.text = BI.createWidget({ |
||||
type: "bi.label", |
||||
element: this, |
||||
textAlign: o.textAlign, |
||||
whiteSpace: o.whiteSpace, |
||||
textWidth: o.textWidth, |
||||
textHeight: o.textHeight, |
||||
width: o.width, |
||||
height: o.height, |
||||
hgap: o.hgap, |
||||
vgap: o.vgap, |
||||
lgap: o.lgap, |
||||
rgap: o.rgap, |
||||
text: o.text, |
||||
value: o.value, |
||||
py: o.py, |
||||
keyword: o.keyword |
||||
}); |
||||
}, |
||||
|
||||
doClick: function () { |
||||
BI.TextButton.superclass.doClick.apply(this, arguments); |
||||
if (this.isValid()) { |
||||
this.fireEvent(BI.TextButton.EVENT_CHANGE, this.getValue(), this); |
||||
} |
||||
}, |
||||
|
||||
doRedMark: function () { |
||||
this.text.doRedMark.apply(this.text, arguments); |
||||
}, |
||||
|
||||
unRedMark: function () { |
||||
this.text.unRedMark.apply(this.text, arguments); |
||||
}, |
||||
|
||||
doHighLight: function () { |
||||
this.text.doHighLight.apply(this.text, arguments); |
||||
}, |
||||
|
||||
unHighLight: function () { |
||||
this.text.unHighLight.apply(this.text, arguments); |
||||
}, |
||||
|
||||
setText: function (text) { |
||||
BI.TextButton.superclass.setText.apply(this, arguments); |
||||
text = BI.isArray(text) ? text.join(",") : text; |
||||
this.text.setText(text); |
||||
}, |
||||
|
||||
setStyle: function (style) { |
||||
this.text.setStyle(style); |
||||
}, |
||||
|
||||
setValue: function (text) { |
||||
BI.TextButton.superclass.setValue.apply(this, arguments); |
||||
if (!this.isReadOnly()) { |
||||
text = BI.isArray(text) ? text.join(",") : text; |
||||
this.text.setValue(text); |
||||
} |
||||
} |
||||
}); |
||||
BI.TextButton.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
BI.shortcut("bi.text_button", BI.TextButton); |
@ -0,0 +1,119 @@
|
||||
/** |
||||
* 带有一个占位 |
||||
* |
||||
* Created by GUY on 2015/9/11. |
||||
* @class BI.BlankIconIconTextItem |
||||
* @extends BI.BasicButton |
||||
*/ |
||||
BI.BlankIconIconTextItem = BI.inherit(BI.BasicButton, { |
||||
|
||||
_defaultConfig: function () { |
||||
var conf = BI.BlankIconIconTextItem.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend(conf, { |
||||
baseCls: (conf.baseCls || "") + " bi-blank-icon-text-item", |
||||
logic: { |
||||
dynamic: false |
||||
}, |
||||
iconCls1: "", |
||||
iconCls2: "", |
||||
blankWidth: 0, |
||||
iconHeight: null, |
||||
iconWidth: null, |
||||
textHgap: 0, |
||||
textVgap: 0, |
||||
textLgap: 0, |
||||
textRgap: 0 |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var o = this.options, c = this._const; |
||||
var blank = BI.createWidget({ |
||||
type: "bi.layout", |
||||
width: o.blankWidth, |
||||
height: o.height |
||||
}); |
||||
this.text = BI.createWidget({ |
||||
type: "bi.label", |
||||
cls: "list-item-text", |
||||
textAlign: "left", |
||||
hgap: o.textHgap, |
||||
vgap: o.textVgap, |
||||
lgap: o.textLgap, |
||||
rgap: o.textRgap, |
||||
text: o.text, |
||||
value: o.value, |
||||
keyword: o.keyword, |
||||
height: o.height |
||||
}); |
||||
this.icon1 = BI.createWidget({ |
||||
type: "bi.icon_button", |
||||
cls: o.iconCls1, |
||||
forceNotSelected: true, |
||||
width: o.height, |
||||
height: o.height |
||||
}); |
||||
this.icon2 = BI.createWidget({ |
||||
type: "bi.icon_button", |
||||
cls: o.iconCls2, |
||||
forceNotSelected: true, |
||||
width: o.height, |
||||
height: o.height |
||||
}); |
||||
|
||||
BI.createWidget(BI.extend({ |
||||
element: this |
||||
}, BI.LogicFactory.createLogic("horizontal", BI.extend(o.logic, { |
||||
items: BI.LogicFactory.createLogicItemsByDirection("left", blank, this.icon1, this.icon2, this.text) |
||||
})))); |
||||
}, |
||||
|
||||
doClick: function () { |
||||
BI.BlankIconIconTextItem.superclass.doClick.apply(this, arguments); |
||||
if (this.isValid()) { |
||||
this.fireEvent(BI.BlankIconIconTextItem.EVENT_CHANGE, this.getValue(), this); |
||||
} |
||||
}, |
||||
|
||||
setSelected: function (b) { |
||||
BI.BlankIconIconTextItem.superclass.setSelected.apply(this, arguments); |
||||
this.icon1.setSelected(b); |
||||
this.icon2.setSelected(b); |
||||
}, |
||||
|
||||
setValue: function () { |
||||
if (!this.isReadOnly()) { |
||||
this.text.setValue.apply(this.text, arguments); |
||||
} |
||||
}, |
||||
|
||||
getValue: function () { |
||||
return this.text.getValue(); |
||||
}, |
||||
|
||||
setText: function () { |
||||
this.text.setText.apply(this.text, arguments); |
||||
}, |
||||
|
||||
getText: function () { |
||||
return this.text.getText(); |
||||
}, |
||||
|
||||
doRedMark: function () { |
||||
this.text.doRedMark.apply(this.text, arguments); |
||||
}, |
||||
|
||||
unRedMark: function () { |
||||
this.text.unRedMark.apply(this.text, arguments); |
||||
}, |
||||
|
||||
doHighLight: function () { |
||||
this.text.doHighLight.apply(this.text, arguments); |
||||
}, |
||||
|
||||
unHighLight: function () { |
||||
this.text.unHighLight.apply(this.text, arguments); |
||||
} |
||||
}); |
||||
BI.BlankIconIconTextItem.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
BI.shortcut("bi.blank_icon_icon_text_item", BI.BlankIconIconTextItem); |
@ -0,0 +1,126 @@
|
||||
/** |
||||
* guy |
||||
* 一个占位符和两个icon和一行数 组成的一行listitem |
||||
* |
||||
* Created by GUY on 2015/9/15. |
||||
* @class BI.BlankIconTextIconItem |
||||
* @extends BI.BasicButton |
||||
*/ |
||||
BI.BlankIconTextIconItem = BI.inherit(BI.BasicButton, { |
||||
|
||||
_defaultConfig: function () { |
||||
var conf = BI.BlankIconTextIconItem.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend(conf, { |
||||
baseCls: (conf.baseCls || "") + " bi-blank-icon-text-icon-item", |
||||
logic: { |
||||
dynamic: false |
||||
}, |
||||
iconCls1: "", |
||||
iconCls2: "", |
||||
blankWidth: 0, |
||||
iconHeight: null, |
||||
iconWidth: null, |
||||
textHgap: 0, |
||||
textVgap: 0, |
||||
textLgap: 0, |
||||
textRgap: 0 |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var o = this.options, c = this._const; |
||||
this.text = BI.createWidget({ |
||||
type: "bi.label", |
||||
textAlign: "left", |
||||
hgap: o.textHgap, |
||||
vgap: o.textVgap, |
||||
lgap: o.textLgap, |
||||
rgap: o.textRgap, |
||||
text: o.text, |
||||
value: o.value, |
||||
keyword: o.keyword, |
||||
height: o.height |
||||
}); |
||||
|
||||
var icon1 = BI.createWidget({ |
||||
type: "bi.icon_label", |
||||
cls: o.iconCls1, |
||||
width: o.height, |
||||
height: o.height, |
||||
iconWidth: o.iconWidth, |
||||
iconHeight: o.iconHeight |
||||
}); |
||||
BI.createWidget({ |
||||
type: "bi.absolute", |
||||
element: this, |
||||
items: [{ |
||||
el: { |
||||
type: "bi.icon_label", |
||||
cls: o.iconCls2, |
||||
width: o.height, |
||||
height: o.height, |
||||
iconWidth: o.iconWidth, |
||||
iconHeight: o.iconHeight |
||||
}, |
||||
top: 0, |
||||
bottom: 0, |
||||
right: 0 |
||||
}] |
||||
}); |
||||
|
||||
BI.createWidget(BI.extend({ |
||||
element: this |
||||
}, BI.LogicFactory.createLogic("horizontal", BI.extend(o.logic, { |
||||
items: BI.LogicFactory.createLogicItemsByDirection("left", { |
||||
type: "bi.layout", |
||||
width: o.blankWidth |
||||
}, icon1, this.text, { |
||||
type: "bi.layout", |
||||
width: o.height |
||||
}) |
||||
})))); |
||||
}, |
||||
|
||||
doClick: function () { |
||||
BI.BlankIconTextIconItem.superclass.doClick.apply(this, arguments); |
||||
if (this.isValid()) { |
||||
this.fireEvent(BI.BlankIconTextIconItem.EVENT_CHANGE, this.getValue(), this); |
||||
} |
||||
}, |
||||
|
||||
doRedMark: function () { |
||||
this.text.doRedMark.apply(this.text, arguments); |
||||
}, |
||||
|
||||
unRedMark: function () { |
||||
this.text.unRedMark.apply(this.text, arguments); |
||||
}, |
||||
|
||||
doHighLight: function () { |
||||
this.text.doHighLight.apply(this.text, arguments); |
||||
}, |
||||
|
||||
unHighLight: function () { |
||||
this.text.unHighLight.apply(this.text, arguments); |
||||
}, |
||||
|
||||
setValue: function () { |
||||
if (!this.isReadOnly()) { |
||||
this.text.setValue.apply(this.text, arguments); |
||||
} |
||||
}, |
||||
|
||||
getValue: function () { |
||||
return this.text.getValue(); |
||||
}, |
||||
|
||||
setText: function () { |
||||
this.text.setText.apply(this.text, arguments); |
||||
}, |
||||
|
||||
getText: function () { |
||||
return this.text.getText(); |
||||
} |
||||
}); |
||||
BI.BlankIconTextIconItem.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
BI.shortcut("bi.blank_icon_text_icon_item", BI.BlankIconTextIconItem); |
@ -0,0 +1,105 @@
|
||||
/** |
||||
* 带有一个占位 |
||||
* |
||||
* Created by GUY on 2015/9/11. |
||||
* @class BI.BlankIconTextItem |
||||
* @extends BI.BasicButton |
||||
*/ |
||||
BI.BlankIconTextItem = BI.inherit(BI.BasicButton, { |
||||
|
||||
_defaultConfig: function () { |
||||
var conf = BI.BlankIconTextItem.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend(conf, { |
||||
baseCls: (conf.baseCls || "") + " bi-blank-icon-text-item", |
||||
logic: { |
||||
dynamic: false |
||||
}, |
||||
blankWidth: 0, |
||||
iconHeight: null, |
||||
iconWidth: null, |
||||
iconCls: "", |
||||
textHgap: 0, |
||||
textVgap: 0, |
||||
textLgap: 0, |
||||
textRgap: 0 |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var o = this.options, c = this._const; |
||||
var blank = BI.createWidget({ |
||||
type: "bi.layout", |
||||
width: o.blankWidth |
||||
}); |
||||
this.text = BI.createWidget({ |
||||
type: "bi.label", |
||||
cls: "list-item-text", |
||||
textAlign: "left", |
||||
hgap: o.textHgap, |
||||
vgap: o.textVgap, |
||||
lgap: o.textLgap, |
||||
rgap: o.textRgap, |
||||
text: o.text, |
||||
value: o.value, |
||||
keyword: o.keyword, |
||||
height: o.height |
||||
}); |
||||
this.icon = BI.createWidget({ |
||||
type: "bi.icon_label", |
||||
cls: o.iconCls, |
||||
width: o.height, |
||||
height: o.height, |
||||
iconWidth: o.iconWidth, |
||||
iconHeight: o.iconHeight |
||||
}); |
||||
|
||||
BI.createWidget(BI.extend({ |
||||
element: this |
||||
}, BI.LogicFactory.createLogic("horizontal", BI.extend(o.logic, { |
||||
items: BI.LogicFactory.createLogicItemsByDirection("left", blank, this.icon, this.text) |
||||
})))); |
||||
}, |
||||
|
||||
doClick: function () { |
||||
BI.BlankIconTextItem.superclass.doClick.apply(this, arguments); |
||||
if (this.isValid()) { |
||||
this.fireEvent(BI.BlankIconTextItem.EVENT_CHANGE, this.getValue(), this); |
||||
} |
||||
}, |
||||
|
||||
setValue: function () { |
||||
if (!this.isReadOnly()) { |
||||
this.text.setValue.apply(this.text, arguments); |
||||
} |
||||
}, |
||||
|
||||
getValue: function () { |
||||
return this.text.getValue(); |
||||
}, |
||||
|
||||
setText: function () { |
||||
this.text.setText.apply(this.text, arguments); |
||||
}, |
||||
|
||||
getText: function () { |
||||
return this.text.getText(); |
||||
}, |
||||
|
||||
doRedMark: function () { |
||||
this.text.doRedMark.apply(this.text, arguments); |
||||
}, |
||||
|
||||
unRedMark: function () { |
||||
this.text.unRedMark.apply(this.text, arguments); |
||||
}, |
||||
|
||||
doHighLight: function () { |
||||
this.text.doHighLight.apply(this.text, arguments); |
||||
}, |
||||
|
||||
unHighLight: function () { |
||||
this.text.unHighLight.apply(this.text, arguments); |
||||
} |
||||
}); |
||||
BI.BlankIconTextItem.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
BI.shortcut("bi.blank_icon_text_item", BI.BlankIconTextItem); |
@ -0,0 +1,123 @@
|
||||
/** |
||||
* guy |
||||
* 两个icon和一行数 组成的一行listitem |
||||
* |
||||
* Created by GUY on 2015/9/9. |
||||
* @class BI.IconTextIconItem |
||||
* @extends BI.BasicButton |
||||
*/ |
||||
BI.IconTextIconItem = BI.inherit(BI.BasicButton, { |
||||
|
||||
_defaultConfig: function () { |
||||
var conf = BI.IconTextIconItem.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend(conf, { |
||||
baseCls: (conf.baseCls || "") + " bi-icon-text-icon-item", |
||||
logic: { |
||||
dynamic: false |
||||
}, |
||||
iconCls1: "", |
||||
iconCls2: "", |
||||
iconHeight: null, |
||||
iconWidth: null, |
||||
textHgap: 0, |
||||
textVgap: 0, |
||||
textLgap: 0, |
||||
textRgap: 0 |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var o = this.options, c = this._const; |
||||
this.text = BI.createWidget({ |
||||
type: "bi.label", |
||||
textAlign: "left", |
||||
hgap: o.textHgap, |
||||
vgap: o.textVgap, |
||||
lgap: o.textLgap, |
||||
rgap: o.textRgap, |
||||
text: o.text, |
||||
value: o.value, |
||||
keyword: o.keyword, |
||||
height: o.height |
||||
}); |
||||
|
||||
var icon1 = BI.createWidget({ |
||||
type: "bi.icon_label", |
||||
cls: o.iconCls1, |
||||
width: o.leftIconWrapperWidth, |
||||
height: o.height, |
||||
iconWidth: o.iconWidth, |
||||
iconHeight: o.iconHeight |
||||
}); |
||||
var blank = BI.createWidget({ |
||||
type: "bi.layout", |
||||
width: o.height |
||||
}); |
||||
BI.createWidget({ |
||||
type: "bi.absolute", |
||||
element: this, |
||||
items: [{ |
||||
el: { |
||||
type: "bi.icon_label", |
||||
cls: o.iconCls2, |
||||
width: o.rightIconWrapperWidth, |
||||
height: o.height, |
||||
iconWidth: o.iconWidth, |
||||
iconHeight: o.iconHeight |
||||
}, |
||||
top: 0, |
||||
bottom: 0, |
||||
right: 0 |
||||
}] |
||||
}); |
||||
|
||||
BI.createWidget(BI.extend({ |
||||
element: this |
||||
}, BI.LogicFactory.createLogic("horizontal", BI.extend(o.logic, { |
||||
items: BI.LogicFactory.createLogicItemsByDirection("left", icon1, this.text, blank) |
||||
})))); |
||||
}, |
||||
|
||||
doClick: function () { |
||||
BI.IconTextIconItem.superclass.doClick.apply(this, arguments); |
||||
if (this.isValid()) { |
||||
this.fireEvent(BI.IconTextIconItem.EVENT_CHANGE, this.getValue(), this); |
||||
} |
||||
}, |
||||
|
||||
doRedMark: function () { |
||||
this.text.doRedMark.apply(this.text, arguments); |
||||
}, |
||||
|
||||
unRedMark: function () { |
||||
this.text.unRedMark.apply(this.text, arguments); |
||||
}, |
||||
|
||||
doHighLight: function () { |
||||
this.text.doHighLight.apply(this.text, arguments); |
||||
}, |
||||
|
||||
unHighLight: function () { |
||||
this.text.unHighLight.apply(this.text, arguments); |
||||
}, |
||||
|
||||
setValue: function () { |
||||
if (!this.isReadOnly()) { |
||||
this.text.setValue.apply(this.text, arguments); |
||||
} |
||||
}, |
||||
|
||||
getValue: function () { |
||||
return this.text.getValue(); |
||||
}, |
||||
|
||||
setText: function () { |
||||
this.text.setText.apply(this.text, arguments); |
||||
}, |
||||
|
||||
getText: function () { |
||||
return this.text.getText(); |
||||
} |
||||
}); |
||||
BI.IconTextIconItem.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
BI.shortcut("bi.icon_text_icon_item", BI.IconTextIconItem); |
@ -0,0 +1,102 @@
|
||||
/** |
||||
* guy |
||||
* |
||||
* Created by GUY on 2015/9/9. |
||||
* @class BI.IconTextItem |
||||
* @extends BI.BasicButton |
||||
*/ |
||||
BI.IconTextItem = BI.inherit(BI.BasicButton, { |
||||
|
||||
_defaultConfig: function () { |
||||
var conf = BI.IconTextItem.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend(conf, { |
||||
baseCls: (conf.baseCls || "") + " bi-icon-text-item", |
||||
direction: BI.Direction.Left, |
||||
logic: { |
||||
dynamic: false |
||||
}, |
||||
iconWrapperWidth: null, |
||||
iconHeight: null, |
||||
iconWidth: null, |
||||
iconCls: "", |
||||
textHgap: 0, |
||||
textVgap: 0, |
||||
textLgap: 0, |
||||
textRgap: 0 |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var o = this.options, c = this._const; |
||||
this.text = BI.createWidget({ |
||||
type: "bi.label", |
||||
cls: "list-item-text", |
||||
textAlign: "left", |
||||
hgap: o.textHgap, |
||||
vgap: o.textVgap, |
||||
lgap: o.textLgap, |
||||
rgap: o.textRgap, |
||||
text: o.text, |
||||
value: o.value, |
||||
keyword: o.keyword, |
||||
height: o.height |
||||
}); |
||||
this.icon = BI.createWidget({ |
||||
type: "bi.icon_label", |
||||
cls: o.iconCls, |
||||
width: o.iconWrapperWidth || o.height, |
||||
height: o.height, |
||||
iconWidth: o.iconWidth, |
||||
iconHeight: o.iconHeight |
||||
}); |
||||
|
||||
BI.createWidget(BI.extend({ |
||||
element: this |
||||
}, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(o.direction), BI.extend(o.logic, { |
||||
items: BI.LogicFactory.createLogicItemsByDirection(o.direction, this.icon, this.text) |
||||
})))); |
||||
}, |
||||
|
||||
setValue: function () { |
||||
if (!this.isReadOnly()) { |
||||
this.text.setValue.apply(this.text, arguments); |
||||
} |
||||
}, |
||||
|
||||
getValue: function () { |
||||
return this.text.getValue(); |
||||
}, |
||||
|
||||
setText: function () { |
||||
this.text.setText.apply(this.text, arguments); |
||||
}, |
||||
|
||||
getText: function () { |
||||
return this.text.getText(); |
||||
}, |
||||
|
||||
doClick: function () { |
||||
BI.IconTextItem.superclass.doClick.apply(this, arguments); |
||||
if (this.isValid()) { |
||||
this.fireEvent(BI.IconTextItem.EVENT_CHANGE, this.getValue(), this); |
||||
} |
||||
}, |
||||
|
||||
doRedMark: function () { |
||||
this.text.doRedMark.apply(this.text, arguments); |
||||
}, |
||||
|
||||
unRedMark: function () { |
||||
this.text.unRedMark.apply(this.text, arguments); |
||||
}, |
||||
|
||||
doHighLight: function () { |
||||
this.text.doHighLight.apply(this.text, arguments); |
||||
}, |
||||
|
||||
unHighLight: function () { |
||||
this.text.unHighLight.apply(this.text, arguments); |
||||
} |
||||
}); |
||||
BI.IconTextItem.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
BI.shortcut("bi.icon_text_item", BI.IconTextItem); |
@ -0,0 +1,101 @@
|
||||
/** |
||||
* |
||||
* 图标的button |
||||
* |
||||
* Created by GUY on 2015/9/9. |
||||
* @class BI.TextIconItem |
||||
* @extends BI.BasicButton |
||||
*/ |
||||
BI.TextIconItem = BI.inherit(BI.BasicButton, { |
||||
|
||||
_defaultConfig: function () { |
||||
var conf = BI.TextIconItem.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend(conf, { |
||||
baseCls: (conf.baseCls || "") + " bi-text-icon-item", |
||||
logic: { |
||||
dynamic: false |
||||
}, |
||||
iconHeight: null, |
||||
iconWidth: null, |
||||
iconCls: "", |
||||
textHgap: 0, |
||||
textVgap: 0, |
||||
textLgap: 0, |
||||
textRgap: 0 |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var o = this.options, c = this._const; |
||||
this.text = BI.createWidget({ |
||||
type: "bi.label", |
||||
cls: "list-item-text", |
||||
textAlign: "left", |
||||
hgap: o.textHgap, |
||||
vgap: o.textVgap, |
||||
lgap: o.textLgap, |
||||
rgap: o.textRgap, |
||||
text: o.text, |
||||
value: o.value, |
||||
keyword: o.keyword, |
||||
height: o.height |
||||
}); |
||||
this.icon = BI.createWidget({ |
||||
type: "bi.icon_label", |
||||
cls: o.iconCls, |
||||
width: o.height, |
||||
height: o.height, |
||||
iconWidth: o.iconWidth, |
||||
iconHeight: o.iconHeight |
||||
}); |
||||
|
||||
BI.createWidget(BI.extend({ |
||||
element: this |
||||
}, BI.LogicFactory.createLogic("horizontal", BI.extend(o.logic, { |
||||
items: BI.LogicFactory.createLogicItemsByDirection("left", this.text, this.icon) |
||||
})))); |
||||
}, |
||||
|
||||
doClick: function () { |
||||
BI.TextIconItem.superclass.doClick.apply(this, arguments); |
||||
if (this.isValid()) { |
||||
this.fireEvent(BI.TextIconItem.EVENT_CHANGE, this.getValue(), this); |
||||
} |
||||
}, |
||||
|
||||
setValue: function () { |
||||
if (!this.isReadOnly()) { |
||||
this.text.setValue.apply(this.text, arguments); |
||||
} |
||||
}, |
||||
|
||||
getValue: function () { |
||||
return this.text.getValue(); |
||||
}, |
||||
|
||||
setText: function () { |
||||
this.text.setText.apply(this.text, arguments); |
||||
}, |
||||
|
||||
getText: function () { |
||||
return this.text.getText(); |
||||
}, |
||||
|
||||
doRedMark: function () { |
||||
this.text.doRedMark.apply(this.text, arguments); |
||||
}, |
||||
|
||||
unRedMark: function () { |
||||
this.text.unRedMark.apply(this.text, arguments); |
||||
}, |
||||
|
||||
doHighLight: function () { |
||||
this.text.doHighLight.apply(this.text, arguments); |
||||
}, |
||||
|
||||
unHighLight: function () { |
||||
this.text.unHighLight.apply(this.text, arguments); |
||||
} |
||||
}); |
||||
BI.TextIconItem.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
BI.shortcut("bi.text_icon_item", BI.TextIconItem); |
@ -0,0 +1,86 @@
|
||||
/** |
||||
* guy |
||||
* 一个button和一行数 组成的一行listitem |
||||
* |
||||
* Created by GUY on 2015/9/9. |
||||
* @class BI.TextItem |
||||
* @extends BI.BasicButton |
||||
*/ |
||||
BI.TextItem = BI.inherit(BI.BasicButton, { |
||||
|
||||
_defaultConfig: function () { |
||||
var conf = BI.TextItem.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend(conf, { |
||||
baseCls: (conf.baseCls || "") + " bi-text-item", |
||||
textAlign: "left", |
||||
whiteSpace: "nowrap", |
||||
textHgap: 0, |
||||
textVgap: 0, |
||||
textLgap: 0, |
||||
textRgap: 0 |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var o = this.options; |
||||
this.text = BI.createWidget({ |
||||
type: "bi.label", |
||||
element: this, |
||||
textAlign: o.textAlign, |
||||
whiteSpace: o.whiteSpace, |
||||
textHeight: o.whiteSpace == "nowrap" ? o.height : o.textHeight, |
||||
height: o.height, |
||||
hgap: o.textHgap, |
||||
vgap: o.textVgap, |
||||
lgap: o.textLgap, |
||||
rgap: o.textRgap, |
||||
text: o.text, |
||||
value: o.value, |
||||
keyword: o.keyword, |
||||
py: o.py |
||||
}); |
||||
}, |
||||
|
||||
doClick: function () { |
||||
BI.TextItem.superclass.doClick.apply(this, arguments); |
||||
if (this.isValid()) { |
||||
this.fireEvent(BI.TextItem.EVENT_CHANGE, this.getValue(), this); |
||||
} |
||||
}, |
||||
|
||||
doRedMark: function () { |
||||
this.text.doRedMark.apply(this.text, arguments); |
||||
}, |
||||
|
||||
unRedMark: function () { |
||||
this.text.unRedMark.apply(this.text, arguments); |
||||
}, |
||||
|
||||
doHighLight: function () { |
||||
this.text.doHighLight.apply(this.text, arguments); |
||||
}, |
||||
|
||||
unHighLight: function () { |
||||
this.text.unHighLight.apply(this.text, arguments); |
||||
}, |
||||
|
||||
setValue: function () { |
||||
if (!this.isReadOnly()) { |
||||
this.text.setValue.apply(this.text, arguments); |
||||
} |
||||
}, |
||||
|
||||
getValue: function () { |
||||
return this.text.getValue(); |
||||
}, |
||||
|
||||
setText: function () { |
||||
this.text.setText.apply(this.text, arguments); |
||||
}, |
||||
|
||||
getText: function () { |
||||
return this.text.getText(); |
||||
} |
||||
}); |
||||
BI.TextItem.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
BI.shortcut("bi.text_item", BI.TextItem); |
@ -0,0 +1,104 @@
|
||||
/** |
||||
* @author Kobi |
||||
* @date 2020/4/21 |
||||
*/ |
||||
|
||||
describe("IconTextIconNodeTest", function () { |
||||
|
||||
/** |
||||
* test_author_kobi |
||||
*/ |
||||
it("setText", function () { |
||||
var iconTextIconNode = BI.Test.createWidget({ |
||||
type: "bi.icon_text_icon_node" |
||||
}); |
||||
iconTextIconNode.setText("AAA"); |
||||
expect(iconTextIconNode.element.find(".bi-text").text()).to.equal("AAA"); |
||||
iconTextIconNode.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_kobi |
||||
*/ |
||||
it("getText", function () { |
||||
var iconTextIconNode = BI.Test.createWidget({ |
||||
type: "bi.icon_text_icon_node", |
||||
text: "AAA", |
||||
}); |
||||
expect(iconTextIconNode.getText()).to.equal("AAA"); |
||||
iconTextIconNode.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_kobi |
||||
*/ |
||||
it("setValue", function () { |
||||
var iconTextIconNode = BI.Test.createWidget({ |
||||
type: "bi.icon_text_icon_node" |
||||
}); |
||||
iconTextIconNode.setValue("AAA"); |
||||
expect(iconTextIconNode.element.find(".bi-text").text()).to.equal("AAA"); |
||||
iconTextIconNode.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_kobi |
||||
*/ |
||||
it("readonly下的setValue", function () { |
||||
var iconTextIconNode = BI.Test.createWidget({ |
||||
type: "bi.icon_text_icon_node", |
||||
value: "AAA", |
||||
readonly: true |
||||
}); |
||||
iconTextIconNode.setValue("BBB"); |
||||
expect(iconTextIconNode.element.find(".bi-text").text()).to.equal("AAA"); |
||||
iconTextIconNode.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_kobi |
||||
*/ |
||||
it("getValue", function () { |
||||
var iconTextIconNode = BI.Test.createWidget({ |
||||
type: "bi.icon_text_icon_node", |
||||
value: "AAA" |
||||
}); |
||||
expect(iconTextIconNode.getValue()).to.equal("AAA"); |
||||
iconTextIconNode.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_kobi |
||||
*/ |
||||
it("doRedMark和unRedMark", function () { |
||||
var iconTextIconNode = BI.Test.createWidget({ |
||||
type: "bi.icon_text_icon_node", |
||||
text: "要标红的AAA", |
||||
}); |
||||
iconTextIconNode.doRedMark("AAA"); |
||||
expect(iconTextIconNode.element.find(".bi-keyword-red-mark").length).to.not.equal(0); |
||||
iconTextIconNode.unRedMark(); |
||||
expect(iconTextIconNode.element.find(".bi-keyword-red-mark").length).to.equal(0); |
||||
iconTextIconNode.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_kobi |
||||
*/ |
||||
it("Click点击触发事件", function (done) { |
||||
var iconTextIconNode = BI.Test.createWidget({ |
||||
type: "bi.icon_text_icon_node", |
||||
text: "AAA", |
||||
handler: function () { |
||||
this.setText("click"); |
||||
} |
||||
}); |
||||
BI.nextTick(function () { |
||||
iconTextIconNode.element.click(); |
||||
expect(iconTextIconNode.element.find(".bi-text").text()).to.equal("click"); |
||||
iconTextIconNode.destroy(); |
||||
done(); |
||||
}); |
||||
}); |
||||
|
||||
}); |
@ -0,0 +1,104 @@
|
||||
/** |
||||
* @author Kobi |
||||
* @date 2020/4/21 |
||||
*/ |
||||
|
||||
describe("IconTextNodeTest", function () { |
||||
|
||||
/** |
||||
* test_author_kobi |
||||
*/ |
||||
it("setText", function () { |
||||
var iconTextNode = BI.Test.createWidget({ |
||||
type: "bi.icon_text_node" |
||||
}); |
||||
iconTextNode.setText("AAA"); |
||||
expect(iconTextNode.element.find(".bi-text").text()).to.equal("AAA"); |
||||
iconTextNode.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_kobi |
||||
*/ |
||||
it("getText", function () { |
||||
var iconTextNode = BI.Test.createWidget({ |
||||
type: "bi.icon_text_node", |
||||
text: "AAA", |
||||
}); |
||||
expect(iconTextNode.getText()).to.equal("AAA"); |
||||
iconTextNode.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_kobi |
||||
*/ |
||||
it("setValue", function () { |
||||
var iconTextNode = BI.Test.createWidget({ |
||||
type: "bi.icon_text_node" |
||||
}); |
||||
iconTextNode.setValue("AAA"); |
||||
expect(iconTextNode.element.find(".bi-text").text()).to.equal("AAA"); |
||||
iconTextNode.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_kobi |
||||
*/ |
||||
it("readonly下的setValue", function () { |
||||
var iconTextNode = BI.Test.createWidget({ |
||||
type: "bi.icon_text_node", |
||||
value: "AAA", |
||||
readonly: true |
||||
}); |
||||
iconTextNode.setValue("BBB"); |
||||
expect(iconTextNode.element.find(".bi-text").text()).to.equal("AAA"); |
||||
iconTextNode.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_kobi |
||||
*/ |
||||
it("getValue", function () { |
||||
var iconTextNode = BI.Test.createWidget({ |
||||
type: "bi.icon_text_node", |
||||
value: "AAA" |
||||
}); |
||||
expect(iconTextNode.getValue()).to.equal("AAA"); |
||||
iconTextNode.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_kobi |
||||
*/ |
||||
it("doRedMark和unRedMark", function () { |
||||
var iconTextNode = BI.Test.createWidget({ |
||||
type: "bi.icon_text_node", |
||||
text: "要标红的AAA", |
||||
}); |
||||
iconTextNode.doRedMark("AAA"); |
||||
expect(iconTextNode.element.find(".bi-keyword-red-mark").length).to.not.equal(0); |
||||
iconTextNode.unRedMark(); |
||||
expect(iconTextNode.element.find(".bi-keyword-red-mark").length).to.equal(0); |
||||
iconTextNode.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_kobi |
||||
*/ |
||||
it("Click点击触发事件", function (done) { |
||||
var iconTextNode = BI.Test.createWidget({ |
||||
type: "bi.icon_text_node", |
||||
text: "AAA", |
||||
handler: function () { |
||||
this.setText("click"); |
||||
} |
||||
}); |
||||
BI.nextTick(function () { |
||||
iconTextNode.element.click(); |
||||
expect(iconTextNode.element.find(".bi-text").text()).to.equal("click"); |
||||
iconTextNode.destroy(); |
||||
done(); |
||||
}); |
||||
}); |
||||
|
||||
}); |
@ -0,0 +1,104 @@
|
||||
/** |
||||
* @author Kobi |
||||
* @date 2020/4/21 |
||||
*/ |
||||
|
||||
describe("TextIconNodeTest", function () { |
||||
|
||||
/** |
||||
* test_author_kobi |
||||
*/ |
||||
it("setText", function () { |
||||
var textIconNode = BI.Test.createWidget({ |
||||
type: "bi.text_icon_node" |
||||
}); |
||||
textIconNode.setText("AAA"); |
||||
expect(textIconNode.element.find(".bi-text").text()).to.equal("AAA"); |
||||
textIconNode.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_kobi |
||||
*/ |
||||
it("getText", function () { |
||||
var textIconNode = BI.Test.createWidget({ |
||||
type: "bi.text_icon_node", |
||||
text: "AAA", |
||||
}); |
||||
expect(textIconNode.getText()).to.equal("AAA"); |
||||
textIconNode.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_kobi |
||||
*/ |
||||
it("setValue", function () { |
||||
var textIconNode = BI.Test.createWidget({ |
||||
type: "bi.text_icon_node" |
||||
}); |
||||
textIconNode.setValue("AAA"); |
||||
expect(textIconNode.element.find(".bi-text").text()).to.equal("AAA"); |
||||
textIconNode.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_kobi |
||||
*/ |
||||
it("readonly下的setValue", function () { |
||||
var textIconNode = BI.Test.createWidget({ |
||||
type: "bi.text_icon_node", |
||||
value: "AAA", |
||||
readonly: true |
||||
}); |
||||
textIconNode.setValue("BBB"); |
||||
expect(textIconNode.element.find(".bi-text").text()).to.equal("AAA"); |
||||
textIconNode.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_kobi |
||||
*/ |
||||
it("getValue", function () { |
||||
var textIconNode = BI.Test.createWidget({ |
||||
type: "bi.text_icon_node", |
||||
value: "AAA" |
||||
}); |
||||
expect(textIconNode.getValue()).to.equal("AAA"); |
||||
textIconNode.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_kobi |
||||
*/ |
||||
it("doRedMark和unRedMark", function () { |
||||
var textIconNode = BI.Test.createWidget({ |
||||
type: "bi.text_icon_node", |
||||
text: "要标红的AAA", |
||||
}); |
||||
textIconNode.doRedMark("AAA"); |
||||
expect(textIconNode.element.find(".bi-keyword-red-mark").length).to.not.equal(0); |
||||
textIconNode.unRedMark(); |
||||
expect(textIconNode.element.find(".bi-keyword-red-mark").length).to.equal(0); |
||||
textIconNode.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_kobi |
||||
*/ |
||||
it("Click点击触发事件", function (done) { |
||||
var textIconNode = BI.Test.createWidget({ |
||||
type: "bi.text_icon_node", |
||||
text: "AAA", |
||||
handler: function () { |
||||
this.setText("click"); |
||||
} |
||||
}); |
||||
BI.nextTick(function () { |
||||
textIconNode.element.click(); |
||||
expect(textIconNode.element.find(".bi-text").text()).to.equal("click"); |
||||
textIconNode.destroy(); |
||||
done(); |
||||
}); |
||||
}); |
||||
|
||||
}); |
@ -0,0 +1,106 @@
|
||||
/** |
||||
* @author Kobi |
||||
* @date 2020/4/21 |
||||
*/ |
||||
|
||||
describe("TextNodeTest", function () { |
||||
|
||||
/** |
||||
* test_author_kobi |
||||
*/ |
||||
it("setText", function () { |
||||
var textNode = BI.Test.createWidget({ |
||||
type: "bi.text_node" |
||||
}); |
||||
textNode.setText("AAA"); |
||||
expect(textNode.element.children(".bi-text").text()).to.equal("AAA"); |
||||
textNode.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_kobi |
||||
*/ |
||||
it("getText", function () { |
||||
var textNode = BI.Test.createWidget({ |
||||
type: "bi.text_node", |
||||
text: "AAA", |
||||
whiteSpace: "normal" |
||||
}); |
||||
expect(textNode.getText()).to.equal("AAA"); |
||||
textNode.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_kobi |
||||
*/ |
||||
it("setValue", function () { |
||||
var textNode = BI.Test.createWidget({ |
||||
type: "bi.text_node" |
||||
}); |
||||
textNode.setValue("AAA"); |
||||
expect(textNode.element.children(".bi-text").text()).to.equal("AAA"); |
||||
textNode.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_kobi |
||||
*/ |
||||
it("readonly下的setValue", function () { |
||||
var textNode = BI.Test.createWidget({ |
||||
type: "bi.text_node", |
||||
value: "AAA", |
||||
readonly: true |
||||
}); |
||||
textNode.setValue("BBB"); |
||||
expect(textNode.element.children(".bi-text").text()).to.equal("AAA"); |
||||
textNode.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_kobi |
||||
*/ |
||||
it("getValue", function () { |
||||
var textNode = BI.Test.createWidget({ |
||||
type: "bi.text_node", |
||||
value: "AAA" |
||||
}); |
||||
expect(textNode.getValue()).to.equal("AAA"); |
||||
textNode.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_kobi |
||||
*/ |
||||
it("doRedMark和unRedMark", function () { |
||||
var textNode = BI.Test.createWidget({ |
||||
type: "bi.text_node", |
||||
text: "要标红的AAA", |
||||
}); |
||||
textNode.doRedMark("AAA"); |
||||
expect(textNode.element.find(".bi-keyword-red-mark").length).to.not.equal(0); |
||||
textNode.unRedMark(); |
||||
expect(textNode.element.find(".bi-keyword-red-mark").length).to.equal(0); |
||||
textNode.destroy(); |
||||
}); |
||||
|
||||
/** |
||||
* test_author_kobi |
||||
*/ |
||||
it("Click点击触发事件", function (done) { |
||||
var textNode = BI.Test.createWidget({ |
||||
type: "bi.text_node", |
||||
text: "AAA", |
||||
handler: function () { |
||||
this.setText("click"); |
||||
} |
||||
}); |
||||
BI.nextTick(function () { |
||||
textNode.element.click(); |
||||
expect(textNode.element.children(".bi-text").text()).to.equal("click"); |
||||
textNode.destroy(); |
||||
done(); |
||||
}); |
||||
}); |
||||
|
||||
|
||||
}); |
@ -0,0 +1,113 @@
|
||||
/** |
||||
* guy |
||||
* Created by GUY on 2015/9/9. |
||||
* @class BI.IconTextIconNode |
||||
* @extends BI.NodeButton |
||||
*/ |
||||
BI.IconTextIconNode = BI.inherit(BI.NodeButton, { |
||||
|
||||
_defaultConfig: function () { |
||||
var conf = BI.IconTextIconNode.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend(conf, { |
||||
baseCls: (conf.baseCls || "") + " bi-icon-text-icon-node", |
||||
logic: { |
||||
dynamic: false |
||||
}, |
||||
iconCls1: "close-ha-font", |
||||
iconCls2: "close-ha-font", |
||||
iconHeight: null, |
||||
iconWidth: null, |
||||
textHgap: 0, |
||||
textVgap: 0, |
||||
textLgap: 0, |
||||
textRgap: 0 |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var o = this.options, c = this._const; |
||||
this.text = BI.createWidget({ |
||||
type: "bi.label", |
||||
textAlign: "left", |
||||
hgap: o.textHgap, |
||||
vgap: o.textVgap, |
||||
lgap: o.textLgap, |
||||
rgap: o.textRgap, |
||||
text: o.text, |
||||
value: o.value, |
||||
keyword: o.keyword, |
||||
height: o.height |
||||
}); |
||||
|
||||
var icon1 = BI.createWidget({ |
||||
type: "bi.icon_label", |
||||
cls: o.iconCls1, |
||||
width: o.height, |
||||
height: o.height, |
||||
iconWidth: o.iconWidth, |
||||
iconHeight: o.iconHeight |
||||
}); |
||||
var blank = BI.createWidget({ |
||||
type: "bi.layout", |
||||
width: o.height, |
||||
height: o.height |
||||
}); |
||||
BI.createWidget({ |
||||
type: "bi.absolute", |
||||
element: this, |
||||
items: [{ |
||||
el: { |
||||
type: "bi.icon_label", |
||||
cls: o.iconCls2, |
||||
width: o.height, |
||||
iconWidth: o.iconWidth, |
||||
iconHeight: o.iconHeight |
||||
}, |
||||
top: 0, |
||||
bottom: 0, |
||||
right: 0 |
||||
}] |
||||
}); |
||||
|
||||
BI.createWidget(BI.extend({ |
||||
element: this |
||||
}, BI.LogicFactory.createLogic("horizontal", BI.extend(o.logic, { |
||||
items: BI.LogicFactory.createLogicItemsByDirection("left", icon1, this.text, blank) |
||||
})))); |
||||
}, |
||||
|
||||
doClick: function () { |
||||
BI.IconTextIconNode.superclass.doClick.apply(this, arguments); |
||||
if (this.isValid()) { |
||||
this.fireEvent(BI.IconTextIconNode.EVENT_CHANGE, this.getValue(), this); |
||||
} |
||||
}, |
||||
|
||||
doRedMark: function () { |
||||
this.text.doRedMark.apply(this.text, arguments); |
||||
}, |
||||
|
||||
unRedMark: function () { |
||||
this.text.unRedMark.apply(this.text, arguments); |
||||
}, |
||||
|
||||
setValue: function () { |
||||
if (!this.isReadOnly()) { |
||||
this.text.setValue.apply(this.text, arguments); |
||||
} |
||||
}, |
||||
|
||||
getValue: function () { |
||||
return this.text.getValue(); |
||||
}, |
||||
|
||||
setText: function () { |
||||
this.text.setText.apply(this.text, arguments); |
||||
}, |
||||
|
||||
getText: function () { |
||||
return this.text.getText(); |
||||
} |
||||
}); |
||||
BI.IconTextIconNode.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
BI.shortcut("bi.icon_text_icon_node", BI.IconTextIconNode); |
@ -0,0 +1,90 @@
|
||||
/** |
||||
* guy |
||||
* Created by GUY on 2015/9/9. |
||||
* @class BI.IconTextNode |
||||
* @extends BI.NodeButton |
||||
*/ |
||||
BI.IconTextNode = BI.inherit(BI.NodeButton, { |
||||
|
||||
_defaultConfig: function () { |
||||
var conf = BI.IconTextNode.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend(conf, { |
||||
baseCls: (conf.baseCls || "") + " bi-icon-text-node", |
||||
logic: { |
||||
dynamic: false |
||||
}, |
||||
cls: "close-ha-font", |
||||
iconHeight: null, |
||||
iconWidth: null, |
||||
textHgap: 0, |
||||
textVgap: 0, |
||||
textLgap: 0, |
||||
textRgap: 0 |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var o = this.options, c = this._const; |
||||
this.text = BI.createWidget({ |
||||
type: "bi.label", |
||||
cls: "list-item-text", |
||||
textAlign: "left", |
||||
hgap: o.textHgap, |
||||
vgap: o.textVgap, |
||||
lgap: o.textLgap, |
||||
rgap: o.textRgap, |
||||
text: o.text, |
||||
value: o.value, |
||||
keyword: o.keyword, |
||||
height: o.height |
||||
}); |
||||
this.icon = BI.createWidget({ |
||||
type: "bi.icon_label", |
||||
width: o.height, |
||||
height: o.height, |
||||
iconWidth: o.iconWidth, |
||||
iconHeight: o.iconHeight |
||||
}); |
||||
|
||||
BI.createWidget(BI.extend({ |
||||
element: this |
||||
}, BI.LogicFactory.createLogic("horizontal", BI.extend(o.logic, { |
||||
items: BI.LogicFactory.createLogicItemsByDirection("left", this.icon, this.text) |
||||
})))); |
||||
}, |
||||
|
||||
setValue: function () { |
||||
if (!this.isReadOnly()) { |
||||
this.text.setValue.apply(this.text, arguments); |
||||
} |
||||
}, |
||||
|
||||
getValue: function () { |
||||
return this.text.getValue(); |
||||
}, |
||||
|
||||
setText: function () { |
||||
this.text.setText.apply(this.text, arguments); |
||||
}, |
||||
|
||||
getText: function () { |
||||
return this.text.getText(); |
||||
}, |
||||
|
||||
doClick: function () { |
||||
BI.IconTextNode.superclass.doClick.apply(this, arguments); |
||||
if (this.isValid()) { |
||||
this.fireEvent(BI.IconTextNode.EVENT_CHANGE, this.getValue(), this); |
||||
} |
||||
}, |
||||
|
||||
doRedMark: function () { |
||||
this.text.doRedMark.apply(this.text, arguments); |
||||
}, |
||||
|
||||
unRedMark: function () { |
||||
this.text.unRedMark.apply(this.text, arguments); |
||||
} |
||||
}); |
||||
BI.IconTextNode.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
BI.shortcut("bi.icon_text_node", BI.IconTextNode); |
@ -0,0 +1,89 @@
|
||||
/** |
||||
* Created by GUY on 2015/9/9. |
||||
* @class BI.TextIconNode |
||||
* @extends BI.NodeButton |
||||
*/ |
||||
BI.TextIconNode = BI.inherit(BI.NodeButton, { |
||||
|
||||
_defaultConfig: function () { |
||||
var conf = BI.TextIconNode.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend(conf, { |
||||
baseCls: (conf.baseCls || "") + " bi-text-icon-node", |
||||
logic: { |
||||
dynamic: false |
||||
}, |
||||
cls: "close-ha-font", |
||||
iconHeight: null, |
||||
iconWidth: null, |
||||
textHgap: 0, |
||||
textVgap: 0, |
||||
textLgap: 0, |
||||
textRgap: 0 |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var o = this.options, c = this._const; |
||||
this.text = BI.createWidget({ |
||||
type: "bi.label", |
||||
cls: "list-item-text", |
||||
textAlign: "left", |
||||
hgap: o.textHgap, |
||||
vgap: o.textVgap, |
||||
lgap: o.textLgap, |
||||
rgap: o.textRgap, |
||||
text: o.text, |
||||
value: o.value, |
||||
keyword: o.keyword, |
||||
height: o.height |
||||
}); |
||||
this.icon = BI.createWidget({ |
||||
type: "bi.icon_label", |
||||
width: o.height, |
||||
height: o.height, |
||||
iconWidth: o.iconWidth, |
||||
iconHeight: o.iconHeight |
||||
}); |
||||
|
||||
BI.createWidget(BI.extend({ |
||||
element: this |
||||
}, BI.LogicFactory.createLogic("horizontal", BI.extend(o.logic, { |
||||
items: BI.LogicFactory.createLogicItemsByDirection("left", this.text, this.icon) |
||||
})))); |
||||
}, |
||||
|
||||
doClick: function () { |
||||
BI.TextIconNode.superclass.doClick.apply(this, arguments); |
||||
if (this.isValid()) { |
||||
this.fireEvent(BI.TextIconNode.EVENT_CHANGE, this.getValue(), this); |
||||
} |
||||
}, |
||||
|
||||
setValue: function () { |
||||
if (!this.isReadOnly()) { |
||||
this.text.setValue.apply(this.text, arguments); |
||||
} |
||||
}, |
||||
|
||||
getValue: function () { |
||||
return this.text.getValue(); |
||||
}, |
||||
|
||||
setText: function () { |
||||
this.text.setText.apply(this.text, arguments); |
||||
}, |
||||
|
||||
getText: function () { |
||||
return this.text.getText(); |
||||
}, |
||||
|
||||
doRedMark: function () { |
||||
this.text.doRedMark.apply(this.text, arguments); |
||||
}, |
||||
|
||||
unRedMark: function () { |
||||
this.text.unRedMark.apply(this.text, arguments); |
||||
} |
||||
}); |
||||
BI.TextIconNode.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
BI.shortcut("bi.text_icon_node", BI.TextIconNode); |
@ -0,0 +1,77 @@
|
||||
/** |
||||
* guy |
||||
* |
||||
* Created by GUY on 2015/9/9. |
||||
* @class BI.TextNode |
||||
* @extends BI.NodeButton |
||||
*/ |
||||
BI.TextNode = BI.inherit(BI.NodeButton, { |
||||
|
||||
_defaultConfig: function () { |
||||
var conf = BI.TextNode.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend(conf, { |
||||
baseCls: (conf.baseCls || "") + " bi-text-node", |
||||
textAlign: "left", |
||||
whiteSpace: "nowrap", |
||||
textHgap: 0, |
||||
textVgap: 0, |
||||
textLgap: 0, |
||||
textRgap: 0 |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var o = this.options; |
||||
this.text = BI.createWidget({ |
||||
type: "bi.label", |
||||
element: this, |
||||
textAlign: o.textAlign, |
||||
whiteSpace: o.whiteSpace, |
||||
textHeight: o.whiteSpace == "nowrap" ? o.height : o.textHeight, |
||||
height: o.height, |
||||
hgap: o.textHgap, |
||||
vgap: o.textVgap, |
||||
lgap: o.textLgap, |
||||
rgap: o.textRgap, |
||||
text: o.text, |
||||
value: o.value, |
||||
keyword: o.keyword, |
||||
py: o.py |
||||
}); |
||||
}, |
||||
|
||||
doClick: function () { |
||||
BI.TextNode.superclass.doClick.apply(this, arguments); |
||||
if (this.isValid()) { |
||||
this.fireEvent(BI.TextNode.EVENT_CHANGE, this.getValue(), this); |
||||
} |
||||
}, |
||||
|
||||
doRedMark: function () { |
||||
this.text.doRedMark.apply(this.text, arguments); |
||||
}, |
||||
|
||||
unRedMark: function () { |
||||
this.text.unRedMark.apply(this.text, arguments); |
||||
}, |
||||
|
||||
setValue: function () { |
||||
if (!this.isReadOnly()) { |
||||
this.text.setValue.apply(this.text, arguments); |
||||
} |
||||
}, |
||||
|
||||
getValue: function () { |
||||
return this.text.getValue(); |
||||
}, |
||||
|
||||
setText: function () { |
||||
this.text.setText.apply(this.text, arguments); |
||||
}, |
||||
|
||||
getText: function () { |
||||
return this.text.getText(); |
||||
} |
||||
}); |
||||
BI.TextNode.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
BI.shortcut("bi.text_node", BI.TextNode); |
@ -0,0 +1,370 @@
|
||||
/** |
||||
* Created by GUY on 2015/4/15. |
||||
* @class BI.Editor |
||||
* @extends BI.Single |
||||
*/ |
||||
BI.Editor = BI.inherit(BI.Single, { |
||||
_defaultConfig: function () { |
||||
var conf = BI.Editor.superclass._defaultConfig.apply(this, arguments); |
||||
|
||||
return BI.extend(conf, { |
||||
baseCls: "bi-editor bi-focus-shadow", |
||||
hgap: 4, |
||||
vgap: 2, |
||||
lgap: 0, |
||||
rgap: 0, |
||||
tgap: 0, |
||||
bgap: 0, |
||||
// title,warningTitle这两个属性没用
|
||||
tipType: "warning", |
||||
inputType: "text", |
||||
validationChecker: BI.emptyFn, |
||||
quitChecker: BI.emptyFn, |
||||
allowBlank: false, |
||||
watermark: "", |
||||
errorText: "", |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var self = this, o = this.options; |
||||
// 密码输入框设置autocomplete="new-password"的情况下Firefox和chrome不会自动填充密码
|
||||
var autocomplete = o.autocomplete ? " autocomplete=" + o.autocomplete : ""; |
||||
this.editor = this.addWidget(BI.createWidget({ |
||||
type: "bi.input", |
||||
element: "<input type='" + o.inputType + "'" + autocomplete + " />", |
||||
root: true, |
||||
value: o.value, |
||||
watermark: o.watermark, |
||||
validationChecker: o.validationChecker, |
||||
quitChecker: o.quitChecker, |
||||
allowBlank: o.allowBlank |
||||
})); |
||||
this.editor.element.css({ |
||||
width: "100%", |
||||
height: "100%", |
||||
border: "none", |
||||
outline: "none", |
||||
padding: "0", |
||||
margin: "0" |
||||
}); |
||||
|
||||
var items = [{ |
||||
el: { |
||||
type: "bi.absolute", |
||||
ref: function (_ref) { |
||||
self.contentWrapper = _ref; |
||||
}, |
||||
items: [{ |
||||
el: this.editor, |
||||
left: 0, |
||||
right: 0, |
||||
top: 0, |
||||
bottom: 0 |
||||
}] |
||||
}, |
||||
left: o.hgap + o.lgap, |
||||
right: o.hgap + o.rgap, |
||||
top: o.vgap + o.tgap, |
||||
bottom: o.vgap + o.bgap |
||||
}]; |
||||
|
||||
BI.createWidget({ |
||||
type: "bi.absolute", |
||||
element: this, |
||||
items: items |
||||
}); |
||||
|
||||
this.setWaterMark(this.options.watermark); |
||||
|
||||
this.editor.on(BI.Controller.EVENT_CHANGE, function () { |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); |
||||
}); |
||||
this.editor.on(BI.Input.EVENT_FOCUS, function () { |
||||
self._checkError(); |
||||
self.element.addClass("bi-editor-focus"); |
||||
self.fireEvent(BI.Editor.EVENT_FOCUS, arguments); |
||||
}); |
||||
this.editor.on(BI.Input.EVENT_BLUR, function () { |
||||
self._setErrorVisible(false); |
||||
self.element.removeClass("bi-editor-focus"); |
||||
self.fireEvent(BI.Editor.EVENT_BLUR, arguments); |
||||
}); |
||||
this.editor.on(BI.Input.EVENT_CLICK, function () { |
||||
self.fireEvent(BI.Editor.EVENT_CLICK, arguments); |
||||
}); |
||||
this.editor.on(BI.Input.EVENT_CHANGE, function () { |
||||
self.fireEvent(BI.Editor.EVENT_CHANGE, arguments); |
||||
}); |
||||
this.editor.on(BI.Input.EVENT_KEY_DOWN, function (v) { |
||||
self.fireEvent(BI.Editor.EVENT_KEY_DOWN, arguments); |
||||
}); |
||||
this.editor.on(BI.Input.EVENT_QUICK_DOWN, function (e) { |
||||
// tab键就不要隐藏了
|
||||
if (e.keyCode !== BI.KeyCode.TAB && self.watermark) { |
||||
self.watermark.invisible(); |
||||
} |
||||
}); |
||||
|
||||
this.editor.on(BI.Input.EVENT_VALID, function () { |
||||
self._checkWaterMark(); |
||||
self._setErrorVisible(false); |
||||
self.fireEvent(BI.Editor.EVENT_VALID, arguments); |
||||
}); |
||||
this.editor.on(BI.Input.EVENT_ERROR, function () { |
||||
self._checkWaterMark(); |
||||
self.fireEvent(BI.Editor.EVENT_ERROR, arguments); |
||||
self._setErrorVisible(self.isEditing()); |
||||
}); |
||||
this.editor.on(BI.Input.EVENT_RESTRICT, function () { |
||||
self._checkWaterMark(); |
||||
var tip = self._setErrorVisible(true); |
||||
tip && tip.element.fadeOut(100, function () { |
||||
tip.element.fadeIn(100); |
||||
}); |
||||
self.fireEvent(BI.Editor.EVENT_RESTRICT, arguments); |
||||
}); |
||||
this.editor.on(BI.Input.EVENT_EMPTY, function () { |
||||
self._checkWaterMark(); |
||||
self.fireEvent(BI.Editor.EVENT_EMPTY, arguments); |
||||
}); |
||||
this.editor.on(BI.Input.EVENT_ENTER, function () { |
||||
self.fireEvent(BI.Editor.EVENT_ENTER, arguments); |
||||
}); |
||||
this.editor.on(BI.Input.EVENT_SPACE, function () { |
||||
self.fireEvent(BI.Editor.EVENT_SPACE, arguments); |
||||
}); |
||||
this.editor.on(BI.Input.EVENT_BACKSPACE, function () { |
||||
self.fireEvent(BI.Editor.EVENT_BACKSPACE, arguments); |
||||
}); |
||||
this.editor.on(BI.Input.EVENT_REMOVE, function () { |
||||
self.fireEvent(BI.Editor.EVENT_REMOVE, arguments); |
||||
}); |
||||
this.editor.on(BI.Input.EVENT_START, function () { |
||||
self.fireEvent(BI.Editor.EVENT_START, arguments); |
||||
}); |
||||
this.editor.on(BI.Input.EVENT_PAUSE, function () { |
||||
self.fireEvent(BI.Editor.EVENT_PAUSE, arguments); |
||||
}); |
||||
this.editor.on(BI.Input.EVENT_STOP, function () { |
||||
self.fireEvent(BI.Editor.EVENT_STOP, arguments); |
||||
}); |
||||
this.editor.on(BI.Input.EVENT_CONFIRM, function () { |
||||
self.fireEvent(BI.Editor.EVENT_CONFIRM, arguments); |
||||
}); |
||||
this.editor.on(BI.Input.EVENT_CHANGE_CONFIRM, function () { |
||||
self.fireEvent(BI.Editor.EVENT_CHANGE_CONFIRM, arguments); |
||||
}); |
||||
this.element.click(function (e) { |
||||
e.stopPropagation(); |
||||
return false; |
||||
}); |
||||
if (BI.isKey(this.options.value) || BI.isEmptyString(this.options.value)) { |
||||
this._checkError(); |
||||
this._checkWaterMark(); |
||||
} else { |
||||
this._checkWaterMark(); |
||||
} |
||||
}, |
||||
|
||||
_checkToolTip: function () { |
||||
var o = this.options; |
||||
var errorText = o.errorText; |
||||
if (BI.isFunction(errorText)) { |
||||
errorText = errorText(this.editor.getValue()); |
||||
} |
||||
if (BI.isKey(errorText)) { |
||||
if (!this.isEnabled() || this.isValid() || BI.Bubbles.has(this.getName())) { |
||||
this.setTitle(""); |
||||
} else { |
||||
this.setTitle(errorText); |
||||
} |
||||
} |
||||
}, |
||||
|
||||
_assertWaterMark: function () { |
||||
var self = this, o = this.options; |
||||
if (BI.isNull(this.watermark)) { |
||||
this.watermark = BI.createWidget({ |
||||
type: "bi.label", |
||||
cls: "bi-water-mark", |
||||
text: this.options.watermark, |
||||
height: o.height - 2 * o.vgap - o.tgap, |
||||
hgap: 2, |
||||
whiteSpace: "nowrap", |
||||
textAlign: "left" |
||||
}); |
||||
this.watermark.element.bind({ |
||||
mousedown: function (e) { |
||||
if (self.isEnabled()) { |
||||
self.editor.isEditing() || self.editor.focus(); |
||||
} else { |
||||
self.editor.isEditing() && self.editor.blur(); |
||||
} |
||||
e.stopEvent(); |
||||
} |
||||
}); |
||||
this.watermark.element.bind("click", function (e) { |
||||
if (self.isEnabled()) { |
||||
self.editor.isEditing() || self.editor.focus(); |
||||
} else { |
||||
self.editor.isEditing() && self.editor.blur(); |
||||
} |
||||
e.stopEvent(); |
||||
}); |
||||
} |
||||
}, |
||||
|
||||
_checkError: function () { |
||||
this._setErrorVisible(this.isEnabled() && !this.isValid()); |
||||
this._checkToolTip(); |
||||
}, |
||||
|
||||
_checkWaterMark: function () { |
||||
var o = this.options; |
||||
if (!this.disabledWaterMark && this.editor.getValue() === "" && BI.isKey(o.watermark)) { |
||||
this.watermark && this.watermark.visible(); |
||||
} else { |
||||
this.watermark && this.watermark.invisible(); |
||||
} |
||||
}, |
||||
|
||||
setErrorText: function (text) { |
||||
this.options.errorText = text; |
||||
}, |
||||
|
||||
getErrorText: function () { |
||||
return this.options.errorText; |
||||
}, |
||||
|
||||
setWaterMark: function (v) { |
||||
if (!BI.isKey(v)) { |
||||
return; |
||||
} |
||||
|
||||
this.options.watermark = v; |
||||
|
||||
if (BI.isNull(this.watermark)) { |
||||
this._assertWaterMark(); |
||||
BI.createWidget({ |
||||
type: "bi.absolute", |
||||
element: this.contentWrapper, |
||||
items: [{ |
||||
el: this.watermark, |
||||
left: 0, |
||||
right: 0, |
||||
top: 0, |
||||
bottom: 0, |
||||
}], |
||||
}); |
||||
} |
||||
this.watermark.setText(v); |
||||
}, |
||||
|
||||
_setErrorVisible: function (b) { |
||||
var o = this.options; |
||||
var errorText = o.errorText; |
||||
if (BI.isFunction(errorText)) { |
||||
errorText = errorText(BI.trim(this.editor.getValue())); |
||||
} |
||||
if (!this.disabledError && BI.isKey(errorText)) { |
||||
BI.Bubbles[b ? "show" : "hide"](this.getName(), errorText, this, { |
||||
adjustYOffset: 2 |
||||
}); |
||||
this._checkToolTip(); |
||||
} |
||||
}, |
||||
|
||||
disableError: function () { |
||||
this.disabledError = true; |
||||
this._checkError(); |
||||
}, |
||||
|
||||
enableError: function () { |
||||
this.disabledError = false; |
||||
this._checkError(); |
||||
}, |
||||
|
||||
disableWaterMark: function () { |
||||
this.disabledWaterMark = true; |
||||
this._checkWaterMark(); |
||||
}, |
||||
|
||||
enableWaterMark: function () { |
||||
this.disabledWaterMark = false; |
||||
this._checkWaterMark(); |
||||
}, |
||||
|
||||
focus: function () { |
||||
this.element.addClass("text-editor-focus"); |
||||
this.editor.focus(); |
||||
}, |
||||
|
||||
blur: function () { |
||||
this.element.removeClass("text-editor-focus"); |
||||
this.editor.blur(); |
||||
}, |
||||
|
||||
selectAll: function () { |
||||
this.editor.selectAll(); |
||||
}, |
||||
|
||||
onKeyDown: function (k) { |
||||
this.editor.onKeyDown(k); |
||||
}, |
||||
|
||||
setValue: function (v) { |
||||
BI.Editor.superclass.setValue.apply(this, arguments); |
||||
this.editor.setValue(v); |
||||
this._checkError(); |
||||
this._checkWaterMark(); |
||||
}, |
||||
|
||||
getLastValidValue: function () { |
||||
return this.editor.getLastValidValue(); |
||||
}, |
||||
|
||||
getLastChangedValue: function () { |
||||
return this.editor.getLastChangedValue(); |
||||
}, |
||||
|
||||
getValue: function () { |
||||
if (!this.isValid()) { |
||||
return BI.trim(this.editor.getLastValidValue()); |
||||
} |
||||
return BI.trim(this.editor.getValue()); |
||||
}, |
||||
|
||||
isEditing: function () { |
||||
return this.editor.isEditing(); |
||||
}, |
||||
|
||||
isValid: function () { |
||||
return this.editor.isValid(); |
||||
}, |
||||
|
||||
destroyed: function () { |
||||
BI.Bubbles.remove(this.getName()); |
||||
} |
||||
}); |
||||
BI.Editor.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
BI.Editor.EVENT_FOCUS = "EVENT_FOCUS"; |
||||
BI.Editor.EVENT_BLUR = "EVENT_BLUR"; |
||||
BI.Editor.EVENT_CLICK = "EVENT_CLICK"; |
||||
BI.Editor.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; |
||||
BI.Editor.EVENT_SPACE = "EVENT_SPACE"; |
||||
BI.Editor.EVENT_BACKSPACE = "EVENT_BACKSPACE"; |
||||
|
||||
BI.Editor.EVENT_START = "EVENT_START"; |
||||
BI.Editor.EVENT_PAUSE = "EVENT_PAUSE"; |
||||
BI.Editor.EVENT_STOP = "EVENT_STOP"; |
||||
BI.Editor.EVENT_CONFIRM = "EVENT_CONFIRM"; |
||||
BI.Editor.EVENT_CHANGE_CONFIRM = "EVENT_CHANGE_CONFIRM"; |
||||
BI.Editor.EVENT_VALID = "EVENT_VALID"; |
||||
BI.Editor.EVENT_ERROR = "EVENT_ERROR"; |
||||
BI.Editor.EVENT_ENTER = "EVENT_ENTER"; |
||||
BI.Editor.EVENT_RESTRICT = "EVENT_RESTRICT"; |
||||
BI.Editor.EVENT_REMOVE = "EVENT_REMOVE"; |
||||
BI.Editor.EVENT_EMPTY = "EVENT_EMPTY"; |
||||
|
||||
BI.shortcut("bi.editor", BI.Editor); |
@ -0,0 +1,99 @@
|
||||
/** |
||||
* 多文件 |
||||
* |
||||
* Created by GUY on 2016/4/13. |
||||
* @class BI.MultifileEditor |
||||
* @extends BI.Single |
||||
* @abstract |
||||
*/ |
||||
BI.MultifileEditor = BI.inherit(BI.Widget, { |
||||
_defaultConfig: function () { |
||||
var conf = BI.MultifileEditor.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend(conf, { |
||||
baseCls: (conf.baseCls || "") + " bi-multifile-editor", |
||||
multiple: false, |
||||
maxSize: -1, // 1024 * 1024
|
||||
accept: "", |
||||
url: "" |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var self = this, o = this.options; |
||||
this.file = BI.createWidget({ |
||||
type: "bi.file", |
||||
cls: "multifile-editor", |
||||
width: "100%", |
||||
height: "100%", |
||||
name: o.name, |
||||
url: o.url, |
||||
multiple: o.multiple, |
||||
accept: o.accept, |
||||
maxSize: o.maxSize, |
||||
maxLength: o.maxLength, |
||||
title: o.title |
||||
}); |
||||
this.file.on(BI.File.EVENT_CHANGE, function () { |
||||
self.fireEvent(BI.MultifileEditor.EVENT_CHANGE, arguments); |
||||
}); |
||||
this.file.on(BI.File.EVENT_UPLOADSTART, function () { |
||||
self.fireEvent(BI.MultifileEditor.EVENT_UPLOADSTART, arguments); |
||||
}); |
||||
this.file.on(BI.File.EVENT_ERROR, function () { |
||||
self.fireEvent(BI.MultifileEditor.EVENT_ERROR, arguments); |
||||
}); |
||||
this.file.on(BI.File.EVENT_PROGRESS, function () { |
||||
self.fireEvent(BI.MultifileEditor.EVENT_PROGRESS, arguments); |
||||
}); |
||||
this.file.on(BI.File.EVENT_UPLOADED, function () { |
||||
self.fireEvent(BI.MultifileEditor.EVENT_UPLOADED, arguments); |
||||
}); |
||||
|
||||
BI.createWidget({ |
||||
type: "bi.absolute", |
||||
element: this, |
||||
items: [{ |
||||
el: { |
||||
type: "bi.adaptive", |
||||
scrollable: false, |
||||
items: [this.file] |
||||
}, |
||||
top: 0, |
||||
right: 0, |
||||
left: 0, |
||||
bottom: 0 |
||||
}] |
||||
}); |
||||
}, |
||||
|
||||
_reset: function () { |
||||
this.file.reset(); |
||||
}, |
||||
|
||||
setMaxFileLength: function (v) { |
||||
this.file.setMaxFileLength(v); |
||||
}, |
||||
|
||||
select: function () { |
||||
this.file.select(); |
||||
}, |
||||
|
||||
getValue: function () { |
||||
return this.file.getValue(); |
||||
}, |
||||
|
||||
upload: function () { |
||||
this._reset(); |
||||
this.file.upload(); |
||||
}, |
||||
|
||||
reset: function () { |
||||
this._reset(); |
||||
} |
||||
}); |
||||
BI.MultifileEditor.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
BI.MultifileEditor.EVENT_UPLOADSTART = "EVENT_UPLOADSTART"; |
||||
BI.MultifileEditor.EVENT_ERROR = "EVENT_ERROR"; |
||||
BI.MultifileEditor.EVENT_PROGRESS = "EVENT_PROGRESS"; |
||||
BI.MultifileEditor.EVENT_UPLOADED = "EVENT_UPLOADED"; |
||||
BI.shortcut("bi.multifile_editor", BI.MultifileEditor); |
@ -0,0 +1,252 @@
|
||||
/** |
||||
* |
||||
* Created by GUY on 2016/1/18. |
||||
* @class BI.TextAreaEditor |
||||
* @extends BI.Single |
||||
*/ |
||||
BI.TextAreaEditor = BI.inherit(BI.Single, { |
||||
_defaultConfig: function () { |
||||
return BI.extend(BI.TextAreaEditor.superclass._defaultConfig.apply(), { |
||||
baseCls: "bi-textarea-editor", |
||||
value: "", |
||||
errorText: "", |
||||
adjustYOffset: 2, |
||||
adjustXOffset: 0, |
||||
offsetStyle: "left", |
||||
validationChecker: function () { |
||||
return true; |
||||
}, |
||||
scrolly: true, |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var o = this.options, self = this; |
||||
this.content = BI.createWidget({ |
||||
type: "bi.layout", |
||||
tagName: "textarea", |
||||
width: "100%", |
||||
height: "100%", |
||||
cls: "bi-textarea textarea-editor-content display-block", |
||||
css: o.scrolly ? null : { |
||||
overflowY: "hidden", |
||||
}, |
||||
}); |
||||
this.content.element.css({ resize: "none" }); |
||||
BI.createWidget({ |
||||
type: "bi.absolute", |
||||
element: this, |
||||
items: [{ |
||||
el: { |
||||
type: "bi.adaptive", |
||||
items: [this.content] |
||||
}, |
||||
left: 4, |
||||
right: 4, |
||||
top: 2, |
||||
bottom: 2 |
||||
}] |
||||
}); |
||||
|
||||
this.content.element.on("input propertychange", function (e) { |
||||
self._checkError(); |
||||
self._checkWaterMark(); |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.CHANGE, self.getValue(), self); |
||||
self.fireEvent(BI.TextAreaEditor.EVENT_CHANGE); |
||||
if (BI.isEmptyString(self.getValue())) { |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EMPTY, self.getValue(), self); |
||||
} |
||||
}); |
||||
|
||||
this.content.element.focus(function () { |
||||
self._checkError(); |
||||
self._focus(); |
||||
self.fireEvent(BI.TextAreaEditor.EVENT_FOCUS); |
||||
BI.Widget._renderEngine.createElement(document).bind("mousedown." + self.getName(), function (e) { |
||||
if (BI.DOM.isExist(self) && !self.element.__isMouseInBounds__(e)) { |
||||
BI.Widget._renderEngine.createElement(document).unbind("mousedown." + self.getName()); |
||||
self.content.element.blur(); |
||||
} |
||||
}); |
||||
}); |
||||
this.content.element.blur(function () { |
||||
self._setErrorVisible(false); |
||||
self._blur(); |
||||
if (!self._isError()) { |
||||
self.fireEvent(BI.TextAreaEditor.EVENT_CONFIRM); |
||||
} |
||||
self.fireEvent(BI.TextAreaEditor.EVENT_BLUR); |
||||
BI.Widget._renderEngine.createElement(document).unbind("mousedown." + self.getName()); |
||||
}); |
||||
this.content.element.keydown(function () { |
||||
// 水印快速消失
|
||||
self._checkWaterMark(); |
||||
}); |
||||
this.content.element.keyup(function (e) { |
||||
self.fireEvent(BI.TextAreaEditor.EVENT_KEY_DOWN, e.keyCode); |
||||
}); |
||||
this.content.element.click(function (e) { |
||||
e.stopPropagation(); |
||||
}); |
||||
if (BI.isKey(o.value)) { |
||||
this.setValue(o.value); |
||||
} |
||||
if (BI.isNotNull(o.style)) { |
||||
this.setStyle(o.style); |
||||
} |
||||
this._checkWaterMark(); |
||||
}, |
||||
|
||||
_checkWaterMark: function () { |
||||
var self = this, o = this.options; |
||||
var val = this.getValue(); |
||||
if (BI.isNotEmptyString(val)) { |
||||
this.watermark && this.watermark.destroy(); |
||||
this.watermark = null; |
||||
} else { |
||||
if (BI.isNotEmptyString(o.watermark)) { |
||||
if (!this.watermark) { |
||||
this.watermark = BI.createWidget({ |
||||
type: "bi.label", |
||||
cls: "bi-water-mark textarea-watermark", |
||||
textAlign: "left", |
||||
whiteSpace: o.scrolly ? "normal" : "nowrap", |
||||
title: o.watermark, |
||||
text: o.watermark, |
||||
invalid: o.invalid, |
||||
disabled: o.disabled, |
||||
hgap: 6, |
||||
vgap: o.height > 24 ? 4 : 2, |
||||
height: o.height > 24 ? "" : o.height, |
||||
}); |
||||
this.watermark.element.bind({ |
||||
mousedown: function (e) { |
||||
if (self.isEnabled()) { |
||||
self.focus(); |
||||
} else { |
||||
self.blur(); |
||||
} |
||||
e.stopEvent(); |
||||
}, |
||||
click: function (e) { |
||||
e.stopPropagation(); |
||||
}, |
||||
}); |
||||
BI.createWidget({ |
||||
type: "bi.absolute", |
||||
element: this, |
||||
items: [{ |
||||
el: this.watermark, |
||||
left: 0, |
||||
top: 0, |
||||
right: 0 |
||||
}] |
||||
}); |
||||
} else { |
||||
this.watermark.setText(o.watermark); |
||||
this.watermark.setValid(!o.invalid); |
||||
this.watermark.setEnable(!o.disabled); |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
|
||||
_isError: function () { |
||||
return this.isEnabled() && !this.options.validationChecker(this.getValue()); |
||||
}, |
||||
|
||||
_checkError: function () { |
||||
this._setErrorVisible(this._isError()); |
||||
}, |
||||
|
||||
_focus: function () { |
||||
this.content.element.addClass("textarea-editor-focus"); |
||||
this._checkWaterMark(); |
||||
if (BI.isEmptyString(this.getValue())) { |
||||
this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EMPTY, this.getValue(), this); |
||||
} |
||||
}, |
||||
|
||||
_blur: function () { |
||||
this.content.element.removeClass("textarea-editor-focus"); |
||||
this._checkWaterMark(); |
||||
}, |
||||
|
||||
_setErrorVisible: function (b) { |
||||
var o = this.options; |
||||
var errorText = o.errorText; |
||||
if (BI.isFunction(errorText)) { |
||||
errorText = errorText(BI.trim(this.getValue())); |
||||
} |
||||
if (!this.disabledError && BI.isKey(errorText)) { |
||||
BI.Bubbles[b ? "show" : "hide"](this.getName(), errorText, this, { |
||||
adjustYOffset: o.adjustYOffset, |
||||
adjustXOffset: o.adjustXOffset, |
||||
offsetStyle: o.offsetStyle, |
||||
}); |
||||
} |
||||
}, |
||||
|
||||
_defaultState: function () { |
||||
if (BI.isEmptyString(this.getValue())) { |
||||
this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EMPTY, this.getValue(), this); |
||||
this.fireEvent(BI.TextAreaEditor.EVENT_EMPTY); |
||||
} |
||||
}, |
||||
|
||||
focus: function () { |
||||
this._focus(); |
||||
this.content.element.focus(); |
||||
}, |
||||
|
||||
blur: function () { |
||||
this._blur(); |
||||
this.content.element.blur(); |
||||
}, |
||||
|
||||
getValue: function () { |
||||
return this.content.element.val(); |
||||
}, |
||||
|
||||
setValue: function (value) { |
||||
this.content.element.val(value); |
||||
this._checkError(); |
||||
this._checkWaterMark(); |
||||
this._defaultState(); |
||||
}, |
||||
|
||||
setStyle: function (style) { |
||||
this.style = style; |
||||
this.element.css(style); |
||||
this.content.element.css(BI.extend({}, style, { |
||||
color: style.color || BI.DOM.getContrastColor(BI.DOM.isRGBColor(style.backgroundColor) ? BI.DOM.rgb2hex(style.backgroundColor) : style.backgroundColor) |
||||
})); |
||||
}, |
||||
|
||||
getStyle: function () { |
||||
return this.style; |
||||
}, |
||||
|
||||
setWatermark: function (v) { |
||||
this.options.watermark = v; |
||||
this._checkWaterMark(); |
||||
}, |
||||
|
||||
_setValid: function (b) { |
||||
BI.TextAreaEditor.superclass._setValid.apply(this, arguments); |
||||
// this.content.setValid(b);
|
||||
// this.watermark && this.watermark.setValid(b);
|
||||
}, |
||||
|
||||
_setEnable: function (b) { |
||||
BI.TextAreaEditor.superclass._setEnable.apply(this, [b]); |
||||
this.content && (this.content.element[0].disabled = !b); |
||||
} |
||||
}); |
||||
BI.TextAreaEditor.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
BI.TextAreaEditor.EVENT_BLUR = "EVENT_BLUR"; |
||||
BI.TextAreaEditor.EVENT_FOCUS = "EVENT_FOCUS"; |
||||
BI.TextAreaEditor.EVENT_CONFIRM = "EVENT_CONFIRM"; |
||||
BI.TextAreaEditor.EVENT_EMPTY = "EVENT_EMPTY"; |
||||
BI.TextAreaEditor.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; |
||||
BI.shortcut("bi.textarea_editor", BI.TextAreaEditor); |
@ -0,0 +1,42 @@
|
||||
/** |
||||
* @author windy |
||||
* @version 2.0 |
||||
* Created by windy on 2020/3/10 |
||||
*/ |
||||
|
||||
describe("HtmlTest", function () { |
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("html_h1", function () { |
||||
var a = BI.Test.createWidget({ |
||||
type: "bi.html", |
||||
text: "<h1>在bi.html标签中使用html原生标签</h1>" |
||||
}); |
||||
expect(a.element.find("h1").length).to.equal(1); |
||||
a.destroy(); |
||||
}); |
||||
|
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("html测试属性方法", function () { |
||||
var a = BI.Test.createWidget({ |
||||
type: "bi.html", |
||||
text: "<h1>在bi.html标签中使用html原生标签</h1>", |
||||
height: 200, |
||||
width: 200, |
||||
value: "1", |
||||
highLight: true, |
||||
hgap: 10, |
||||
vgap: 10, |
||||
handler: BI.emptyFn |
||||
}); |
||||
a.setValue("DDDDD"); |
||||
a.setStyle({"background-color": "red"}); |
||||
expect(a.text.element.css("background-color")).to.equal("rgb(255, 0, 0)"); |
||||
a.destroy(); |
||||
}); |
||||
}); |
@ -0,0 +1,114 @@
|
||||
/** |
||||
* guy 表示一行数据,通过position来定位位置的数据 |
||||
* @class BI.Html |
||||
* @extends BI.Single |
||||
*/ |
||||
BI.Html = BI.inherit(BI.Single, { |
||||
|
||||
props: { |
||||
baseCls: "bi-html", |
||||
textAlign: "left", |
||||
whiteSpace: "normal", |
||||
lineHeight: null, |
||||
handler: null, // 如果传入handler,表示处理文字的点击事件,不是区域的
|
||||
hgap: 0, |
||||
vgap: 0, |
||||
lgap: 0, |
||||
rgap: 0, |
||||
tgap: 0, |
||||
bgap: 0, |
||||
text: "", |
||||
highLight: false, |
||||
}, |
||||
|
||||
render: function () { |
||||
var self = this, o = this.options; |
||||
if (o.hgap + o.lgap > 0) { |
||||
this.element.css({ |
||||
"padding-left": (o.hgap + o.lgap) / BI.pixRatio + BI.pixUnit |
||||
}); |
||||
} |
||||
if (o.hgap + o.rgap > 0) { |
||||
this.element.css({ |
||||
"padding-right": (o.hgap + o.rgap) / BI.pixRatio + BI.pixUnit |
||||
}); |
||||
} |
||||
if (o.vgap + o.tgap > 0) { |
||||
this.element.css({ |
||||
"padding-top": (o.vgap + o.tgap) / BI.pixRatio + BI.pixUnit |
||||
}); |
||||
} |
||||
if (o.vgap + o.bgap > 0) { |
||||
this.element.css({ |
||||
"padding-bottom": (o.vgap + o.bgap) / BI.pixRatio + BI.pixUnit |
||||
}); |
||||
} |
||||
if (BI.isNumber(o.height)) { |
||||
this.element.css({lineHeight: o.height / BI.pixRatio + BI.pixUnit}); |
||||
} |
||||
if (BI.isNumber(o.lineHeight)) { |
||||
this.element.css({lineHeight: o.lineHeight / BI.pixRatio + BI.pixUnit}); |
||||
} |
||||
if (BI.isWidthOrHeight(o.maxWidth)) { |
||||
this.element.css({maxWidth: o.maxWidth}); |
||||
} |
||||
this.element.css({ |
||||
textAlign: o.textAlign, |
||||
whiteSpace: o.whiteSpace, |
||||
textOverflow: o.whiteSpace === 'nowrap' ? "ellipsis" : "", |
||||
overflow: o.whiteSpace === "nowrap" ? "" : "auto" |
||||
}); |
||||
if (o.handler) { |
||||
this.text = BI.createWidget({ |
||||
type: "bi.layout", |
||||
tagName: "span" |
||||
}); |
||||
this.text.element.click(function () { |
||||
o.handler(self.getValue()); |
||||
}); |
||||
BI.createWidget({ |
||||
type: "bi.default", |
||||
element: this, |
||||
items: [this.text] |
||||
}); |
||||
} else { |
||||
this.text = this; |
||||
} |
||||
|
||||
if (BI.isKey(o.text)) { |
||||
this.setText(o.text); |
||||
} else if (BI.isKey(o.value)) { |
||||
this.setText(o.value); |
||||
} |
||||
if (o.highLight) { |
||||
this.doHighLight(); |
||||
} |
||||
}, |
||||
|
||||
doHighLight: function () { |
||||
this.text.element.addClass("bi-high-light"); |
||||
}, |
||||
|
||||
unHighLight: function () { |
||||
this.text.element.removeClass("bi-high-light"); |
||||
}, |
||||
|
||||
setValue: function (text) { |
||||
BI.Html.superclass.setValue.apply(this, arguments); |
||||
if (!this.isReadOnly()) { |
||||
this.setText(text); |
||||
} |
||||
}, |
||||
|
||||
setStyle: function (css) { |
||||
this.text.element.css(css); |
||||
}, |
||||
|
||||
setText: function (text) { |
||||
BI.Html.superclass.setText.apply(this, arguments); |
||||
this.options.text = text; |
||||
this.text.element.html(text); |
||||
} |
||||
}); |
||||
|
||||
BI.shortcut("bi.html", BI.Html); |
@ -0,0 +1,21 @@
|
||||
/** |
||||
* guy 图标 |
||||
* @class BI.Icon |
||||
* @extends BI.Single |
||||
*/ |
||||
BI.Icon = BI.inherit(BI.Single, { |
||||
_defaultConfig: function () { |
||||
var conf = BI.Icon.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend(conf, { |
||||
tagName: "i", |
||||
baseCls: (conf.baseCls || "") + " x-icon b-font horizon-center display-block" |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
if (BI.isIE9Below && BI.isIE9Below()) { |
||||
this.element.addClass("hack"); |
||||
} |
||||
} |
||||
}); |
||||
BI.shortcut("bi.icon", BI.Icon); |
@ -0,0 +1,23 @@
|
||||
/** |
||||
* @author windy |
||||
* @version 2.0 |
||||
* Created by windy on 2020/3/17 |
||||
*/ |
||||
|
||||
describe("IframeTest", function () { |
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("directionPager", function () { |
||||
var a = BI.Test.createWidget({ |
||||
type: "bi.iframe" |
||||
}); |
||||
a.setSrc("http://www.baidu.com"); |
||||
a.setName("testIFrame"); |
||||
expect(a.element.attr("src"), "http://www.baidu.com"); |
||||
expect(a.getSrc(), "http://www.baidu.com"); |
||||
expect(a.getName(), "testIFrame"); |
||||
a.destroy(); |
||||
}); |
||||
}); |
@ -0,0 +1,57 @@
|
||||
/** |
||||
* @class BI.Iframe |
||||
* @extends BI.Single |
||||
* @abstract |
||||
* Created by GameJian on 2016/3/2. |
||||
*/ |
||||
BI.Iframe = BI.inherit(BI.Single, { |
||||
_defaultConfig: function (config) { |
||||
var conf = BI.Iframe.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend(conf, { |
||||
tagName: "iframe", |
||||
baseCls: (conf.baseCls || "") + " bi-iframe", |
||||
src: "", |
||||
name: "", |
||||
attributes: {}, |
||||
width: "100%", |
||||
height: "100%" |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var self = this; |
||||
this.element.on("load", function () { |
||||
self.fireEvent("EVENT_LOADED"); |
||||
}); |
||||
}, |
||||
|
||||
_initProps: function () { |
||||
BI.Iframe.superclass._initProps.apply(this, arguments); |
||||
var o = this.options; |
||||
this.options.attributes = BI.extend({ |
||||
frameborder: 0, |
||||
src: o.src, |
||||
name: o.name |
||||
}, this.options.attributes); |
||||
}, |
||||
|
||||
setSrc: function (src) { |
||||
this.options.src = src; |
||||
this.element.attr("src", src); |
||||
}, |
||||
|
||||
getSrc: function () { |
||||
return this.options.src; |
||||
}, |
||||
|
||||
setName: function (name) { |
||||
this.options.name = name; |
||||
this.element.attr("name", name); |
||||
}, |
||||
|
||||
getName: function () { |
||||
return this.options.name; |
||||
} |
||||
}); |
||||
|
||||
BI.shortcut("bi.iframe", BI.Iframe); |
@ -0,0 +1,23 @@
|
||||
/** |
||||
* @author windy |
||||
* @version 2.0 |
||||
* Created by windy on 2020/3/17 |
||||
*/ |
||||
|
||||
describe("ImgTest", function () { |
||||
|
||||
/** |
||||
* test_author_windy |
||||
*/ |
||||
it("img", function () { |
||||
var a = BI.Test.createWidget({ |
||||
type: "bi.img", |
||||
iconWidth: 36, |
||||
iconHeight: 36 |
||||
}); |
||||
a.setSrc("test.png"); |
||||
expect(a.element.attr("src")).to.equal("test.png"); |
||||
expect(a.getSrc()).to.equal("test.png"); |
||||
a.destroy(); |
||||
}); |
||||
}); |
@ -0,0 +1,40 @@
|
||||
/** |
||||
* ͼƬ |
||||
* |
||||
* Created by GUY on 2016/1/26. |
||||
* @class BI.Img |
||||
* @extends BI.Single |
||||
* @abstract |
||||
*/ |
||||
BI.Img = BI.inherit(BI.Single, { |
||||
_defaultConfig: function (config) { |
||||
var conf = BI.Img.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend(conf, { |
||||
tagName: "img", |
||||
baseCls: (conf.baseCls || "") + " bi-img display-block", |
||||
src: "", |
||||
attributes: config.src ? { src: config.src } : {}, |
||||
width: "100%", |
||||
height: "100%" |
||||
}); |
||||
}, |
||||
|
||||
_initProps: function () { |
||||
BI.Img.superclass._initProps.apply(this, arguments); |
||||
var o = this.options; |
||||
this.options.attributes = BI.extend({ |
||||
src: o.src |
||||
}, this.options.attributes); |
||||
}, |
||||
|
||||
setSrc: function (src) { |
||||
this.options.src = src; |
||||
this.element.attr("src", src); |
||||
}, |
||||
|
||||
getSrc: function () { |
||||
return this.options.src; |
||||
} |
||||
}); |
||||
|
||||
BI.shortcut("bi.img", BI.Img); |
@ -0,0 +1,22 @@
|
||||
/** |
||||
* guy |
||||
* @extends BI.Single |
||||
* @type {*|void|Object} |
||||
*/ |
||||
BI.ImageCheckbox = BI.inherit(BI.IconButton, { |
||||
_defaultConfig: function () { |
||||
var conf = BI.ImageCheckbox.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend(conf, { |
||||
baseCls: (conf.baseCls || "") + " bi-image-checkbox check-box-icon", |
||||
selected: false, |
||||
handler: BI.emptyFn, |
||||
width: 16, |
||||
height: 16, |
||||
iconWidth: 16, |
||||
iconHeight: 16 |
||||
}); |
||||
} |
||||
}); |
||||
BI.ImageCheckbox.EVENT_CHANGE = BI.IconButton.EVENT_CHANGE; |
||||
|
||||
BI.shortcut("bi.image_checkbox", BI.ImageCheckbox); |
@ -0,0 +1,61 @@
|
||||
/** |
||||
* guy |
||||
* @extends BI.Single |
||||
* @type {*|void|Object} |
||||
*/ |
||||
BI.Checkbox = BI.inherit(BI.BasicButton, { |
||||
|
||||
props: { |
||||
baseCls: "bi-checkbox", |
||||
selected: false, |
||||
handler: BI.emptyFn, |
||||
width: 14, |
||||
height: 14, |
||||
iconWidth: 14, |
||||
iconHeight: 14 |
||||
}, |
||||
|
||||
render: function () { |
||||
var self = this, o = this.options; |
||||
return { |
||||
type: "bi.center_adapt", |
||||
items: [{ |
||||
type: "bi.default", |
||||
ref: function (_ref) { |
||||
self.checkbox = _ref; |
||||
}, |
||||
cls: "checkbox-content", |
||||
width: o.iconWidth, |
||||
height: o.iconHeight |
||||
}] |
||||
}; |
||||
}, |
||||
|
||||
_setEnable: function (enable) { |
||||
BI.Checkbox.superclass._setEnable.apply(this, arguments); |
||||
if (enable === true) { |
||||
this.checkbox.element.removeClass("base-disabled disabled"); |
||||
} else { |
||||
this.checkbox.element.addClass("base-disabled disabled"); |
||||
} |
||||
}, |
||||
|
||||
doClick: function () { |
||||
BI.Checkbox.superclass.doClick.apply(this, arguments); |
||||
if(this.isValid()) { |
||||
this.fireEvent(BI.Checkbox.EVENT_CHANGE); |
||||
} |
||||
}, |
||||
|
||||
setSelected: function (b) { |
||||
BI.Checkbox.superclass.setSelected.apply(this, arguments); |
||||
if (b) { |
||||
this.checkbox.element.addClass("bi-high-light-background"); |
||||
} else { |
||||
this.checkbox.element.removeClass("bi-high-light-background"); |
||||
} |
||||
} |
||||
}); |
||||
BI.Checkbox.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
|
||||
BI.shortcut("bi.checkbox", BI.Checkbox); |
@ -0,0 +1,697 @@
|
||||
/** |
||||
* 文件 |
||||
* |
||||
* Created by GUY on 2016/1/27. |
||||
* @class BI.File |
||||
* @extends BI.Single |
||||
* @abstract |
||||
*/ |
||||
(function (document) { |
||||
|
||||
/** |
||||
* @description normalize input.files. create if not present, add item method if not present |
||||
* @param Object generated wrap object |
||||
* @return Object the wrap object itself |
||||
*/ |
||||
var F = (function (item) { |
||||
return function (input) { |
||||
var files = input.files || [input]; |
||||
if (!files.item) { |
||||
files.item = item; |
||||
} |
||||
return files; |
||||
}; |
||||
})(function (i) { |
||||
return this[i]; |
||||
}); |
||||
|
||||
var event = { |
||||
|
||||
/** |
||||
* @description add an event via addEventListener or attachEvent |
||||
* @param DOMElement the element to add event |
||||
* @param String event name without "on" (e.g. "mouseover") |
||||
* @param Function the callback to associate as event |
||||
* @return Object noswfupload.event |
||||
*/ |
||||
add: document.addEventListener ? |
||||
function (node, name, callback) { |
||||
node.addEventListener(name, callback, false); |
||||
return this; |
||||
} : |
||||
function (node, name, callback) { |
||||
node.attachEvent("on" + name, callback); |
||||
return this; |
||||
}, |
||||
|
||||
/** |
||||
* @description remove an event via removeEventListener or detachEvent |
||||
* @param DOMElement the element to remove event |
||||
* @param String event name without "on" (e.g. "mouseover") |
||||
* @param Function the callback associated as event |
||||
* @return Object noswfupload.event |
||||
*/ |
||||
del: document.removeEventListener ? |
||||
function (node, name, callback) { |
||||
node.removeEventListener(name, callback, false); |
||||
return this; |
||||
} : |
||||
function (node, name, callback) { |
||||
node.detachEvent("on" + name, callback); |
||||
return this; |
||||
}, |
||||
|
||||
/** |
||||
* @description to block event propagation and prevent event default |
||||
* @param void generated event or undefined |
||||
* @return Boolean false |
||||
*/ |
||||
stop: function (e) { |
||||
if (!e) { |
||||
if (self.event) { |
||||
event.returnValue = !(event.cancelBubble = true); |
||||
} |
||||
} else { |
||||
e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true; |
||||
e.preventDefault ? e.preventDefault() : e.returnValue = false; |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
}; |
||||
|
||||
var sendFile = (function (toString) { |
||||
var multipart = function (boundary, name, file) { |
||||
return "--".concat( |
||||
boundary, CRLF, |
||||
"Content-Disposition: form-data; name=\"", name, "\"; filename=\"", _global.encodeURIComponent(file.fileName), "\"", CRLF, |
||||
"Content-Type: application/octet-stream", CRLF, |
||||
CRLF, |
||||
file.getAsBinary(), CRLF, |
||||
"--", boundary, "--", CRLF |
||||
); |
||||
}, |
||||
isFunction = function (Function) { |
||||
return toString.call(Function) === "[object Function]"; |
||||
}, |
||||
split = "onabort.onerror.onloadstart.onprogress".split("."), |
||||
length = split.length, |
||||
CRLF = "\r\n", |
||||
xhr = this.XMLHttpRequest ? new XMLHttpRequest : new ActiveXObject("Microsoft.XMLHTTP"), |
||||
sendFile; |
||||
|
||||
// FireFox 3+, Safari 4 beta (Chrome 2 beta file is buggy and will not work)
|
||||
if (xhr.upload || xhr.sendAsBinary) { |
||||
sendFile = function (handler, maxSize, width, height) { |
||||
var current = handler.current; |
||||
if (-1 < maxSize && maxSize < handler.file.fileSize) { |
||||
if (isFunction(handler.onerror)) { |
||||
handler.onerror(); |
||||
} |
||||
return; |
||||
} |
||||
for (var |
||||
xhr = new XMLHttpRequest, |
||||
upload = xhr.upload || { |
||||
addEventListener: function (event, callback) { |
||||
this["on" + event] = callback; |
||||
} |
||||
}, |
||||
i = 0; |
||||
i < length; |
||||
i++ |
||||
) { |
||||
upload.addEventListener( |
||||
split[i].substring(2), |
||||
(function (event) { |
||||
return function (rpe) { |
||||
if (isFunction(handler[event])) { |
||||
handler[event](rpe, xhr); |
||||
} |
||||
}; |
||||
})(split[i]), |
||||
false |
||||
); |
||||
} |
||||
upload.addEventListener( |
||||
"load", |
||||
function (rpe) { |
||||
if (handler.onreadystatechange === false) { |
||||
if (isFunction(handler.onload)) { |
||||
handler.onload(rpe, xhr); |
||||
} |
||||
} else { |
||||
setTimeout(function () { |
||||
if (xhr.readyState === 4) { |
||||
if (isFunction(handler.onload)) { |
||||
handler.onload(rpe, xhr); |
||||
} |
||||
} else { |
||||
setTimeout(arguments.callee, 15); |
||||
} |
||||
}, 15); |
||||
} |
||||
}, |
||||
false |
||||
); |
||||
xhr.open("post", BI.appendQuery(handler.url, { |
||||
filename: _global.encodeURIComponent(handler.file.fileName), |
||||
}), true); |
||||
if (!xhr.upload) { |
||||
var rpe = { loaded: 0, total: handler.file.fileSize || handler.file.size, simulation: true }; |
||||
rpe.interval = setInterval(function () { |
||||
rpe.loaded += 1024 / 4; |
||||
if (rpe.total <= rpe.loaded) { |
||||
rpe.loaded = rpe.total; |
||||
} |
||||
upload.onprogress(rpe); |
||||
}, 100); |
||||
xhr.onabort = function () { |
||||
upload.onabort({}); |
||||
}; |
||||
xhr.onerror = function () { |
||||
upload.onerror({}); |
||||
}; |
||||
xhr.onreadystatechange = function () { |
||||
switch (xhr.readyState) { |
||||
case 2: |
||||
case 3: |
||||
if (rpe.total <= rpe.loaded) { |
||||
rpe.loaded = rpe.total; |
||||
} |
||||
upload.onprogress(rpe); |
||||
break; |
||||
case 4: |
||||
clearInterval(rpe.interval); |
||||
rpe.interval = 0; |
||||
rpe.loaded = rpe.total; |
||||
upload.onprogress(rpe); |
||||
if (199 < xhr.status && xhr.status < 400) { |
||||
upload["onload"]({}); |
||||
var attachO = BI.jsonDecode(xhr.responseText); |
||||
attachO.filename = handler.file.fileName; |
||||
if (handler.file.type.indexOf("image") != -1) { |
||||
attachO.attach_type = "image"; |
||||
} |
||||
handler.attach_array[current] = attachO; |
||||
} else { |
||||
upload["onerror"]({}); |
||||
} |
||||
break; |
||||
} |
||||
}; |
||||
upload.onloadstart(rpe); |
||||
} else { |
||||
xhr.onreadystatechange = function () { |
||||
switch (xhr.readyState) { |
||||
case 4: |
||||
var attachO = BI.jsonDecode(xhr.responseText); |
||||
if (handler.file.type.indexOf("image") != -1) { |
||||
attachO.attach_type = "image"; |
||||
} |
||||
attachO.filename = handler.file.fileName; |
||||
if (handler.maxLength == 1) { |
||||
handler.attach_array[0] = attachO; |
||||
// handler.attach_array.push(attachO);
|
||||
} else { |
||||
handler.attach_array[current] = attachO; |
||||
} |
||||
break; |
||||
} |
||||
}; |
||||
if (isFunction(upload.onloadstart)) { |
||||
upload.onloadstart(); |
||||
} |
||||
} |
||||
var boundary = "AjaxUploadBoundary" + (new Date).getTime(); |
||||
xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundary); |
||||
if (handler.file.getAsBinary) { |
||||
xhr[xhr.sendAsBinary ? "sendAsBinary" : "send"](multipart(boundary, handler.name, handler.file)); |
||||
} else { |
||||
xhr.setRequestHeader("Content-Type", "multipart/form-data"); |
||||
// xhr.setRequestHeader("X-Name", handler.name);
|
||||
// xhr.setRequestHeader("X-File-Name", handler.file.fileName);
|
||||
var form = new FormData(); |
||||
form.append("FileData", handler.file); |
||||
xhr.send(form); |
||||
} |
||||
return handler; |
||||
}; |
||||
} |
||||
// Internet Explorer, Opera, others
|
||||
else { |
||||
sendFile = function (handler, maxSize, width, height) { |
||||
var current = handler.current; |
||||
var url = handler.url.concat(-1 === handler.url.indexOf("?") ? "?" : "&", "AjaxUploadFrame=true"), |
||||
rpe = { |
||||
loaded: 1, total: 100, simulation: true, interval: setInterval(function () { |
||||
if (rpe.loaded < rpe.total) { |
||||
++rpe.loaded; |
||||
} |
||||
if (isFunction(handler.onprogress)) { |
||||
handler.onprogress(rpe, {}); |
||||
} |
||||
}, 100) |
||||
}, |
||||
onload = function () { |
||||
iframe.onreadystatechange = iframe.onload = iframe.onerror = null; |
||||
form.parentNode.removeChild(form); |
||||
form = null; |
||||
clearInterval(rpe.interval); |
||||
// rpe.loaded = rpe.total;
|
||||
try { |
||||
var responseText = (iframe.contentWindow.document || iframe.contentWindow.contentDocument).body.innerHTML; |
||||
var attachO = BI.jsonDecode(responseText); |
||||
if (handler.file.type.indexOf("image") != -1) { |
||||
attachO.attach_type = "image"; |
||||
} |
||||
|
||||
// attachO.fileSize = responseText.length;
|
||||
try { |
||||
// decodeURIComponent特殊字符可能有问题, catch一下,保证能正常上传
|
||||
attachO.filename = _global.decodeURIComponent(handler.file.fileName); |
||||
} catch (e) { |
||||
attachO.filename = handler.file.fileName; |
||||
} |
||||
if (handler.maxLength == 1) { |
||||
handler.attach_array[0] = attachO; |
||||
} else { |
||||
handler.attach_array[current] = attachO; |
||||
} |
||||
} catch (e) { |
||||
if (isFunction(handler.onerror)) { |
||||
handler.onerror(rpe, event || _global.event); |
||||
} |
||||
} |
||||
if (isFunction(handler.onload)) { |
||||
handler.onload(rpe, { responseText: responseText }); |
||||
} |
||||
}, |
||||
target = ["AjaxUpload", (new Date).getTime(), String(Math.random()).substring(2)].join("_"); |
||||
try { // IE < 8 does not accept enctype attribute ...
|
||||
var form = document.createElement("<form enctype=\"multipart/form-data\"></form>"), |
||||
iframe = handler.iframe || (handler.iframe = document.createElement("<iframe id=\"" + target + "\" name=\"" + target + "\" src=\"" + url + "\"></iframe>")); |
||||
} catch (e) { |
||||
var form = document.createElement("form"), |
||||
iframe = handler.iframe || (handler.iframe = document.createElement("iframe")); |
||||
form.setAttribute("enctype", "multipart/form-data"); |
||||
iframe.setAttribute("name", iframe.id = target); |
||||
iframe.setAttribute("src", url); |
||||
} |
||||
iframe.style.position = "absolute"; |
||||
iframe.style.left = iframe.style.top = "-10000px"; |
||||
iframe.onload = onload; |
||||
iframe.onerror = function (event) { |
||||
if (isFunction(handler.onerror)) { |
||||
handler.onerror(rpe, event || _global.event); |
||||
} |
||||
}; |
||||
iframe.onreadystatechange = function () { |
||||
if (/loaded|complete/i.test(iframe.readyState)) { |
||||
onload(); |
||||
|
||||
// wei : todo,将附件信息放到handler.attach
|
||||
} else if (isFunction(handler.onloadprogress)) { |
||||
if (rpe.loaded < rpe.total) { |
||||
++rpe.loaded; |
||||
} |
||||
handler.onloadprogress(rpe, { |
||||
readyState: { |
||||
loading: 2, |
||||
interactive: 3, |
||||
loaded: 4, |
||||
complete: 4 |
||||
}[iframe.readyState] || 1 |
||||
}); |
||||
} |
||||
}; |
||||
form.setAttribute("action", handler.url + "&filename=" + _global.encodeURIComponent(handler.file.fileName)); |
||||
form.setAttribute("target", iframe.id); |
||||
form.setAttribute("method", "post"); |
||||
form.appendChild(handler.file); |
||||
form.style.display = "none"; |
||||
if (isFunction(handler.onloadstart)) { |
||||
handler.onloadstart(rpe, {}); |
||||
} |
||||
with (document.body || document.documentElement) { |
||||
appendChild(iframe); |
||||
appendChild(form); |
||||
form.submit(); |
||||
} |
||||
|
||||
return handler; |
||||
}; |
||||
} |
||||
xhr = null; |
||||
return sendFile; |
||||
})(Object.prototype.toString); |
||||
|
||||
var sendFiles = function (handler, maxSize, width, height) { |
||||
|
||||
var length = handler.files.length, |
||||
i = 0, |
||||
onload = handler.onload, |
||||
onloadstart = handler.onloadstart; |
||||
handler.current = 0; |
||||
handler.total = 0; |
||||
handler.sent = 0; |
||||
while (handler.current < length) { |
||||
handler.total += (handler.files[handler.current].fileSize || handler.files[handler.current].size); |
||||
handler.current++; |
||||
} |
||||
handler.current = 0; |
||||
if (length && handler.files[0].fileSize !== -1) { |
||||
handler.file = handler.files[handler.current]; |
||||
|
||||
sendFile(handler, maxSize, width, height).onload = function (rpe, xhr) { |
||||
handler.onloadstart = null; |
||||
handler.sent += (handler.files[handler.current].fileSize || handler.files[handler.current].size); |
||||
if (++handler.current < length) { |
||||
handler.file = handler.files[handler.current]; |
||||
sendFile(handler, maxSize, width, height).onload = arguments.callee; |
||||
} else if (onload) { |
||||
handler.onloadstart = onloadstart; |
||||
handler.onload = onload; |
||||
handler.onload(rpe, xhr); |
||||
} |
||||
}; |
||||
} else if (length) { |
||||
handler.total = length * 100; |
||||
handler.file = handler.files[handler.current]; |
||||
sendFile(handler, maxSize, width, height).onload = function (rpe, xhr) { |
||||
var callee = arguments.callee; |
||||
handler.onloadstart = null; |
||||
handler.sent += 100; |
||||
if (++handler.current < length) { |
||||
if (/\b(chrome|safari)\b/i.test(navigator.userAgent)) { |
||||
handler.iframe.parentNode.removeChild(handler.iframe); |
||||
handler.iframe = null; |
||||
} |
||||
setTimeout(function () { |
||||
handler.file = handler.files[handler.current]; |
||||
sendFile(handler, maxSize, width, height).onload = callee; |
||||
}, 15); |
||||
} else if (onload) { |
||||
setTimeout(function () { |
||||
handler.iframe.parentNode.removeChild(handler.iframe); |
||||
handler.iframe = null; |
||||
handler.onloadstart = onloadstart; |
||||
handler.onload = onload; |
||||
handler.onload(rpe, xhr); |
||||
}, 15); |
||||
} |
||||
}; |
||||
} |
||||
return handler; |
||||
}; |
||||
|
||||
var r1 = /\.([^.]+)$/; // .png
|
||||
var r2 = /\/([^/]+)$/; // image/png
|
||||
|
||||
/** |
||||
* 校验文件类型是否合法,同时兼容旧版形式 |
||||
* @param fileName |
||||
* @param fileType |
||||
* @returns {boolean} |
||||
*/ |
||||
var fileTypeValidate = function (fileName, fileType) { |
||||
if (!fileType) { |
||||
return true; |
||||
} |
||||
var mimes = fileType.split(","); |
||||
if (mimes[0] === fileType) { |
||||
mimes = (fileType + "").split(";"); |
||||
} |
||||
return BI.some(mimes, function (index, mime) { |
||||
var matches; |
||||
if (matches = mime.match(r1)) { |
||||
return fileName.toLowerCase().indexOf(matches[1]) > -1; |
||||
} |
||||
if (matches = mime.match(r2)) { |
||||
return matches[1] === "*" ? true : fileName.toLowerCase().indexOf(matches[1]) > -1; |
||||
} |
||||
}); |
||||
}; |
||||
|
||||
BI.File = BI.inherit(BI.Widget, { |
||||
_defaultConfig: function () { |
||||
var conf = BI.File.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend(conf, { |
||||
baseCls: (conf.baseCls || "") + " bi-file display-block", |
||||
tagName: "input", |
||||
attributes: { |
||||
type: "file" |
||||
}, |
||||
name: "", |
||||
url: "", |
||||
multiple: true, |
||||
accept: "", // .png,.pdf,image/jpg,image/* 等
|
||||
maxSize: -1, // 1024 * 1024
|
||||
maxLength: -1 // 无限制, 与multiple配合使用
|
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var self = this, o = this.options; |
||||
if (o.multiple === true) { |
||||
this.element.attr("multiple", "multiple"); |
||||
} |
||||
this.element.attr("name", o.name || this.getName()); |
||||
this.element.attr("title", o.title || ""); |
||||
this.element.attr("accept", o.accept); |
||||
}, |
||||
|
||||
created: function () { |
||||
var self = this, o = this.options; |
||||
// create the noswfupload.wrap Object
|
||||
// wrap.maxSize 文件大小限制
|
||||
// wrap.maxLength 文件个数限制
|
||||
var _wrap = this.wrap = this._wrap(this.element[0], o.maxSize); |
||||
// fileType could contain whatever text but filter checks *.{extension}
|
||||
// if present
|
||||
|
||||
// handlers
|
||||
|
||||
_wrap.onloadstart = function (rpe, xhr) { |
||||
// BI.Msg.toast("loadstart");
|
||||
self.fireEvent(BI.File.EVENT_UPLOADSTART, arguments); |
||||
}; |
||||
|
||||
_wrap.onprogress = function (rpe, xhr) { |
||||
// BI.Msg.toast("onprogress");
|
||||
// percent for each bar
|
||||
|
||||
// fileSize is -1 only if browser does not support file info access
|
||||
// this if splits recent browsers from others
|
||||
if (this.file.fileSize !== -1) { |
||||
// simulation property indicates when the progress event is fake
|
||||
if (rpe.simulation) { |
||||
|
||||
} else { |
||||
|
||||
} |
||||
} else { |
||||
// if fileSIze is -1 browser is using an iframe because it does
|
||||
// not support
|
||||
// files sent via Ajax (XMLHttpRequest)
|
||||
// We can still show some information
|
||||
} |
||||
self.fireEvent(BI.File.EVENT_PROGRESS, { |
||||
file: this.file, |
||||
total: rpe.total, |
||||
loaded: rpe.loaded, |
||||
simulation: rpe.simulation |
||||
}); |
||||
}; |
||||
|
||||
// generated if there is something wrong during upload
|
||||
_wrap.onerror = function () { |
||||
// just inform the user something was wrong
|
||||
self.fireEvent(BI.File.EVENT_ERROR); |
||||
}; |
||||
|
||||
// generated when every file has been sent (one or more, it does not
|
||||
// matter)
|
||||
_wrap.onload = function (rpe, xhr) { |
||||
var self_ = this; |
||||
// just show everything is fine ...
|
||||
// ... and after a second reset the component
|
||||
setTimeout(function () { |
||||
self_.clean(); // remove files from list
|
||||
self_.hide(); // hide progress bars and enable input file
|
||||
// enable again the submit button/element
|
||||
}, 100); |
||||
if (200 > xhr.status || xhr.status > 399) { |
||||
BI.Msg.toast(BI.i18nText("BI-Upload_File_Error"), { level: "error" }); |
||||
self.fireEvent(BI.File.EVENT_ERROR); |
||||
return; |
||||
} |
||||
var error = BI.some(_wrap.attach_array, function (index, attach) { |
||||
if (attach.errorCode) { |
||||
BI.Msg.toast(BI.i18nText(attach.errorMsg), { level: "error" }); |
||||
self.fireEvent(BI.File.EVENT_ERROR, attach); |
||||
return true; |
||||
} |
||||
}); |
||||
!error && self.fireEvent(BI.File.EVENT_UPLOADED); |
||||
}; |
||||
_wrap.url = o.url; |
||||
_wrap.fileType = o.accept; // 文件类型限制
|
||||
_wrap.attach_array = []; |
||||
_wrap.attach_names = []; |
||||
_wrap.attachNum = 0; |
||||
}, |
||||
|
||||
_events: function (wrap) { |
||||
var self = this, o = this.options; |
||||
event.add(wrap.dom.input, "change", function () { |
||||
event.del(wrap.dom.input, "change", arguments.callee); |
||||
var input = wrap.dom.input.cloneNode(true); |
||||
var files = F(wrap.dom.input); |
||||
if (o.maxLength !== -1 && o.maxLength < files.length) { |
||||
self.fireEvent(BI.File.EVENT_ERROR, { |
||||
errorType: 2 |
||||
}); |
||||
} else { |
||||
for (var i = 0; i < files.length; i++) { |
||||
var item = files.item(i); |
||||
var tempFile = item.value || item.name; |
||||
var value = item.fileName || (item.fileName = tempFile.split("\\").pop()), |
||||
ext = -1 !== value.indexOf(".") ? value.split(".").pop().toLowerCase() : "unknown", |
||||
size = item.fileSize || item.size; |
||||
var validateFileType = fileTypeValidate(value, wrap.fileType); |
||||
if (!validateFileType) { |
||||
// 文件类型不支持
|
||||
BI.Msg.toast(BI.i18nText("BI-Upload_File_Type_Error"), { level: "error" }); |
||||
self.fireEvent(BI.File.EVENT_ERROR, { |
||||
errorType: 0, |
||||
file: item |
||||
}); |
||||
} else if (wrap.maxSize !== -1 && size && wrap.maxSize < size) { |
||||
// 文件大小不支持
|
||||
BI.Msg.toast(BI.i18nText("BI-Upload_File_Size_Error"), { level: "error" }); |
||||
self.fireEvent(BI.File.EVENT_ERROR, { |
||||
errorType: 1, |
||||
file: item |
||||
}); |
||||
} else { |
||||
wrap.files.unshift(item); |
||||
// BI.Msg.toast(value);
|
||||
} |
||||
} |
||||
} |
||||
wrap.files.length > 0 && self.fireEvent(BI.File.EVENT_CHANGE, { |
||||
files: wrap.files |
||||
}); |
||||
input.value = ""; |
||||
wrap.dom.input.parentNode.replaceChild(input, wrap.dom.input); |
||||
wrap.dom.input = input; |
||||
event.add(wrap.dom.input, "change", arguments.callee); |
||||
}); |
||||
return wrap; |
||||
}, |
||||
|
||||
_wrap: function () { |
||||
var self = this, o = this.options; |
||||
// be sure input accept multiple files
|
||||
var input = this.element[0]; |
||||
if (o.multiple === true) { |
||||
this.element.attr("multiple", "multiple"); |
||||
} |
||||
input.value = ""; |
||||
|
||||
// wrap Object
|
||||
return this._events({ |
||||
|
||||
// DOM namespace
|
||||
dom: { |
||||
input: input, // input file
|
||||
disabled: false // internal use, checks input file state
|
||||
}, |
||||
name: input.name, // name to send for each file ($_FILES[{name}] in the server)
|
||||
// maxSize is the maximum amount of bytes for each file
|
||||
maxSize: o.maxSize ? o.maxSize >> 0 : -1, |
||||
maxLength: o.maxLength, |
||||
files: [], // file list
|
||||
|
||||
// remove every file from the noswfupload component
|
||||
clean: function () { |
||||
this.files = []; |
||||
}, |
||||
|
||||
// upload one file a time (which make progress possible rather than all files in one shot)
|
||||
// the handler is an object injected into the wrap one, could be the wrap itself or
|
||||
// something like {onload:function(){alert("OK")},onerror:function(){alert("Error")}, etc ...}
|
||||
upload: function (handler) { |
||||
if (handler) { |
||||
for (var key in handler) { |
||||
this[key] = handler[key]; |
||||
} |
||||
} |
||||
sendFiles(this, this.maxSize); |
||||
return this; |
||||
}, |
||||
|
||||
// hide progress bar (total + current) and enable files selection
|
||||
hide: function () { |
||||
if (this.dom.disabled) { |
||||
this.dom.disabled = false; |
||||
this.dom.input.removeAttribute("disabled"); |
||||
} |
||||
}, |
||||
|
||||
// show progress bar and disable file selection (used during upload)
|
||||
// total and current are pixels used to style bars
|
||||
// totalProp and currentProp are properties to change, "height" by default
|
||||
show: function (total, current, totalProp, currentProp) { |
||||
if (!this.dom.disabled) { |
||||
this.dom.disabled = true; |
||||
this.dom.input.setAttribute("disabled", "disabled"); |
||||
} |
||||
} |
||||
}); |
||||
}, |
||||
|
||||
setMaxFileLength: function(v) { |
||||
this.options.maxLength = v; |
||||
if (this.wrap) { |
||||
this.wrap.maxLength = v; |
||||
} |
||||
}, |
||||
|
||||
select: function () { |
||||
this.wrap && BI.Widget._renderEngine.createElement(this.wrap.dom.input).click(); |
||||
}, |
||||
|
||||
upload: function (handler) { |
||||
this.wrap && this.wrap.upload(handler); |
||||
}, |
||||
|
||||
getValue: function () { |
||||
return this.wrap ? this.wrap.attach_array : []; |
||||
}, |
||||
|
||||
reset: function () { |
||||
if (this.wrap) { |
||||
this.wrap.attach_array = []; |
||||
this.wrap.attach_names = []; |
||||
this.wrap.attachNum = 0; |
||||
} |
||||
}, |
||||
|
||||
_setEnable: function (enable) { |
||||
BI.File.superclass._setEnable.apply(this, arguments); |
||||
if (enable === true) { |
||||
this.element.attr("disabled", "disabled"); |
||||
} else { |
||||
this.element.removeAttr("disabled"); |
||||
} |
||||
} |
||||
}); |
||||
BI.File.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
BI.File.EVENT_UPLOADSTART = "EVENT_UPLOADSTART"; |
||||
BI.File.EVENT_ERROR = "EVENT_ERROR"; |
||||
BI.File.EVENT_PROGRESS = "EVENT_PROGRESS"; |
||||
BI.File.EVENT_UPLOADED = "EVENT_UPLOADED"; |
||||
BI.shortcut("bi.file", BI.File); |
||||
})(_global.document || {}); |
@ -0,0 +1,315 @@
|
||||
/** |
||||
* guy |
||||
* @class BI.Input 一个button和一行数 组成的一行listitem |
||||
* @extends BI.Single |
||||
* @type {*|void|Object} |
||||
*/ |
||||
BI.Input = BI.inherit(BI.Single, { |
||||
_defaultConfig: function () { |
||||
var conf = BI.Input.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend(conf, { |
||||
baseCls: (conf.baseCls || "") + " bi-input display-block overflow-dot", |
||||
tagName: "input", |
||||
validationChecker: BI.emptyFn, |
||||
quitChecker: BI.emptyFn, // 按确定键能否退出编辑
|
||||
allowBlank: false |
||||
}); |
||||
}, |
||||
|
||||
render: function () { |
||||
var self = this; |
||||
var ctrlKey = false; |
||||
var keyCode = null; |
||||
var inputEventValid = false; |
||||
var _keydown = BI.debounce(function (keyCode) { |
||||
self.onKeyDown(keyCode, ctrlKey); |
||||
self._keydown_ = false; |
||||
}, 300); |
||||
var _clk = BI.debounce(BI.bind(this._click, this), BI.EVENT_RESPONSE_TIME, { |
||||
"leading": true, |
||||
"trailing": false |
||||
}); |
||||
this._focusDebounce = BI.debounce(BI.bind(this._focus, this), BI.EVENT_RESPONSE_TIME, { |
||||
"leading": true, |
||||
"trailing": false |
||||
}); |
||||
this._blurDebounce = BI.debounce(BI.bind(this._blur, this), BI.EVENT_RESPONSE_TIME, { |
||||
"leading": true, |
||||
"trailing": false |
||||
}); |
||||
this.element |
||||
.keydown(function (e) { |
||||
inputEventValid = false; |
||||
ctrlKey = e.ctrlKey || e.metaKey; // mac的cmd支持一下
|
||||
keyCode = e.keyCode; |
||||
self.fireEvent(BI.Input.EVENT_QUICK_DOWN, arguments); |
||||
}) |
||||
.keyup(function (e) { |
||||
keyCode = null; |
||||
if (!(inputEventValid && e.keyCode === BI.KeyCode.ENTER)) { |
||||
self._keydown_ = true; |
||||
_keydown(e.keyCode); |
||||
} |
||||
}) |
||||
.on("input propertychange", function (e) { |
||||
// 输入内容全选并直接删光,如果按键没放开就失去焦点不会触发keyup,被focusout覆盖了
|
||||
// 其中propertychange在元素属性发生改变的时候就会触发 是为了兼容IE8
|
||||
// 通过keyCode判断会漏掉输入法点击输入(右键粘贴暂缓)
|
||||
var originalEvent = e.originalEvent; |
||||
if (BI.isNull(originalEvent.propertyName) || originalEvent.propertyName === "value") { |
||||
inputEventValid = true; |
||||
self._keydown_ = true; |
||||
_keydown(keyCode); |
||||
keyCode = null; |
||||
} |
||||
}) |
||||
.click(function (e) { |
||||
e.stopPropagation(); |
||||
_clk(); |
||||
}) |
||||
.mousedown(function (e) { |
||||
self.element.val(self.element.val()); |
||||
}) |
||||
.focus(function (e) { // 可以不用冒泡
|
||||
self._focusDebounce(); |
||||
}) |
||||
.blur(function (e) { |
||||
// DEC-14919 IE11在浏览器重新获得焦点之后会先触发focusout再触发focus,要保持先获得焦点再失去焦点的顺序不变,因此采用blur
|
||||
self._blurDebounce(); |
||||
}); |
||||
if (BI.isKey(this.options.value) || BI.isEmptyString(this.options.value)) { |
||||
this.setValue(this.options.value); |
||||
} |
||||
}, |
||||
|
||||
_focus: function () { |
||||
this.element.addClass("bi-input-focus"); |
||||
this._checkValidationOnValueChange(); |
||||
this._isEditing = true; |
||||
if (this.getValue() == "") { |
||||
this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EMPTY, this.getValue(), this); |
||||
this.fireEvent(BI.Input.EVENT_EMPTY); |
||||
} |
||||
this.fireEvent(BI.Input.EVENT_FOCUS); |
||||
}, |
||||
|
||||
_blur: function () { |
||||
var self = this; |
||||
if (self._keydown_ === true) { |
||||
BI.delay(blur, 300); |
||||
} else { |
||||
blur(); |
||||
} |
||||
|
||||
function blur () { |
||||
if (!self.isValid() && self.options.quitChecker.apply(self, [BI.trim(self.getValue())]) !== false) { |
||||
self.element.val(self._lastValidValue ? self._lastValidValue : ""); |
||||
self._checkValidationOnValueChange(); |
||||
self._defaultState(); |
||||
} |
||||
self.element.removeClass("bi-input-focus"); |
||||
self._isEditing = false; |
||||
self._start = false; |
||||
if (self.isValid()) { |
||||
var lastValidValue = self._lastValidValue; |
||||
self._lastValidValue = self.getValue(); |
||||
self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.CONFIRM, self.getValue(), self); |
||||
self.fireEvent(BI.Input.EVENT_CONFIRM); |
||||
if (self._lastValidValue !== lastValidValue) { |
||||
self.fireEvent(BI.Input.EVENT_CHANGE_CONFIRM); |
||||
} |
||||
} |
||||
self.fireEvent(BI.Input.EVENT_BLUR); |
||||
} |
||||
}, |
||||
|
||||
_click: function () { |
||||
if (this._isEditing !== true) { |
||||
this.selectAll(); |
||||
this.fireEvent(BI.Input.EVENT_CLICK); |
||||
} |
||||
}, |
||||
|
||||
onClick: function () { |
||||
this._click(); |
||||
}, |
||||
|
||||
onKeyDown: function (keyCode, ctrlKey) { |
||||
if (!this.isValid() || BI.trim(this._lastChangedValue) !== BI.trim(this.getValue())) { |
||||
this._checkValidationOnValueChange(); |
||||
} |
||||
if (this.isValid() && BI.trim(this.getValue()) !== "") { |
||||
if (BI.trim(this.getValue()) !== this._lastValue && (!this._start || this._lastValue == null || this._lastValue === "") |
||||
|| (this._pause === true && !/(\s|\u00A0)$/.test(this.getValue()))) { |
||||
this._start = true; |
||||
this._pause = false; |
||||
this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.STARTEDIT, this.getValue(), this); |
||||
this.fireEvent(BI.Input.EVENT_START); |
||||
} |
||||
} |
||||
if (keyCode == BI.KeyCode.ENTER) { |
||||
if (this.isValid() || this.options.quitChecker.apply(this, [BI.trim(this.getValue())]) !== false) { |
||||
this.blur(); |
||||
this.fireEvent(BI.Input.EVENT_ENTER); |
||||
} else { |
||||
this.fireEvent(BI.Input.EVENT_RESTRICT); |
||||
} |
||||
} |
||||
if (keyCode == BI.KeyCode.SPACE) { |
||||
this.fireEvent(BI.Input.EVENT_SPACE); |
||||
} |
||||
if (keyCode == BI.KeyCode.BACKSPACE && this._lastValue == "") { |
||||
this.fireEvent(BI.Input.EVENT_REMOVE); |
||||
} |
||||
if (keyCode == BI.KeyCode.BACKSPACE || keyCode == BI.KeyCode.DELETE) { |
||||
this.fireEvent(BI.Input.EVENT_BACKSPACE); |
||||
} |
||||
this.fireEvent(BI.Input.EVENT_KEY_DOWN, arguments); |
||||
|
||||
// _valueChange中会更新_lastValue, 这边缓存用以后续STOP事件服务
|
||||
var lastValue = this._lastValue; |
||||
if(BI.trim(this.getValue()) !== BI.trim(this._lastValue || "")){ |
||||
this._valueChange(); |
||||
} |
||||
if (BI.isEndWithBlank(this.getValue())) { |
||||
this._pause = true; |
||||
this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.PAUSE, "", this); |
||||
this.fireEvent(BI.Input.EVENT_PAUSE); |
||||
this._defaultState(); |
||||
} else if ((keyCode === BI.KeyCode.BACKSPACE || keyCode === BI.KeyCode.DELETE) && |
||||
BI.trim(this.getValue()) === "" && (lastValue !== null && BI.trim(lastValue) !== "")) { |
||||
this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.STOPEDIT, this.getValue(), this); |
||||
this.fireEvent(BI.Input.EVENT_STOP); |
||||
} |
||||
}, |
||||
|
||||
// 初始状态
|
||||
_defaultState: function () { |
||||
if (this.getValue() == "") { |
||||
this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EMPTY, this.getValue(), this); |
||||
this.fireEvent(BI.Input.EVENT_EMPTY); |
||||
} |
||||
this._lastValue = this.getValue(); |
||||
this._lastSubmitValue = null; |
||||
}, |
||||
|
||||
_valueChange: function () { |
||||
if (this.isValid() && BI.trim(this.getValue()) !== this._lastSubmitValue) { |
||||
this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.CHANGE, this.getValue(), this); |
||||
this.fireEvent(BI.Input.EVENT_CHANGE); |
||||
this._lastSubmitValue = BI.trim(this.getValue()); |
||||
} |
||||
if (this.getValue() == "") { |
||||
this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EMPTY, this.getValue(), this); |
||||
this.fireEvent(BI.Input.EVENT_EMPTY); |
||||
} |
||||
this._lastValue = this.getValue(); |
||||
}, |
||||
|
||||
_checkValidationOnValueChange: function () { |
||||
var o = this.options; |
||||
var v = this.getValue(); |
||||
this.setValid( |
||||
(o.allowBlank === true && BI.trim(v) == "") || ( |
||||
BI.isNotEmptyString(BI.trim(v)) && o.validationChecker.apply(this, [BI.trim(v)]) !== false |
||||
) |
||||
); |
||||
}, |
||||
|
||||
focus: function () { |
||||
if (!this.element.is(":visible")) { |
||||
throw new Error("input输入框在不可见下不能focus"); |
||||
} |
||||
if (!this._isEditing === true) { |
||||
this.element.focus(); |
||||
this.selectAll(); |
||||
} |
||||
}, |
||||
|
||||
blur: function () { |
||||
if (!this.element.is(":visible")) { |
||||
throw new Error("input输入框在不可见下不能blur"); |
||||
} |
||||
if (this._isEditing === true) { |
||||
this.element.blur(); |
||||
this._blurDebounce(); |
||||
} |
||||
}, |
||||
|
||||
selectAll: function () { |
||||
if (!this.element.is(":visible")) { |
||||
throw new Error("input输入框在不可见下不能select"); |
||||
} |
||||
this.element.select(); |
||||
this._isEditing = true; |
||||
}, |
||||
|
||||
setValue: function (textValue) { |
||||
this.element.val(textValue); |
||||
BI.nextTick(BI.bind(function () { |
||||
this._checkValidationOnValueChange(); |
||||
this._defaultState(); |
||||
if (this.isValid()) { |
||||
this._lastValidValue = this._lastSubmitValue = this.getValue(); |
||||
} |
||||
}, this)); |
||||
}, |
||||
|
||||
getValue: function () { |
||||
return this.element.val() || ""; |
||||
}, |
||||
|
||||
isEditing: function () { |
||||
return this._isEditing; |
||||
}, |
||||
|
||||
getLastValidValue: function () { |
||||
return this._lastValidValue; |
||||
}, |
||||
|
||||
getLastChangedValue: function () { |
||||
return this._lastChangedValue; |
||||
}, |
||||
|
||||
_setValid: function () { |
||||
BI.Input.superclass._setValid.apply(this, arguments); |
||||
if (this.isValid()) { |
||||
this._lastChangedValue = this.getValue(); |
||||
this.element.removeClass("bi-input-error"); |
||||
this.fireEvent(BI.Input.EVENT_VALID, BI.trim(this.getValue()), this); |
||||
} else { |
||||
if (this._lastChangedValue === this.getValue()) { |
||||
this._lastChangedValue = null; |
||||
} |
||||
this.element.addClass("bi-input-error"); |
||||
this.fireEvent(BI.Input.EVENT_ERROR, BI.trim(this.getValue()), this); |
||||
} |
||||
}, |
||||
|
||||
_setEnable: function (b) { |
||||
BI.Input.superclass._setEnable.apply(this, [b]); |
||||
this.element[0].disabled = !b; |
||||
} |
||||
}); |
||||
BI.Input.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
|
||||
BI.Input.EVENT_FOCUS = "EVENT_FOCUS"; |
||||
BI.Input.EVENT_CLICK = "EVENT_CLICK"; |
||||
BI.Input.EVENT_BLUR = "EVENT_BLUR"; |
||||
BI.Input.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; |
||||
BI.Input.EVENT_QUICK_DOWN = "EVENT_QUICK_DOWN"; |
||||
BI.Input.EVENT_SPACE = "EVENT_SPACE"; |
||||
BI.Input.EVENT_BACKSPACE = "EVENT_BACKSPACE"; |
||||
|
||||
BI.Input.EVENT_START = "EVENT_START"; |
||||
BI.Input.EVENT_PAUSE = "EVENT_PAUSE"; |
||||
BI.Input.EVENT_STOP = "EVENT_STOP"; |
||||
BI.Input.EVENT_CHANGE_CONFIRM = "EVENT_CHANGE_CONFIRM"; |
||||
BI.Input.EVENT_CONFIRM = "EVENT_CONFIRM"; |
||||
BI.Input.EVENT_REMOVE = "EVENT_REMOVE"; |
||||
BI.Input.EVENT_EMPTY = "EVENT_EMPTY"; |
||||
BI.Input.EVENT_VALID = "EVENT_VALID"; |
||||
BI.Input.EVENT_ERROR = "EVENT_ERROR"; |
||||
BI.Input.EVENT_ENTER = "EVENT_ENTER"; |
||||
BI.Input.EVENT_RESTRICT = "EVENT_RESTRICT"; |
||||
BI.shortcut("bi.input", BI.Input); |
@ -0,0 +1,29 @@
|
||||
/** |
||||
* guy |
||||
* @extends BI.Single |
||||
* @type {*|void|Object} |
||||
*/ |
||||
BI.ImageRadio = BI.inherit(BI.IconButton, { |
||||
_defaultConfig: function () { |
||||
var conf = BI.ImageRadio.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend(conf, { |
||||
baseCls: (conf.baseCls || "") + " bi-radio radio-icon", |
||||
selected: false, |
||||
handler: BI.emptyFn, |
||||
width: 16, |
||||
height: 16, |
||||
iconWidth: 16, |
||||
iconHeight: 16 |
||||
}); |
||||
}, |
||||
|
||||
doClick: function () { |
||||
BI.ImageRadio.superclass.doClick.apply(this, arguments); |
||||
if(this.isValid()) { |
||||
this.fireEvent(BI.ImageRadio.EVENT_CHANGE); |
||||
} |
||||
} |
||||
}); |
||||
BI.ImageRadio.EVENT_CHANGE = BI.IconButton.EVENT_CHANGE; |
||||
|
||||
BI.shortcut("bi.image_radio", BI.ImageRadio); |
@ -0,0 +1,62 @@
|
||||
/** |
||||
* guy |
||||
* @extends BI.Single |
||||
* @type {*|void|Object} |
||||
*/ |
||||
BI.Radio = BI.inherit(BI.BasicButton, { |
||||
|
||||
props: { |
||||
baseCls: "bi-radio", |
||||
selected: false, |
||||
handler: BI.emptyFn, |
||||
width: 14, |
||||
height: 14, |
||||
iconWidth: 14, |
||||
iconHeight: 14 |
||||
}, |
||||
|
||||
render: function () { |
||||
var self = this, o = this.options; |
||||
return { |
||||
type: "bi.center_adapt", |
||||
element: this.element, |
||||
items: [{ |
||||
type: "bi.layout", |
||||
cls: "radio-content", |
||||
ref: function (_ref) { |
||||
self.radio = _ref; |
||||
}, |
||||
width: o.iconWidth, |
||||
height: o.iconHeight |
||||
}] |
||||
}; |
||||
}, |
||||
|
||||
_setEnable: function (enable) { |
||||
BI.Radio.superclass._setEnable.apply(this, arguments); |
||||
if (enable === true) { |
||||
this.radio.element.removeClass("base-disabled disabled"); |
||||
} else { |
||||
this.radio.element.addClass("base-disabled disabled"); |
||||
} |
||||
}, |
||||
|
||||
doClick: function () { |
||||
BI.Radio.superclass.doClick.apply(this, arguments); |
||||
if(this.isValid()) { |
||||
this.fireEvent(BI.Radio.EVENT_CHANGE); |
||||
} |
||||
}, |
||||
|
||||
setSelected: function (b) { |
||||
BI.Radio.superclass.setSelected.apply(this, arguments); |
||||
if (b) { |
||||
this.radio.element.addClass("bi-high-light-background"); |
||||
} else { |
||||
this.radio.element.removeClass("bi-high-light-background"); |
||||
} |
||||
} |
||||
}); |
||||
BI.Radio.EVENT_CHANGE = "EVENT_CHANGE"; |
||||
|
||||
BI.shortcut("bi.radio", BI.Radio); |
@ -0,0 +1,377 @@
|
||||
/** |
||||
* Created by dailer on 2019/6/19. |
||||
*/ |
||||
!(function () { |
||||
BI.AbstractLabel = BI.inherit(BI.Single, { |
||||
|
||||
_defaultConfig: function (props) { |
||||
var conf = BI.AbstractLabel.superclass._defaultConfig.apply(this, arguments); |
||||
return BI.extend(conf, { |
||||
textAlign: "center", |
||||
whiteSpace: "nowrap", // normal or nowrap
|
||||
textWidth: null, |
||||
textHeight: null, |
||||
hgap: 0, |
||||
vgap: 0, |
||||
lgap: 0, |
||||
rgap: 0, |
||||
tgap: 0, |
||||
bgap: 0, |
||||
highLight: false, |
||||
handler: null |
||||
}); |
||||
}, |
||||
|
||||
_createJson: function () { |
||||
var o = this.options; |
||||
return { |
||||
type: "bi.text", |
||||
textAlign: o.textAlign, |
||||
whiteSpace: o.whiteSpace, |
||||
lineHeight: o.textHeight, |
||||
maxWidth: "100%", |
||||
text: o.text, |
||||
value: o.value, |
||||
py: o.py, |
||||
keyword: o.keyword, |
||||
highLight: o.highLight, |
||||
handler: o.handler |
||||
}; |
||||
}, |
||||
|
||||
render: function () { |
||||
if (this.options.textAlign === "center") { |
||||
this._createCenterEl(); |
||||
} else { |
||||
this._createNotCenterEl(); |
||||
} |
||||
}, |
||||
|
||||
_createCenterEl: function () { |
||||
var o = this.options; |
||||
var json = this._createJson(); |
||||
json.textAlign = "left"; |
||||
if (BI.isNumber(o.width) && o.width > 0) { |
||||
if (BI.isNumber(o.textWidth) && o.textWidth > 0) { |
||||
json.maxWidth = o.textWidth; |
||||
if (BI.isNumber(o.height) && o.height > 0) { // 1.1
|
||||
BI.createWidget({ |
||||
type: "bi.center_adapt", |
||||
height: o.height, |
||||
columnSize: ["auto"], // important! 让文字在flex布局下shrink为1
|
||||
scrollable: o.whiteSpace === "normal", |
||||
element: this, |
||||
items: [ |
||||
{ |
||||
el: (this.text = BI.createWidget(json)) |
||||
} |
||||
] |
||||
}); |
||||
return; |
||||
} |
||||
BI.createWidget({ // 1.2
|
||||
type: "bi.center_adapt", |
||||
columnSize: ["auto"], // important! 让文字在flex布局下shrink为1
|
||||
scrollable: o.whiteSpace === "normal", |
||||
element: this, |
||||
items: [ |
||||
{ |
||||
el: (this.text = BI.createWidget(json)) |
||||
} |
||||
] |
||||
}); |
||||
return; |
||||
} |
||||
if (o.whiteSpace === "normal") { // 1.3
|
||||
BI.extend(json, { |
||||
hgap: o.hgap, |
||||
vgap: o.vgap, |
||||
lgap: o.lgap, |
||||
rgap: o.rgap, |
||||
tgap: o.tgap, |
||||
bgap: o.bgap |
||||
}); |
||||
this.text = BI.createWidget(json); |
||||
BI.createWidget({ |
||||
type: "bi.center_adapt", |
||||
columnSize: ["auto"], // important! 让文字在flex布局下shrink为1
|
||||
scrollable: o.whiteSpace === "normal", |
||||
element: this, |
||||
items: [this.text] |
||||
}); |
||||
return; |
||||
} |
||||
if (BI.isNumber(o.height) && o.height > 0) { // 1.4
|
||||
this.element.css({ |
||||
"line-height": o.height / BI.pixRatio + BI.pixUnit |
||||
}); |
||||
json.textAlign = o.textAlign; |
||||
this.text = BI.createWidget(BI.extend(json, { |
||||
element: this, |
||||
hgap: o.hgap, |
||||
vgap: o.vgap, |
||||
lgap: o.lgap, |
||||
rgap: o.rgap, |
||||
tgap: o.tgap, |
||||
bgap: o.bgap |
||||
})); |
||||
return; |
||||
} |
||||
BI.extend(json, { // 1.5
|
||||
hgap: o.hgap, |
||||
vgap: o.vgap, |
||||
lgap: o.lgap, |
||||
rgap: o.rgap, |
||||
tgap: o.tgap, |
||||
bgap: o.bgap, |
||||
maxWidth: "100%" |
||||
}); |
||||
this.text = BI.createWidget(json); |
||||
BI.createWidget({ |
||||
type: "bi.center_adapt", |
||||
columnSize: ["auto"], // important! 让文字在flex布局下shrink为1
|
||||
scrollable: o.whiteSpace === "normal", |
||||
element: this, |
||||
items: [this.text] |
||||
}); |
||||
return; |
||||
} |
||||
if (BI.isNumber(o.textWidth) && o.textWidth > 0) { // 1.6
|
||||
json.maxWidth = o.textWidth; |
||||
BI.createWidget({ |
||||
type: "bi.center_adapt", |
||||
columnSize: ["auto"], // important! 让文字在flex布局下shrink为1
|
||||
scrollable: o.whiteSpace === "normal", |
||||
element: this, |
||||
items: [ |
||||
{ |
||||
el: (this.text = BI.createWidget(json)) |
||||
} |
||||
] |
||||
}); |
||||
return; |
||||
} |
||||
if (o.whiteSpace === "normal") { // 1.7
|
||||
BI.extend(json, { |
||||
hgap: o.hgap, |
||||
vgap: o.vgap, |
||||
lgap: o.lgap, |
||||
rgap: o.rgap, |
||||
tgap: o.tgap, |
||||
bgap: o.bgap |
||||
}); |
||||
this.text = BI.createWidget(json); |
||||
BI.createWidget({ |
||||
type: "bi.center_adapt", |
||||
columnSize: ["auto"], // important! 让文字在flex布局下shrink为1
|
||||
scrollable: true, |
||||
element: this, |
||||
items: [this.text] |
||||
}); |
||||
return; |
||||
} |
||||
if (BI.isNumber(o.height) && o.height > 0) { // 1.8
|
||||
this.element.css({ |
||||
"line-height": o.height / BI.pixRatio + BI.pixUnit |
||||
}); |
||||
json.textAlign = o.textAlign; |
||||
this.text = BI.createWidget(BI.extend(json, { |
||||
element: this, |
||||
hgap: o.hgap, |
||||
vgap: o.vgap, |
||||
lgap: o.lgap, |
||||
rgap: o.rgap, |
||||
tgap: o.tgap, |
||||
bgap: o.bgap |
||||
})); |
||||
return; |
||||
} |
||||
this.text = BI.createWidget(BI.extend(json, { |
||||
hgap: o.hgap, |
||||
vgap: o.vgap, |
||||
lgap: o.lgap, |
||||
rgap: o.rgap, |
||||
tgap: o.tgap, |
||||
bgap: o.bgap |
||||
})); |
||||
BI.createWidget({ |
||||
type: "bi.center_adapt", |
||||
columnSize: ["auto"], // important! 让文字在flex布局下shrink为1
|
||||
element: this, |
||||
items: [this.text] |
||||
}); |
||||
}, |
||||
|
||||
_createNotCenterEl: function () { |
||||
var o = this.options; |
||||
var adaptLayout = "bi.vertical_adapt"; |
||||
var json = this._createJson(); |
||||
if (BI.isNumber(o.width) && o.width > 0) { |
||||
if (BI.isNumber(o.textWidth) && o.textWidth > 0) { |
||||
json.maxWidth = o.textWidth; |
||||
if (BI.isNumber(o.height) && o.height > 0) { // 2.1
|
||||
BI.createWidget({ |
||||
type: adaptLayout, |
||||
horizontalAlign: o.textAlign, |
||||
columnSize: ["auto"], // important! 让文字在flex布局下shrink为1
|
||||
height: o.height, |
||||
scrollable: o.whiteSpace === "normal", |
||||
element: this, |
||||
items: [ |
||||
{ |
||||
el: (this.text = BI.createWidget(json)) |
||||
} |
||||
] |
||||
}); |
||||
return; |
||||
} |
||||
BI.createWidget({ // 2.2
|
||||
type: adaptLayout, |
||||
horizontalAlign: o.textAlign, |
||||
columnSize: ["auto"], // important! 让文字在flex布局下shrink为1
|
||||
scrollable: o.whiteSpace === "normal", |
||||
hgap: o.hgap, |
||||
vgap: o.vgap, |
||||
lgap: o.lgap, |
||||
rgap: o.rgap, |
||||
tgap: o.tgap, |
||||
bgap: o.bgap, |
||||
element: this, |
||||
items: [ |
||||
{ |
||||
el: (this.text = BI.createWidget(json)) |
||||
} |
||||
] |
||||
}); |
||||
return; |
||||
} |
||||
if (BI.isNumber(o.height) && o.height > 0) { // 2.3
|
||||
if (o.whiteSpace !== "normal") { |
||||
this.element.css({ |
||||
"line-height": (o.height - (o.vgap * 2)) / BI.pixRatio + BI.pixUnit |
||||
}); |
||||
} |
||||
this.text = BI.createWidget(BI.extend(json, { |
||||
element: this, |
||||
hgap: o.hgap, |
||||
vgap: o.vgap, |
||||
lgap: o.lgap, |
||||
rgap: o.rgap, |
||||
tgap: o.tgap, |
||||
bgap: o.bgap |
||||
})); |
||||
return; |
||||
} |
||||
json.maxWidth = o.width - 2 * o.hgap - o.lgap - o.rgap; |
||||
BI.createWidget({ // 2.4
|
||||
type: adaptLayout, |
||||
horizontalAlign: o.textAlign, |
||||
columnSize: ["auto"], // important! 让文字在flex布局下shrink为1
|
||||
scrollable: o.whiteSpace === "normal", |
||||
hgap: o.hgap, |
||||
vgap: o.vgap, |
||||
lgap: o.lgap, |
||||
rgap: o.rgap, |
||||
tgap: o.tgap, |
||||
bgap: o.bgap, |
||||
element: this, |
||||
items: [{ |
||||
el: (this.text = BI.createWidget(json)) |
||||
}] |
||||
}); |
||||
return; |
||||
} |
||||
if (BI.isNumber(o.textWidth) && o.textWidth > 0) { |
||||
json.maxWidth = o.textWidth; |
||||
BI.createWidget({ // 2.5
|
||||
type: adaptLayout, |
||||
horizontalAlign: o.textAlign, |
||||
columnSize: ["auto"], // important! 让文字在flex布局下shrink为1
|
||||
scrollable: o.whiteSpace === "normal", |
||||
hgap: o.hgap, |
||||
vgap: o.vgap, |
||||
lgap: o.lgap, |
||||
rgap: o.rgap, |
||||
tgap: o.tgap, |
||||
bgap: o.bgap, |
||||
element: this, |
||||
items: [ |
||||
{ |
||||
el: (this.text = BI.createWidget(json)) |
||||
} |
||||
] |
||||
}); |
||||
return; |
||||
} |
||||
if (BI.isNumber(o.height) && o.height > 0) { |
||||
if (o.whiteSpace !== "normal") { |
||||
this.element.css({ |
||||
"line-height": (o.height - (o.vgap * 2)) / BI.pixRatio + BI.pixUnit |
||||
}); |
||||
} |
||||
this.text = BI.createWidget(BI.extend(json, { // 2.6
|
||||
element: this, |
||||
hgap: o.hgap, |
||||
vgap: o.vgap, |
||||
lgap: o.lgap, |
||||
rgap: o.rgap, |
||||
tgap: o.tgap, |
||||
bgap: o.bgap |
||||
})); |
||||
return; |
||||
} |
||||
this.text = BI.createWidget(BI.extend(json, { |
||||
hgap: o.hgap, |
||||
vgap: o.vgap, |
||||
lgap: o.lgap, |
||||
rgap: o.rgap, |
||||
tgap: o.tgap, |
||||
bgap: o.bgap |
||||
})); |
||||
BI.createWidget({ |
||||
type: adaptLayout, |
||||
horizontalAlign: o.textAlign, |
||||
columnSize: ["auto"], // important! 让文字在flex布局下shrink为1
|
||||
element: this, |
||||
scrollable: o.whiteSpace === "normal", |
||||
items: [this.text] |
||||
}); |
||||
}, |
||||
|
||||
doRedMark: function () { |
||||
this.text.doRedMark.apply(this.text, arguments); |
||||
}, |
||||
|
||||
unRedMark: function () { |
||||
this.text.unRedMark.apply(this.text, arguments); |
||||
}, |
||||
|
||||
doHighLight: function () { |
||||
this.text.doHighLight.apply(this.text, arguments); |
||||
}, |
||||
|
||||
unHighLight: function () { |
||||
this.text.unHighLight.apply(this.text, arguments); |
||||
}, |
||||
|
||||
setText: function (v) { |
||||
this.options.text = v; |
||||
this.text.setText(v); |
||||
}, |
||||
|
||||
getText: function () { |
||||
return this.options.text; |
||||
}, |
||||
|
||||
setStyle: function (css) { |
||||
this.text.setStyle(css); |
||||
}, |
||||
|
||||
setValue: function (v) { |
||||
BI.AbstractLabel.superclass.setValue.apply(this, arguments); |
||||
if (!this.isReadOnly()) { |
||||
this.text.setValue(v); |
||||
} |
||||
} |
||||
}); |
||||
}()); |
@ -0,0 +1,25 @@
|
||||
/** |
||||
* Created by GUY on 2015/6/26. |
||||
*/ |
||||
|
||||
BI.HtmlLabel = BI.inherit(BI.AbstractLabel, { |
||||
|
||||
props: { |
||||
baseCls: "bi-html-label" |
||||
}, |
||||
|
||||
_createJson: function () { |
||||
var o = this.options; |
||||
return { |
||||
type: "bi.html", |
||||
textAlign: o.textAlign, |
||||
whiteSpace: o.whiteSpace, |
||||
lineHeight: o.textHeight, |
||||
text: o.text, |
||||
value: o.value, |
||||
handler: o.handler |
||||
}; |
||||
} |
||||
}); |
||||
|
||||
BI.shortcut("bi.html_label", BI.HtmlLabel); |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue