Extjs 中实现combox多选,已经解决了原有的bug 【选择多条记录后,鼠标点击其他空白处,选择的数据丢失,】

来源:互联网 发布:淘宝找黑客改成绩 编辑:程序博客网 时间:2024/04/27 15:15

需求说明,今天在需求时候,顾客在要求可以从多个部门查询,于是乎做了这个。


实现结果:


实现代码

保存为Ext.ux.form.LovCombo在项目中引用

// vim: ts=4:sw=4:nu:fdc=4:nospell/** * Ext.ux.form.LovCombo, List of Values Combo * * @author    Ing. Jozef Sakáloš * @copyright (c) 2008, by Ing. Jozef Sakáloš * @date      16. April 2008 * @version   $Id: Ext.ux.form.LovCombo.js 285 2008-06-06 09:22:20Z jozo $ * * @license Ext.ux.form.LovCombo.js is licensed under the terms of the Open Source * LGPL 3.0 license. Commercial use is permitted to the extent that the  * code/component(s) do NOT become part of another Open Source or Commercially * licensed development library or toolkit without explicit permission. *  * License details: http://www.gnu.org/licenses/lgpl.html */ /*global Ext */// add RegExp.escape if it has not been already addedif('function' !== typeof RegExp.escape) {RegExp.escape = function(s) {if('string' !== typeof s) {return s;}// Note: if pasting from forum, precede ]/\ with backslash manuallyreturn s.replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');}; // eo function escape}// create namespaceExt.ns('Ext.ux.form'); /** * * @class Ext.ux.form.LovCombo * @extends Ext.form.ComboBox */Ext.ux.form.LovCombo = Ext.extend(Ext.form.ComboBox, {// {{{    // configuration options/** * @cfg {String} checkField name of field used to store checked state. * It is automatically added to existing fields. * Change it only if it collides with your normal field. */ checkField:'checked'/** * @cfg {String} separator separator to use between values and texts */    ,separator:','/** * @cfg {String/Array} tpl Template for items.  * Change it only if you know what you are doing. */// }}}    // {{{    ,initComponent:function() {        // template with checkboxif(!this.tpl) {this.tpl =  '<tpl for=".">'+'<div class="x-combo-list-item">'+'<img src="' + Ext.BLANK_IMAGE_URL + '" '+'class="ux-lovcombo-icon ux-lovcombo-icon-'+'{[values.' + this.checkField + '?"checked":"unchecked"' + ']}">'+'<div class="ux-lovcombo-item-text">{' + (this.displayField || 'text' )+ '}</div>'+'</div>'+'</tpl>';}         // call parent        Ext.ux.form.LovCombo.superclass.initComponent.apply(this, arguments);// install internal event handlersthis.on({ scope:this,beforequery:this.onBeforeQuery,blur:this.onRealBlur});// remove selection from input fieldthis.onLoad = this.onLoad.createSequence(function() {if(this.el) {var v = this.el.dom.value;this.el.dom.value = '';this.el.dom.value = v;}});     } // e/o function initComponent    // }}}// {{{/** * Disables default tab key bahavior * @private */,initEvents:function() {Ext.ux.form.LovCombo.superclass.initEvents.apply(this, arguments);// disable default tab handling - does no goodthis.keyNav.tab = false;} // eo function initEvents// }}}// {{{/** * clears value */,clearValue:function() {this.value = '';this.setRawValue(this.value);this.store.clearFilter();this.store.each(function(r) {r.set(this.checkField, false);}, this);if(this.hiddenField) {this.hiddenField.value = '';}this.applyEmptyText();} // eo function clearValue// }}}// {{{/** * @return {String} separator (plus space) separated list of selected displayFields * @private */,getCheckedDisplay:function() {var re = new RegExp(this.separator, "g");return this.getCheckedValue(this.displayField).replace(re, this.separator + ' ');} // eo function getCheckedDisplay// }}}// {{{/** * @return {String} separator separated list of selected valueFields * @private */,getCheckedValue:function(field) {field = field || this.valueField;var c = [];// store may be filtered so get all recordsvar 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);} // eo function getCheckedValue// }}}// {{{/** * beforequery event handler - handles multiple selections * @param {Object} qe query event * @private */,onBeforeQuery:function(qe) {qe.query = qe.query.replace(new RegExp(this.getCheckedDisplay() + '[ ' + this.separator + ']*'), '');} // eo function onBeforeQuery// }}}// {{{/** * blur event handler - runs only when real blur event is fired */,onRealBlur:function() {this.list.hide();var rv = this.getRawValue();var rva = rv.split(new RegExp(RegExp.escape(this.separator) + ' *'));var va = [];var snapshot = this.store.snapshot || this.store.data;// iterate through raw values and records and check/uncheck itemsExt.each(rva, function(v) {snapshot.each(function(r) {if(v === r.get(this.displayField)) {va.push(r.get(this.valueField));}}, this);}, this);this.setValue(va.join(this.separator));this.store.clearFilter();} // eo function onRealBlur// }}}// {{{/** * Combo's onSelect override * @private * @param {Ext.data.Record} record record that has been selected in the list * @param {Number} index index of selected (clicked) record */,onSelect:function(record, index) {        if(this.fireEvent('beforeselect', this, record, index) !== false){// toggle checked fieldrecord.set(this.checkField, !record.get(this.checkField));// display full listif(this.store.isFiltered()) {this.doQuery(this.allQuery);}// set (update) value and fire eventthis.setValue(this.getCheckedValue());            this.fireEvent('select', this, record, index);        }} // eo function onSelect// }}}// {{{/** * Sets the value of the LovCombo * @param {Mixed} v value */,setValue:function(v) {if(v) {v = '' + v;if(this.valueField) {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);}, this);this.value = this.getCheckedValue();this.setRawValue(this.getCheckedDisplay());if(this.hiddenField) {this.hiddenField.value = this.value;}}else {this.value = v;this.setRawValue(v);if(this.hiddenField) {this.hiddenField.value = v;}}if(this.el) {this.el.removeClass(this.emptyClass);}}else {this.clearValue();}} // eo function setValue// }}}// {{{/** * Selects all items */,selectAll:function() {        this.store.each(function(record){            // toggle checked field            record.set(this.checkField, true);        }, this);        //display full list        this.doQuery(this.allQuery);        this.setValue(this.getCheckedValue());    } // eo full selectAll// }}}// {{{/** * Deselects all items. Synonym for clearValue */    ,deselectAll:function() {this.clearValue();    } // eo full deselectAll // }}}// 修正 : 当多选控件放到grid中时,grideditor会调用combobox中的这个方法。将选中的显示值传入到setvalue中,导致选择丢失。      ,assertValue : function(){          var val = this.getRawValue(),              rec,arr_rec,i=0;          // 分离value为数组,循环取rec          var arr_val = val.split(this.separator);          var arr_value = this.value.split(this.separator);          for(;i<arr_val.length;i++){              if(this.valueField && Ext.isDefined(arr_value[i])){                  rec = this.findRecord(this.valueField, arr_value[i]);              }              if(!rec || rec.get(this.displayField) != arr_val[i].trim()){                  rec = this.findRecord(this.displayField, arr_val[i].trim());              }              if(rec && !arr_rec){                  arr_rec = [];              }              if(rec){                  arr_rec.push(rec);              }          }          if(!arr_rec && this.forceSelection){              if(val.length > 0 && val != this.emptyText){                  this.el.dom.value = Ext.value(this.lastSelectionText, '');                  this.applyEmptyText();              }else{                  this.clearValue();              }          }else{              if(arr_rec && this.valueField){                  // onSelect may have already set the value and by doing so                  // set the display field properly.  Let's not wipe out the                  // valueField here by just sending the displayField.                  if (this.value == val){                      return;                  }                  i = 0;                  val = "";                  var ival;                  for(;i<arr_rec.length;i++){                      ival = arr_rec[i].get(this.valueField);                      if(!ival){                          ival = arr_rec[i].get(this.displayField);                      }                      if(i ==0 ){                          val = ival;                      }else{                          val = val+","+ival;                      }                  }              }              this.setValue(val);          }      }}); // eo extend // register xtypeExt.reg('lovcombo', Ext.ux.form.LovCombo);  // eof

