Ext.form.ComboBoxTree 下拉树 下拉多选树

源代码:

 2012年7月27日更新 修复了选择后通过getValue无法获取值的bug.

/**
 * @author 哈哈的快 QQ:20151481
 * @link http://blog.csdn.net/hahadekuai/article/details/7769093
 * @version 1.4
 * @date 2012-7-27 9:10
 */
if ('function' !== typeof RegExp.escape) {
	RegExp.escape = function(s) {
		if ('string' !== typeof s) {
			return s
		}
		return s.replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1')
	}
}

Ext.form.ComboBoxTree = Ext.extend( Ext.form.ComboBox, {
	checkField		: 'checked',
	displayField	: "TEXT",
	valueField		: "VALUE",
	parentField		: "PARENTID",
	dataRoot		: "root",
	separator		: ",",
	rootText		: "主菜单",
	rootValue		: -1,
	rootVisible		: false,
	triggerAction	: "all",
	//lazyInit		: false,
	/** @selectNodeModel
	 * all : 所有结点都可选中
	 * exceptRoot : 除根结点,其它结点都可选
	 * folder : 只有目录(非叶子和非根结点)可选
	 * leaf :只有叶子结点可选
	 */
	selectNodeModel	: 'all',
	mode			: "local",
	editable		: false,
	emptyText		: '请选择...',
	constructor : function(){
		Ext.form.ComboBoxTree.superclass.constructor.apply(this, arguments);
		this.maxHeight = this.maxHeight || this.height;
		if(!this.store){
			this.store = new Ext.data.JsonStore({
				autoLoad	: true,
				url			: this.url,
				root		: this.dataRoot,
				fields		: [
					{name : this.displayField},
					{name : this.valueField},
					{name : this.parentField}
				]
			});
		}
		this.store.on({
			scope : this,
			load : function(store){
				this.getValue()&&this.setValue(this.getValue());
				if(this.tree){
					this.loadData();
				}
			}
		})
	},
	initList : function(){
        if(!this.list){
            var cls = 'x-combo-list';

            this.list = new Ext.Layer({
                parentEl	: this.getListParent(),
                shadow		: this.shadow,
                cls			: [cls, this.listClass].join(' '),
                constrain	: false
            });

            var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth);
            this.list.setSize(lw, 0);
            this.assetHeight = 0;
            if(this.syncFont !== false){
                this.list.setStyle('font-size', this.el.getStyle('font-size'));
            }

            this.innerList = this.list.createChild({cls:cls+'-inner'});
            this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
			
			if(!this.tree){
				this.tree = new Ext.tree.TreePanel({ 
					root	: new Ext.tree.TreeNode({
						text	: this.rootText,
						id		: this.rootValue,
						expanded: true
					}),
					selectNodeModel	: this.selectNodeModel,
					border			: false,
					rootVisible		: this.rootVisible,
					autoHeight		: true,
					renderTo		: this.innerList
				});

				this.tree.on({
					scope : this,
					checkchange : this.onCheckChange,
					expandnode : function(nodep){
						this.tree.suspendEvents();
						var values = this.getCheckedValue().split(this.separator);
						nodep.cascade(function(node){
							node.getUI().toggleCheck(false);
							node.attributes.checked=false;
							for(var i = 0 ; i < values.length;i++){
								if("" + node.attributes[this.valueField] === values[i]){
									node.getUI().toggleCheck(true);
									node.attributes.checked=true;
									break;
								}
							}
						},this);
						this.tree.resumeEvents();
						this.restrictHeight();
					},
					
					// 取消双击事件
					beforedblclick  : function(){
						return false;
					}
				})
				if(this.store.getCount()>0){
					this.loadData();
				}
			}

            if(this.resizable){
                this.resizer = new Ext.Resizable(this.list,{
                   pinned : true,
				   handles:'se'
                });
                this.mon(this.resizer, 'resize', function(r, w, h){
                    this.maxHeight = h-this.handleHeight-this.list.getFrameWidth('tb')-this.assetHeight;
                    this.listWidth = w;
                    this.innerList.setWidth(w - this.list.getFrameWidth('lr'));
                    this.restrictHeight();
                }, this);

                this[this.pageSize?'footer':'innerList'].setStyle('margin-bottom', this.handleHeight+'px');
            }
        }
    },
	
	onCheckChange : function(node,checked) {
		var isRoot = (node == this.tree.getRootNode());
		var selModel = this.selectNodeModel;
		var isLeaf = node.isLeaf();
		if (isRoot && selModel != 'all') {
			return;
		} else if (selModel == 'folder' && isLeaf) {
			return;
		} else if (selModel == 'leaf' && !isLeaf) {
			return;
		}
		var r = this.findRecord(this.valueField, node.attributes[this.valueField]);
		if(r){
			r["data"][this.checkField] = checked;
		}
		this.setValue(this.getCheckedValue());
	},
	
	expand: function() {
		if (this.isExpanded() || !this.hasFocus) {
			return;
		}
		this.assetHeight = 0;
		if (this.bufferSize) {
			this.doResize(this.bufferSize);
			delete this.bufferSize;
		}
		this.restrictHeight();
		this.list.alignTo.apply(this.list, [this.el].concat(this.listAlign));
		this.list.setZIndex(this.getZIndex());
		this.list.show();
		if (Ext.isGecko2) {
			this.innerList.setOverflow('auto');
		}
		this.mon(Ext.getDoc(), {
			scope: this,
			mousewheel: this.collapseIf,
			mousedown: this.collapseIf
		});
		this.fireEvent('expand', this);
	},
	
	loadData : function(){
		var data = [];
		this.store.each(function(item,index){
			/**此处进行数据复制*/
			data.push(Ext.apply({},item.data));
		},this);
		var treedata = this.formatData(data);
		this.tree.getRootNode().appendChild(treedata);
		this.tree.getRootNode().expandChildNodes();
	},
	
	formatData : function (data){
		var len = data.length;
		var r = [], b = {},
			p = this.parentField,
			v = this.valueField,
			d = this.displayField,
			s = this.rootValue;
		for(var i = 0; i < len; i ++){
			var item = data[i];
				item["text"]=item[d];
				item["id"]=item[v];
				item.checked = false;
			if(item[p]==s){
				r.push(item);
				continue;
			}
			if(!b["_"+item[p]]){
				for(var a = 0 ; a < len; a++){
					var t = data[a];
					if(item[p]==t[v]){
						if(t[p]==s&&!b["_"+t[v]]){
							b["_"+t[v]] = t;
							b["_"+t[v]].leaf = false;
						}
						if(!t["children"])t["children"]=[];
						t.leaf = false;
						t["children"].push(item);
						item.leaf = true;
						item.checked = false;
						break;
					}
				}
				continue;
			}
			if(!b["_"+item[p]]["children"]){
				b["_"+item[p]]["children"] = [];
				b["_"+item[p]].leaf = false;
			}
			item.leaf = true;
			item.checked = false;
			b["_"+item[p]]["children"].push(item);
			continue;
		}
		return 	r;
	},
	
	clearValue: function() {
		this.value = '';
		this.setRawValue(this.value);
		var root = this.tree.getRootNode();
		root.cascade(function(node){
			if (node.attributes.checked) {
				node.getUI().toggleCheck(false);
				node.attributes.checked=false;
			}
		},this)
		if(this.hiddenField) {
			this.hiddenField.value = ''
		}
		this.applyEmptyText()
	},

	getCheckedDisplay: function() {
		var re = new RegExp(this.separator, "g");
		return this.getCheckedValue(this.displayField).replace(re, this.separator + ' ')
	},
	getCheckedValue: function(field) {
		field = field || this.valueField;
		var c = [];
		var snapshot = this.store.snapshot || this.store.data;
		snapshot.each(function(r) {
			if (r.get(this.checkField)) {
				c.push(r.get(field))
			}
		},this);
		return c.join(this.separator)
	},
	
	setValue: function(v) {
		if (typeof v != 'undefined') {
			v = '' + v;
			this.value =  v;
			this.store.clearFilter();
			this.store.each(function(r) {
				var checked = !(!v.match('(^|' + this.separator + ')' + RegExp.escape(r.get(this.valueField)) + '(' + this.separator + '|$)'));
				r.set(this.checkField, checked);
				if(checked)console.log(r);
			},this);
			this.setRawValue(this.store.getCount()>0 ? this.getCheckedDisplay() : this.value);
			if (this.hiddenField) {
				this.hiddenField.value = this.value
			}
			if (this.el) {
				this.el.removeClass(this.emptyClass)
			}
		} else {
			this.clearValue()
		}
	},

	getValue: function() {
		return typeof this.value != 'undefined' ? this.value : '';
	},

	onSelect : Ext.emptyFn,
	select : Ext.emptyFn,
	onViewOver : Ext.emptyFn,
	onViewClick : Ext.emptyFn,
	assertValue : Ext.emptyFn,
	beforeBlur : Ext.emptyFn
});




 

 


