Ext5实现树形下拉框ComboBoxTree
最近为了实现一个属性下拉框被Ext框架折腾了好几天。。
所以,首先要说的是,不管你要做什么系统、强烈建议你不要选择Ext。据我这几天的搜索,应该这个框架现在用的人也很少了。
Ext框架的缺陷:框架沉重、扩展性差(与其他js框架相比)、各版本差别大(Ext3、4、5不兼容)。
现在进入正题,这几天研究ext实现树形下拉框发现网上常见的两种做法:
1、扩展Ext.form.field.ComboBox
使用这种方式的好处是ComboBox与我们要实现的东西其行为更为相似,在取值、赋值方面比较方便、可以对触发下拉事件上做定制。
最后实现的东西发现浏览器不能兼容、只有Win10的Edge可以完美呈现,无奈放弃。。
2、扩展Ext.form.field.Picker
上一条路没有走通最终选择了这种方式。这种方式的好处:对树形节点的展开、关闭不会影响到用户的选取操作。
这段代码也是根据网络上的源码做了修改,之所以发出来因为网上实在是找不到基于Ext5的实现。所以我判断现在使用Ext框架的人应该极少了,网上有的都是几年前使用Ext4、3的人发表的。所有基于Ext4的实现在Ext5上都不能完美支持。。
定义组件:
Ext.define('Ext.ux.ComboBoxTree', {
extend: 'Ext.form.field.Picker',
requires: ['Ext.tree.Panel'],
alias: ['widget.comboboxtree'],
multiSelect: false,
multiCascade: true,
rootVisible: false,
displayField: 'text',
emptyText: '',
submitValue: '',
url: '',
pathValue: '',
defaultValue: null,
pathArray: [],
selectNodeModel: 'all',
maxHeight: 400,
setValue: function (value) {
if (value) {//注意:此处的判断会使id为0的值选中失效
if (typeof value == 'number') {
this.defaultValue = value;
}
this.callParent(arguments);
}
},
initComponent: function () {
var self = this;
self.selectNodeModel = Ext.isEmpty(self.selectNodeModel) ? 'all' : self.selectNodeModel;
Ext.apply(self, {
fieldLabel: self.fieldLabel,
labelWidth: self.labelWidth
});
self.store = Ext.create('Ext.data.TreeStore', {
root: { expanded: true },
proxy: { type: 'ajax', url: self.url },
autoLoad: true
});
self.store.addListener('load', function (st, rds, opts) {
if (self.defaultValue) {
var defaultRecord = self.store.getNodeById(self.defaultValue);
self.setDefaultValue(defaultRecord.get('id'), defaultRecord.get('text'));
} else {
self.setDefaultValue('', self.emptyText);
}
});
self.callParent();
},
createPicker: function () {
var self = this;
self.picker = Ext.create('Ext.tree.Panel', {
//height: self.treeHeight == null ? 200 : self.treeHeight,
autoScroll: true,
floating: true,
focusOnToFront: false,
shadow: true,
ownerCt: this.ownerCt,
useArrows: false,
store: this.store,
rootVisible: this.rootVisible,
displayField: this.displayField,
maxHeight: this.maxHeight,
viewConfig: {
onCheckboxChange: function (e, t) {
if (self.multiSelect) {
var item = e.getTarget(this.getItemSelector(), this.getTargetEl()),
record;
if (item) {
record = this.getRecord(item);
var check = !record.get('checked');
record.set('checked', check);
if (self.multiCascade) {
if (check) {
record.bubble(function (parentNode) {
if ('Root' != parentNode.get('text')) {
parentNode.set('checked', true);
}
});
record.cascadeBy(function (node) {
node.set('checked', true);
node.expand(true);
});
} else {
record.cascadeBy(function (node) {
node.set('checked', false);
});
record.bubble(function (parentNode) {
if ('Root' != parentNode.get('text')) {
var flag = true;
for (var i = 0; i < parentNode.childNodes.length; i++) {
var child = parentNode.childNodes[i];
if (child.get('checked')) {
flag = false;
continue;
}
}
if (flag) {
parentNode.set('checked', false);
}
}
});
}
}
}
var records = self.picker.getView().getChecked(),
names = [],
values = [];
Ext.Array.each(records, function (rec) {
names.push(rec.get('text'));
values.push(rec.get('id'));
});
self.submitValue = values.join(',');
self.setValue(names.join(','));
}
}
}
});
self.picker.on({
itemclick: function (view, recore, item, index, e, object) {
var selModel = self.selectNodeModel;
var isLeaf = recore.data.leaf;
var isRoot = recore.data.root;
var view = self.picker.getView();
if (!self.multiSelect) {
if ((isRoot) && selModel != 'all') {
return;
} else if (selModel == 'exceptRoot' && isRoot) {
return;
} else if (selModel == 'folder' && isLeaf) {
return;
} else if (selModel == 'leaf' && !isLeaf) {
var expand = recore.get('expanded');
if (expand) {
view.collapse(recore);
} else {
view.expand(recore);
}
return;
}
self.submitValue = recore.get('id');
self.setValue(recore.get('text'));
self.eleJson = Ext.encode(recore.raw);
self.collapse();
}
}
});
return self.picker;
},
listeners: {
expand: function (field, eOpts) {
var picker = this.getPicker();
if (!this.multiSelect) {
if (this.pathValue != '') {
picker.expandPath(this.pathValue, 'id', '/', function (bSucess, oLastNode) {
picker.getSelectionModel().select(oLastNode);
});
}
} else {
if (this.pathArray.length > 0) {
for (var m = 0; m < this.pathArray.length; m++) {
picker.expandPath(this.pathArray[m], 'id', '/', function (bSucess, oLastNode) {
oLastNode.set('checked', true);
});
}
}
}
}
},
clearValue: function () {
this.setDefaultValue('', '');
},
getEleJson: function () {
if (this.eleJson == undefined) {
this.eleJson = [];
}
return this.eleJson;
},
getSubmitValue: function () {
if (this.submitValue == undefined) {
this.submitValue = '';
}
return this.submitValue;
},
getDisplayValue: function () {
if (this.value == undefined) {
this.value = '';
}
return this.value;
},
getValue: function () {
return this.getSubmitValue();
},
setPathValue: function (pathValue) {
this.pathValue = pathValue;
},
setPathArray: function (pathArray) {
this.pathArray = pathArray;
},
setDefaultValue: function (submitValue, displayValue) {
this.submitValue = submitValue;
this.setValue(displayValue);
this.eleJson = undefined;
this.pathArray = [];
},
alignPicker: function () {
var me = this,
picker,
isAbove,
aboveSfx = '-above';
if (this.isExpanded) {
picker = me.getPicker();
if (me.matchFieldWidth) {
picker.setWidth(me.bodyEl.getWidth());
}
if (picker.isFloating()) {
picker.alignTo(me.inputEl, "", me.pickerOffset); // ""->tl
isAbove = picker.el.getY() < me.inputEl.getY();
me.bodyEl[isAbove ? 'addCls' : 'removeCls'](me.openCls + aboveSfx);
picker.el[isAbove ? 'addCls' : 'removeCls'](picker.baseCls + aboveSfx);
}
}
}
});
以上代码有待优化,由于只用了单选,所以多选应该还有点问题。
调用代码:
Ext.create('Ext.ux.ComboBoxTree', {
cId: 'cbOrganizationId',
name: 'OrganizationId',
fieldLabel: '所属组织',
editable: false,
url: 'your url of json',
//emptyText: '请选择所属组织',
allowBlank: false
});
效果图:
Ext.form.field.ComboBoxView source...
Ext5实现树形下拉框ComboBoxTree的更多相关文章
- easyui源码翻译1.32--ComboTree(树形下拉框)
前言 扩展自$.fn.combo.defaults和$.fn.tree.defaults.使用$.fn.combotree.defaults重写默认值对象.下载该插件翻译源码 树形下拉框结合选择控件和 ...
- Vue实现树形下拉框
Vue自身并没有实现树形下拉框的组件,找了很多资料,最后在Github上找了个插件vue-treeselect,功能还是比较全的,模糊搜索.多选.延迟加载.异步搜索.排序,自定义.Vuex支持等等.这 ...
- 雷林鹏分享:jQuery EasyUI 表单 - 创建树形下拉框
jQuery EasyUI 表单 - 创建树形下拉框 树形下拉框(ComboTree)是一个带有下列树形结构(Tree)的下拉框(ComboBox).它可以作为一个表单字段进行使用,可以提交给远程服务 ...
- Dorado开发——树形下拉框
最近在学习Dorado开发的过程中,遇到了一个问题,Dorado的树形下拉框选择:Dorado默认情况下父节点和子节点都是可选的,而我要实现的是父节点不可选. 解决办法:在下拉框中,判断父子节点,点击 ...
- 树形下拉框ztree、获取ztree所有父节点,ztree的相关方法
参考:jQuery树形控件zTree使用小结 需求 添加.修改的终端需要选择组织,组织是多级架构(树状图显示). 思路 1.因为下拉框需要树状图显示,所以排除使用select做下拉框,改用input ...
- easyui-conbotree树形下拉框。。。转
最近一直在研究这个树形的下拉选择框,感觉非常的有用,现在整理下来供大家使用: 首先数据库的表架构设计和三级菜单联动的表结构是一样,(父子关系) 1.下面我们用hibernate建一下对应的额实体类: ...
- vue 树形下拉框 亲测 好用
https://vue-treeselect.js.org/ 顺带说一个开发中使用这个组件遇到的问题,关于回显之后无法修改的问题 找了很长时间 原因是数据类型导致的问题,数组里面应该是数字类型,直接 ...
- EasyUI:combotree(树形下拉框)复选框选中父节点(子节点的状态也全部选中)输入框中只显示父节点的文本值
参考: https://blog.csdn.net/weixin_43236850/article/details/100320564
- ligerui多选动态下拉框
今天下午要求做一个支持多选的,并且插件用ligerui的,当时有点小懵了,因为没用过ligerui啊!而且按照API的介绍,我做得也很好啊,可是为什么就是显示不出来?据说有位小神比较厉害,请教来之,两 ...
随机推荐
- IE8文件下载启用
在IE8的浏览器中,需要进行一些设置 Internet选项→安全→本地Intranet→自定义级别→下载→文件下载→启用 禁用迅雷下载:工具栏和扩展→迅雷下载支持→右键禁用
- c语言的学习秘籍之链表
刚翻出来的作品,有点低级,但希望能起到作用: #include<stdio.h>#include<stdlib.h>#include<time.h>#include ...
- mysql 5.0.46安装配置
http://os.chinaunix.net/a2008/0801/986/000000986346.shtml RPM包和源码包存放位置 /usr/local/src 源码包编译安装位置(pref ...
- [原创] 如何用Eclispe调试java -jar xxx.jar 方式执行的jar包
有时候,我们经常会需要调试 java -jar xxx.jar方式运行的代码,而不是必须在Eclipse中用Debug或者Run的方式运行.比如我们拿到的SourceCode不完整.Java提供了一种 ...
- 五步教你实现使用Nginx+uWSGI+Django方法部署Django程序
Django的部署可以有很多方式,采用nginx+uwsgi的方式是其中比较常见的一种方式. 在这种方式中,我们的通常做法是,将nginx作为服务器最前端,它将接收WEB的所有请求,统一管理请求.ng ...
- APICloud开发App总结(一)
apiCloud app 开发是最近一两年刚刚兴起的一种混合开发方式.常用的模块以原生方式开发好,然后用js进行粘合.组织,完成整个的app的逻辑.这种开发方式极大的提高了软件模块的复用率,加快了ap ...
- Android中仿淘宝首页顶部滚动自定义HorizontalScrollView定时水平自动切换图片
Android中仿淘宝首页顶部滚动自定义HorizontalScrollView定时水平自动切换图片 自定义ADPager 自定义水平滚动的ScrollView效仿ViewPager 当遇到要在Vie ...
- [MKRCVCD]Burning SDK report AddFile error
在使用Pipe通信的使用,我使用GetProcessExitCode这个函数来获取返回值.而ExitCode的定义为DWORD DWORD的原型为unsigned long,在32位程序中,DWORD ...
- Microsoft.CompactFramework.CSharp.targets not found
今天打开VS2008的智能设备项目,报以下错误,应该是文件找不到了. The imported project "C:\WINDOWS\Microsoft.NET\Framework\v3. ...
- 虚拟机中Linux系统盘空间不足
虚拟机中Linux系统盘在使用过程中, 出现空间不足的提示. 使用命令du --max-depth=1 -h 查看Home目录下各个文件占用空间, 发现是./cache(隐藏文件)占用很大空间.进入c ...