因需(产)求(品)要求,将原由“Ext.ux.form.LovCombo”实现的下拉多选(框)改为复选(框,Checkbox?CheckboxGroup)样(还得可全选),又因数据的加载获取、提交保存均是加“;”(/“,”)形式的字符串,后台程序改起来也可,但就是改动涉及的文件(类)项比较多,又怕影响到别的模块的数据,也就只能硬着头皮通过继承 CheckboxGroup(Ext.form)来实现咯。
刚接触 Ext,也没有动手做过,啥都不清楚,问同事,也说得不很清楚,只能看着源码(ext-3.4.1.1-gpl.zip)慢慢摸索着测试者来实现咯(测试运行在 Ext JS Library 3.4.0 版本)。整个实现过程挺痛苦,源码实在看不透,G 哥又躲躲闪闪,D 娘总非所需,中途好几次都想放弃(通过后台直接改),不过最终还是“生”出来啦,*^ο^*,特与大家分享、讨论,优化,共进步!
选择“禁北上广”全选:
设置“disabled”并提交:
重新加载设置“disabled”提交的数据
/** * CheckboxGroup(可含全选,可 disabled) * 提交/加载数据格式都为由“;”(this.valueSeparator)分割的字符串 */ Ext.ns('Ext.ux.form'); Ext.ux.form.YtCheckboxGroup = Ext.extend(Ext.form.CheckboxGroup, { // 隐藏域名(不能与name相同,若相同,name 置为 Ext 自动生成值) hiddenName: "", // 格式 [{id: inputValue, text: boxLabel}] store: null, valueSeparator: ";", // 是否需要全选按钮 isCheckedAllField: true, // 全选按钮域名(显示值) checkedAllFieldBoxLabel: "全选", // 全选按钮域值 checkedAllFieldInputValue: -1, initComponent: function() { Ext.ux.form.YtCheckboxGroup.superclass.initComponent.call(this); }, onRender: function(ct, position){ if(this.name == this.hiddenName){ this.name = ""; } this.items = []; if(this.isCheckedAllField){ var checkedAll = { boxLabel: this.checkedAllFieldBoxLabel, name: this.name, inputValue: this.checkedAllFieldInputValue }; this.items.push(checkedAll); } this.store.each(function(record, index){ var checkbox = {}; checkbox = {name: this.name, boxLabel: record.data["text"], inputValue: record.data["id"], checked: false}; this.items.push(checkbox); }, this); if(this.items && 0 < this.items.length){ Ext.ux.form.YtCheckboxGroup.superclass.onRender.call(this, ct, position); // 添加隐藏域 if(this.hiddenName && this.el){ this.hiddenField = this.el.insertSibling({tag:'input', type:'hidden', name: this.hiddenName, id: (this.hiddenId || Ext.id())}, 'before', true); } } }, // checke/change 事件(覆盖自 CheckboxGroup) fireChecked: function(checkbox, checked){ if(this.isCheckedAllField && this.checkedAllFieldInputValue == checkbox.inputValue){ this.checkedAllChecked(checkbox, checked); // 全选项选择动作处理 } else { this.checkboxChecked(checkbox, checked); // 普通有效项选择动作处理 } }, // 全选项选择动作处理 checkedAllChecked: function(checkbox, checked){ if(checkbox.inputValue == this.checkedAllFieldInputValue){ if(checked){ this.checkedAll(checkbox); } else { this.deCheckedAll(checkbox); } } }, // 普通有效项选择动作处理 checkboxChecked: function(checkbox, checked){ // 有效选择项(不含全选项) var validCheckedItems = []; this.eachItem(function(item){ if(item.checked){ if(this.checkedAllFieldInputValue != item.inputValue){ validCheckedItems.push(item); } } }, this); // 设置隐藏域值 this.setHiddenValue(validCheckedItems); // 已选择 checkbox 数 var validChedkedCount = (validCheckedItems && 0 < validCheckedItems.length)? validCheckedItems.length: -1; if(this.isCheckedAllField){ if(checked){ this.checkedAll(null, validChedkedCount); } else { this.deCheckedAll(null, validChedkedCount); } } if(!this.allowBlank){ this.fireEvent('change', this, validCheckedItems); // 验证不空事件 } }, // 设置隐藏域值(提交数据) setHiddenValue: function(checkedValues){ var hiddenValue = ""; if(0 < checkedValues.length){ for(var i = 0; i < checkedValues.length; ++i){ if(this.checkedAllFieldInputValue != checkedValues[i].inputValue){ if(0 != i){ hiddenValue += this.valueSeparator + checkedValues[i].inputValue; } else { hiddenValue += checkedValues[i].inputValue; } } } } this.hiddenField.value = hiddenValue; }, // 全选 checkedAll: function(checkbox, validChedkedCount){ if(!this.isCheckedAllField){ return; } if(checkbox && this.checkedAllFieldInputValue == checkbox.inputValue){ this.eachItem(function(item){ if(this.checkedAllFieldInputValue != item.inputValue && !item.checked){ item.setValue(true); } }, this); } if(this.items.length == (validChedkedCount + 1)){ this.eachItem(function(item){ if(this.checkedAllFieldInputValue == item.inputValue){ item.un('check', this.fireChecked, this); item.un('check', this.checkeded, this); item.setValue(true); item.on('check', this.fireChecked, this); } }, this); } }, // 取消全选 deCheckedAll: function(checkbox, validChedkedCount){ if(!this.isCheckedAllField){ return; } if(checkbox && this.checkedAllFieldInputValue == checkbox.inputValue){ this.eachItem(function(item){ if(this.checkedAllFieldInputValue != item.inputValue && item.checked){ item.setValue(false); } }, this); } if(this.items.length == (validChedkedCount + 2)){ this.eachItem(function(item){ if(this.checkedAllFieldInputValue == item.inputValue){ item.un('check', this.fireChecked, this); item.setValue(false); item.on('check', this.fireChecked, this); } }, this); } }, getName: function(){ return this.hiddenName? this.hiddenName: this.name; }, setValue: function(value){ /*this.eachItem(function(item){ item.setValue(false); });*/ this.reset(); // data[this.hiddenName] var values = value; if(null == values || "" == values){ return; } var inputValues = values.split(this.valueSeparator); this.eachItem(function(item){ if(this.checkedAllFieldInputValue != item.inputValue // 去全选 && null != inputValues && 0 < inputValues.length){ for(var i = 0; i < inputValues.length; ++i){ if(inputValues[i] == item.inputValue){ item.setValue(true); // this.preItems.push(item); } } } }); }, onDisable : function(){ Ext.ux.form.YtCheckboxGroup.superclass.onDisable.call(this); this.hiddenField.disabled = true; // 设置为 true,数据只显示,不提交 }, onEnable : function(){ Ext.ux.form.YtCheckboxGroup.superclass.onEnable.call(this); this.hiddenField.disabled = false; } }); Ext.reg('ytCheckboxGroup', Ext.ux.form.YtCheckboxGroup);