测试代码:

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>多选下拉树</title>
    <link rel="stylesheet" type="text/css" href="http://127.0.0.1:8090/GMMP/ext-3.4.0/resources/css/ext-all.css" />
    
    <script type="text/javascript" src="http://127.0.0.1:8090/GMMP/ext-3.4.0/adapter/ext/ext-base.js"> </script>
    <script type="text/javascript" src="http://127.0.0.1:8090/GMMP/ext-3.4.0/ext-all.js"> </script>

    <script type="text/javascript" src="treeCombo.js"></script>
	<style>
	</style>
</head>
<body>
</body>
</html>
<script>
var comboTree = new Ext.form.ComboBoxTree({
	mode			: "local",
	fieldLabel		: "多选下拉",
	hiddenName		: "mutliselect",
	name			: "mutliselect",
	url				: "data.json",
	//typeAhead		: true,
	selectNodeModel	: "all",
	displayField	: "TEXT",
	valueField		: "VALUE",
	parentField		: "PID",
	rootValue		: -1,
	dataRoot		: "datasource",
	//value			: 0,
	width			: 220,
	resizable 		: true,
	value			: "5,584",
	store			: new Ext.data.JsonStore({
		autoLoad	: true,
		url			: "data.json",
		root		: "datasource",
		fields		: [
			{name : "TEXT"},
			{name : "VALUE"},
			{name : "PID"}
		]
	})
})
var panel = new Ext.FormPanel({
	title : "测试",
	renderTo : document.body,
	items : comboTree
});
</script>


 


 

 

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 19
    评论
