扩展Ext的Combobox实现多选下拉列表
2012-03-01 14:35
489 查看
使用过Ext的人都知道,Ext的Combobox只支持单项选择,而项目中我们经常用到多选下拉框,怎么做呢?
很简单,因为Ext给我们提供了继承机制,这也意味着我们可以通过继承Combobox的方式来重写下拉列表的实现,达到多选的目的!
经过查看Combobox的源码我们发现,Combobox的下拉列表是由DataView类来实现的,那么,我们开始大胆的想:我们直接用一个带CheckBox的GridPanal来代替DataView实现可以吗?
OK,当然可以!我自己研究了一下,写了个代码,基本可以实现下拉框多选了:
怎么使用呢?看看这个使用的例子吧:
OK,目标达到!细心的朋友会发现,这个多选下拉列表使用的就是GridPanel实现的,而GirdPanel是可以支持分页的,那么我们可不以可以搞分页呢?肯定是可以的,但是经过我试了之后发现,加上分页控件后下拉列表展现变得非常难看,这个问题还是留给朋友们实现吧,呵呵可……
由于注册未满一周,不能上传效果图,大家还是拷贝源码下去自己运行吧……
很简单,因为Ext给我们提供了继承机制,这也意味着我们可以通过继承Combobox的方式来重写下拉列表的实现,达到多选的目的!
经过查看Combobox的源码我们发现,Combobox的下拉列表是由DataView类来实现的,那么,我们开始大胆的想:我们直接用一个带CheckBox的GridPanal来代替DataView实现可以吗?
OK,当然可以!我自己研究了一下,写了个代码,基本可以实现下拉框多选了:
Ext.form.MultiSelect = Ext.extend(Ext.form.ComboBox, { // 使用积极的初始化模式 lazyInit : false, headerText : "EMPTY", resetText : "EMPTY", sureText : "EMPTY", textValue : "", maxHeight : 310, beforeSelect : null, /** * 初始化下拉列表 原来的下拉列表使用DataView类来实现,现在改为使用GridPanel来实现,这样更方便于多选操作 */ initList : function() { if (!this.list) { var cls = 'x-combo-list'; this.list = new Ext.Layer( { shadow : this.shadow, cls : [ cls, this.listClass ].join(' '), constrain : false }); var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth); this.list.setWidth(lw); this.assetHeight = 0; if (this.title) { this.header = this.list.createChild( { cls : cls + '-hd', html : this.title }); this.assetHeight += this.header.getHeight(); } this.innerList = this.list.createChild( { cls : cls + '-inner' }); this.innerList.setWidth(lw - this.list.getFrameWidth('lr')); var sm = new Ext.grid.CheckboxSelectionModel(); var all = this; var ht = this.headerText == "EMPTY" ? "选择项目" : this.headerText; var rt = this.resetText == "EMPTY" ? "重置" : this.resetText; var st = this.sureText == "EMPTY" ? "确定" : this.sureText; this.view = new Ext.grid.GridPanel( { store : this.store, hideHeaders : true, applyTo : this.innerList, columns : [ sm, { header : ht, sortable : false, dataIndex : this.displayField } ], viewConfig : { forceFit : true }, autoScroll : true, width : this.list.getWidth(), sm : sm, tbar : new Ext.PagingToolbar({ pageSize: this.pageSize, store:this.store}), bbar : [ { xtype : "button", text : rt, handler : function() { all.onReset(); } }, "-", { xtype : "button", text : st, handler : function() { all.onSure(); } } ], iconCls : 'icon-grid' }); // 设置下拉列表的高度,如果超过了最大高度则使用最大高度 if (this.view.getSize().height > this.maxHeight) { this.view.setHeight(this.maxHeight); } // 如果设置了默认值,则在下拉列表中回显 if (this.value) { this.setValue(this.value); } if (this.pageSize) { /* * var pageBar = new Ext.PagingToolbar({ pageSize: 15, store: * this.view.getStore(), displayInfo: true }); * this.view.add(pageBar); this.view.doLayout(); */ } if (this.resizable) { this.resizer = new Ext.Resizable(this.list, { pinned : true, handles : 'se' }); this.resizer.on('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'); } } }, /** * 确定选择事件 */ onSure : function() { var selecteds = this.view.getSelectionModel().getSelections(); var value = []; var all = this; var tv = []; Ext.each(selecteds, function(rc) { value.push(rc.data[all.valueField]); tv.push(rc.data[all.displayField]); }); this.textValue = tv.join(); var valueStr = value.join(); beforeSelect = this.beforeSelect; if(typeof beforeSelect == 'function') { if(!beforeSelect(valueStr)) { this.collapse(); return; } } this.setValue(valueStr); this.value = value.join(); this.collapse(); }, getTextValue : function(){ return this.textValue; }, /** * 重置事件 */ onReset : function() { this.view.getSelectionModel().clearSelections(); }, /** * 给ComboBox设置值 * 设置完全局的值后,再在下拉列表中回显这些值 */ setValue : function(v) { var text = v; var ta = []; // 根据值查找出名称,并组装显示 if (this.valueField && v && ("" + v).length > 0) { var sv = ("" + v).split(","); for ( var i = 0; i < sv.length; i++) { var r = this.findRecord(this.valueField, sv[i]); if (r) { ta.push(r.data[this.displayField]); } else if (this.valueNotFoundText !== undefined) { ta.push(this.valueNotFoundText); } } text = ta.join(); } this.lastSelectionText = ta.join(); if (this.hiddenField) { this.hiddenField.value = v; } this.textValue = text; Ext.form.ComboBox.superclass.setValue.call(this, text); this.value = v; // 在下拉列表中回显设置的值 if (this.view && v && ("" + v).length > 0) { var sv = ("" + v).split(","); var mv = this.view; var sr = []; var all = this; this.store.each(function(item) { for ( var i = 0; i < sv.length; i++) { if (sv[i] == item.data[all.valueField]) { sr.push(item); break; } } }); this.view.getSelectionModel().selectRecords(sr); } }, /** * 触发下拉列表展现 这里不使用ComboBox的查询功能,直接展现 */ onTriggerClick : function() { if (this.disabled) { return; } if (this.isExpanded()) { this.collapse(); } else { this.onFocus( {}); this.expand(); this.el.focus(); } } });
怎么使用呢?看看这个使用的例子吧:
<html> <head> <script type="text/javascript" src="./ext-2.0.2/adapter/ext/ext-base.js"></script> <script type="text/javascript" src="./ext-2.0.2/ext-all.js"></script> <script type="text/javascript" src="./MultiCombo.js"></script> <link rel="stylesheet" type="text/css" href="./ext-2.0.2/resources/css/ext-all.css" /> </head> <body> <button onclick="showMenu(this)" id="heare">显示值</button> <div id="local-states"></div> </body> <script> var store = new Ext.data.SimpleStore({ fields : ['id', 'text'], data : [['1', '一月'], ['2', '三月'], ['3', '二月'], ['4', '四月'], ['5', '五月'], ['6', '六月'], ['7', '七月'], ['8', '八月'],['9', '九月'], ['10', '十月'], ['11', '十一月'], ['12', '十二月'],['13', '十三月'], ['14', '十四月'], ['15', '十五月']] }); var combo = new Ext.form.MultiSelect({ id : 'myCombo', name : 'name', hiddenName : 'id', store : store, emptyText : '请选择...', mode : 'local', value : '5,6,7', triggerAction : 'all', valueField : 'id', displayField : 'text', editable : false, pageSize : 5, beforeSelect : function(selectValues){ if(selectValues == '5') { return true; } else{ Ext.Msg.alert("alert", "Can not!"); return false; } }, blankText : '请选择...' }); combo.render("local-states"); function showMenu(){ alert(combo.getValue()); } </script> </html>
OK,目标达到!细心的朋友会发现,这个多选下拉列表使用的就是GridPanel实现的,而GirdPanel是可以支持分页的,那么我们可不以可以搞分页呢?肯定是可以的,但是经过我试了之后发现,加上分页控件后下拉列表展现变得非常难看,这个问题还是留给朋友们实现吧,呵呵可……
由于注册未满一周,不能上传效果图,大家还是拷贝源码下去自己运行吧……
相关文章推荐
- 扩展Ext的Combobox实现多选下拉列表
- 使用EXT实现ComboBox多列下拉列表
- 可输入可联想的下拉列表的实现——Ext ComboBox
- 可输入可联想的下拉列表的实现——Ext ComboBox
- C#中comboBox下拉框中实现多选
- Ext下拉 ComboBox多选拓展代码(超好用)
- TFS下拉列表实现多选
- ext-2.0扩展多选下拉框(代码及演示)
- ext-2.0扩展多选下拉框(代码及演示)
- Ext下拉 ComboBox多选拓展代码(超好用)
- 使用jquery-combobox实现select下拉框多选之后,如何将下拉框的值传给input隐藏域
- jquery实现多选下拉列表
- 重写winform 的 ComboBox控件实现自动加载磁盘下拉列表框
- 无序列表(Ul)实现下拉多选[Jquery方式]
- Ext.grid.EditorGridPanel 单元格套用下拉列表ComboBox
- JS实现支持多选的遍历下拉列表代码
- Ext中下拉列表ComboBox组件store数据格式用法介绍
- Extjs 3实现Combobox下拉列表的拼音过滤
- JS实现支持多选的遍历下拉列表代码