CSS

/** vim: ts=4:sw=4:nu:fdc=4:nospell * * Ext.ux.form.LovCombo CSS File * * @author    Ing.Jozef Sak谩lo拧 * @copyright (c) 2008, by Ing. Jozef Sak谩lo拧 * @date      5. April 2008 * @version   $Id: Ext.ux.form.LovCombo.css 189 2008-04-16 21:01:06Z jozo $ * * @license Ext.ux.form.LovCombo.css is licensed under the terms of the Open Source * LGPL 3.0 license. Commercial use is permitted to the extent that the  * code/component(s) do NOT become part of another Open Source or Commercially * licensed development library or toolkit without explicit permission. *  * License details: http://www.gnu.org/licenses/lgpl.html */.ux-lovcombo-icon {     width:16px;     height:16px;     float:left;     background-position: -1px -1px ! important;     background-repeat:no-repeat ! important; } .ux-lovcombo-icon-checked {     background: transparent url(../ext3/resources/images/default/menu/checked.gif); } .ux-lovcombo-icon-unchecked {     background: transparent url(../ext3/resources/images/default/menu/unchecked.gif); } /* eof */

注意调整你的checked.gif 和 uncheck.gif的位置


使用案例:

{                        anchor: "99%",                fieldLabel: "按部门查询",                        xtype: "lovcombo",                        name: "Q_teacherName_S_LK",                        hideOnSelect:false,                mode: "local",                editable: false,                triggerAction: "all",                valueField: "depName",                displayField: "depName",                store: new Ext.data.JsonStore({                    root: "result",                    autoLoad: true,                    url: __ctxPath + "/system/selectDepartment.action",                    fields: ["depId", "depName"]                })            }





原创粉丝点击