Ext.js 3是一个JavaScript框架,用于构建Web应用程序。在Ext.js 3中,要实现多选下拉(MultiSelect Combobox),可以使用Ext.ux.form.MultiSelect组件来实现。 首先,我们需要引入相应的Ext.js文件和MultiSelect组件的文件。 ```javascript <script type="text/javascript" src="extjs/ext-all.js"></script> <script type="text/javascript" src="ext-ux/src/widgets/form/MultiSelect.js"></script> ``` 接下来,我们可以创建一个下拉框,并将其转换为多选下拉框。 ```javascript new Ext.form.MultiSelect({ fieldLabel: '多选下拉', name: 'multiselect', width: 300, height: 150, store: new Ext.data.ArrayStore({ fields: ['value', 'text'], data: [ ['1', '选项1'], ['2', '选项2'], ['3', '选项3'], ['4', '选项4'], ['5', '选项5'] ] }), valueField: 'value', displayField: 'text', mode: 'local', emptyText: '请选择', selectOnFocus: true, delimiter: ',' }); ``` 在上面的代码中,我们创建了一个MultiSelect组件,并将其放置在一个表单中。该组件的name属性用于表单提交时的字段名,width和height属性用于设置组件的宽度和高度。store属性为组件提供数据源,该数据源可以是一个数组或者一个Ext.data.Store对象。valueField属性用于指定值字段,displayField属性用于指定显示的字段。mode属性设置为'local',表示数据源来自本地数据。emptyText属性用于设置默认的空文本,selectOnFocus属性设置为true,在组件获得焦点时自动选中已选择的值。delimiter属性用于设置值之间的分隔符。 以上就是使用Ext.js 3实现多选下拉的简单示例,通过这个示例,我们可以根据实际需求进行灵活的配置和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值