extjs 多选下拉框

[ http://blog.sina.com.cn/s/blog_5140a6a50100bfao.html],简要记录。


一. 自定义组建组建 Ext.form.MultiSelect,新建MultiSelect.js文件,目录自定,但页面上需要把这个js引入,该js文件如下:

[javascript] view plain copy print ?
  1. // vim: ts=4:sw=4:nu:fdc=4:nospell 
  2.   
  3. // add RegExp.escape if it has not been already added 
  4. if('function' !== typeof RegExp.escape) { 
  5. RegExp.escape = function(s) { 
  6.    if('string' !== typeof s) { 
  7.     return s; 
  8.    } 
  9.    // Note: if pasting from forum, precede ]/\ with backslash manually 
  10.    return s.replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); 
  11. }; // eo function escape 
  12. // create namespace 
  13. Ext.ns('Ext.form'); 
  14.  
  15. Ext.form.MultiSelect = Ext.extend(Ext.form.ComboBox, { 
  16. // {{{ 
  17.     // configuration options 
  18.  
  19. checkField:'checked' 
  20.  
  21.     ,separator:',' 
  22.  
  23. // }}} 
  24.     // {{{ 
  25.     ,initComponent:function() { 
  26.         
  27.    // template with checkbox 
  28.    if(!this.tpl) { 
  29.     this.tpl = 
  30.      '<tpl for=".">' 
  31.      +'<div class="x-combo-list-item">' 
  32.      +'<img src="' + Ext.BLANK_IMAGE_URL + '" ' 
  33.      +'class="ux-MultiSelect-icon ux-MultiSelect-icon-' 
  34.      +'{[values.' + this.checkField + '?"checked":"unchecked"' + ']}">' 
  35.      +'{[values.'+this.displayField+']}' 
  36.      +'</div>' 
  37.      +'</tpl>' 
  38.     ; 
  39.    } 
  40.         // call parent 
  41.         Ext.form.MultiSelect.superclass.initComponent.apply(this, arguments); 
  42.    // install internal event handlers 
  43.    this.on({ 
  44.     scope:this 
  45.     ,beforequery:this.onBeforeQuery 
  46.     ,blur:this.onRealBlur 
  47.    }); 
  48.    // remove selection from input field 
  49.    this.onLoad = this.onLoad.createSequence(function() { 
  50.     if(this.el) { 
  51.      var v = this.el.dom.value; 
  52.      this.el.dom.value = ''
  53.      this.el.dom.value = v; 
  54.     } 
  55.    }); 
  56.     } // e/o function initComponent 
  57.     // }}} 
  58. // {{{ 
  59.  
  60. ,initEvents:function() { 
  61.    Ext.form.MultiSelect.superclass.initEvents.apply(this, arguments); 
  62.    // disable default tab handling - does no good 
  63.    this.keyNav.tab = false
  64. } // eo function initEvents 
  65. // }}} 
  66. // {{{ 
  67.  
  68. ,clearValue:function() { 
  69.    this.value = ''
  70.    this.setRawValue(this.value); 
  71.    this.store.clearFilter(); 
  72.    this.store.each(function(r) { 
  73.     r.set(this.checkField, false); 
  74.    }, this); 
  75.    if(this.hiddenField) { 
  76.     this.hiddenField.value = ''
  77.    } 
  78.    this.applyEmptyText(); 
  79. } // eo function clearValue 
  80. // }}} 
  81. // {{{ 
  82.  
  83. ,getCheckedDisplay:function() { 
  84.    var re = new RegExp(this.separator, "g"); 
  85.    return this.getCheckedValue(this.displayField).replace(re, this.separator + ' '); 
  86. } // eo function getCheckedDisplay 
  87. // }}} 
  88. // {{{ 
  89.  
  90. ,getCheckedValue:function(field) { 
  91.    field = field || this.valueField; 
  92.    var c = []; 
  93.    // store may be filtered so get all records 
  94.    var snapshot = this.store.snapshot || this.store.data; 
  95.    snapshot.each(function(r) { 
  96.     if(r.get(this.checkField)) { 
  97.      c.push(r.get(field)); 
  98.     } 
  99.    }, this); 
  100.    return c.join(this.separator); 
  101. } // eo function getCheckedValue 
  102. // }}} 
  103. // {{{ 
  104.  
  105. ,onBeforeQuery:function(qe) { 
  106.    qe.query = qe.query.replace(new RegExp(RegExp.escape(this.getCheckedDisplay()) + '[ ' + this.separator + ']*'), ''); 
  107. } // eo function onBeforeQuery 
  108. // }}} 
  109. // {{{ 
  110.  
  111. ,onRealBlur:function() { 
  112.    this.list.hide(); 
  113.    var rv = this.getRawValue(); 
  114.    var rva = rv.split(new RegExp(RegExp.escape(this.separator) + ' *')); 
  115.    var va = []; 
  116.    var snapshot = this.store.snapshot || this.store.data; 
  117.    // iterate through raw values and records and check/uncheck items 
  118.    Ext.each(rva, function(v) { 
  119.     snapshot.each(function(r) { 
  120.      if(v === r.get(this.displayField)) { 
  121.       va.push(r.get(this.valueField)); 
  122.      } 
  123.     }, this); 
  124.    }, this); 
  125.    this.setValue(va.join(this.separator)); 
  126.    this.store.clearFilter(); 
  127. } // eo function onRealBlur 
  128. // }}} 
  129. // {{{ 
  130.  
  131. ,onSelect:function(record, index) { 
  132.         if(this.fireEvent('beforeselect', this, record, index) !== false){ 
  133.     // toggle checked field 
  134.     record.set(this.checkField, !record.get(this.checkField)); 
  135.     // display full list 
  136.     if(this.store.isFiltered()) { 
  137.      this.doQuery(this.allQuery); 
  138.     } 
  139.     // set (update) value and fire event 
  140.     this.setValue(this.getCheckedValue()); 
  141.             this.fireEvent('select', this, record, index); 
  142.         } 
  143. } // eo function onSelect 
  144. // }}} 
  145. // {{{ 
  146.  
  147. ,setValue:function(v) { 
  148.    if(v) { 
  149.     v = '' + v; 
  150.     if(this.valueField) { 
  151.      this.store.clearFilter(); 
  152.      this.store.each(function(r) { 
  153.       var checked = !(!v.match( 
  154.        '(^|' + this.separator + ')' + RegExp.escape(r.get(this.valueField)) 
  155.        +'(' + this.separator + '|$)')) 
  156.       ; 
  157.       r.set(this.checkField, checked); 
  158.      }, this); 
  159.      this.value = this.getCheckedValue(); 
  160.      this.setRawValue(this.getCheckedDisplay()); 
  161.      if(this.hiddenField) { 
  162.       this.hiddenField.value = this.value; 
  163.      } 
  164.     } 
  165.     else
  166.      this.value = v; 
  167.      this.setRawValue(v); 
  168.      if(this.hiddenField) { 
  169.       this.hiddenField.value = v; 
  170.      } 
  171.     } 
  172.     if(this.el) { 
  173.      this.el.removeClass(this.emptyClass); 
  174.     } 
  175.    } 
  176.    else
  177.     //this.clearValue(); 
  178.    } 
  179. } // eo function setValue 
  180. // }}} 
  181. // {{{ 
  182.  
  183. ,selectAll:function() { 
  184.         this.store.each(function(record){ 
  185.             // toggle checked field 
  186.             record.set(this.checkField, true); 
  187.         }, this); 
  188.         //display full list 
  189.         this.doQuery(this.allQuery); 
  190.         this.setValue(this.getCheckedValue()); 
  191.     } // eo full selectAll 
  192. // }}} 
  193. // {{{ 
  194.  
  195.     ,deselectAll:function() { 
  196.    this.clearValue(); 
  197.     } // eo full deselectAll 
  198. // }}} 
  199. }); // eo extend 
  200. // register xtype 
  201. Ext.reg('multiSelect', Ext.form.MultiSelect); 
// vim: ts=4:sw=4:nu:fdc=4:nospell
 
// add RegExp.escape if it has not been already added
if('function' !== typeof RegExp.escape) {
RegExp.escape = function(s) {
   if('string' !== typeof s) {
    return s;
   }
   // Note: if pasting from forum, precede ]/\ with backslash manually
   return s.replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
}; // eo function escape
}
// create namespace
Ext.ns('Ext.form');

Ext.form.MultiSelect = Ext.extend(Ext.form.ComboBox, {
// {{{
    // configuration options

checkField:'checked'

    ,separator:','

// }}}
    // {{{
    ,initComponent:function() {
       
   // template with checkbox
   if(!this.tpl) {
    this.tpl =
     '<tpl for=".">'
     +'<div class="x-combo-list-item">'
     +'<img src="' + Ext.BLANK_IMAGE_URL + '" '
     +'class="ux-MultiSelect-icon ux-MultiSelect-icon-'
     +'{[values.' + this.checkField + '?"checked":"unchecked"' + ']}">'
     +'{[values.'+this.displayField+']}'
     +'</div>'
     +'</tpl>'
    ;
   }
        // call parent
        Ext.form.MultiSelect.superclass.initComponent.apply(this, arguments);
   // install internal event handlers
   this.on({
    scope:this
    ,beforequery:this.onBeforeQuery
    ,blur:this.onRealBlur
   });
   // remove selection from input field
   this.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
    // }}}
// {{{

,initEvents:function() {
   Ext.form.MultiSelect.superclass.initEvents.apply(this, arguments);
   // disable default tab handling - does no good
   this.keyNav.tab = false;
} // eo function initEvents
// }}}
// {{{

,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
// }}}
// {{{

,getCheckedDisplay:function() {
   var re = new RegExp(this.separator, "g");
   return this.getCheckedValue(this.displayField).replace(re, this.separator + ' ');
} // eo function getCheckedDisplay
// }}}
// {{{

,getCheckedValue:function(field) {
   field = field || this.valueField;
   var c = [];
   // store may be filtered so get all records
   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);
} // eo function getCheckedValue
// }}}
// {{{

,onBeforeQuery:function(qe) {
   qe.query = qe.query.replace(new RegExp(RegExp.escape(this.getCheckedDisplay()) + '[ ' + this.separator + ']*'), '');
} // eo function onBeforeQuery
// }}}
// {{{

,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 items
   Ext.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
// }}}
// {{{

,onSelect:function(record, index) {
        if(this.fireEvent('beforeselect', this, record, index) !== false){
    // toggle checked field
    record.set(this.checkField, !record.get(this.checkField));
    // display full list
    if(this.store.isFiltered()) {
     this.doQuery(this.allQuery);
    }
    // set (update) value and fire event
    this.setValue(this.getCheckedValue());
            this.fireEvent('select', this, record, index);
        }
} // eo function onSelect
// }}}
// {{{

,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
// }}}
// {{{

,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
// }}}
// {{{

    ,deselectAll:function() {
   this.clearValue();
    } // eo full deselectAll
// }}}
}); // eo extend
// register xtype
Ext.reg('multiSelect', Ext.form.MultiSelect);
二. 下面就在你项目的js文件中调用上面 扩展的组建

[javascript] view plain copy print ?
  1. //任务状态JsonStore 
  2. var taskstatusStore = new Ext.data.JsonStore({ 
  3.    id:'optvalue'
  4.         remoteSort: false
  5.         fields: [ 
  6.          'optvalue'
  7.          'opttext' 
  8.   ], 
  9.         proxy: new Ext.data.HttpProxy({ 
  10.             url: 'operation/task/querytaskstatuslist.jsp' 
  11.         }) 
  12.     }); 
  13. //给下拉框设置默认值 
  14. taskstatusStore.load(); 
  15.     taskstatusStore.on('load',function(){ 
  16.      taskstatuscombo.setValue(3); 
  17. }); 
  18. var taskstatuscombo = new Ext.form.MultiSelect({ 
  19.   width:130, 
  20.   editable: false
  21.   store:taskstatusStore , 
  22.   valueField :"optvalue"
  23.   displayField: "opttext"
  24.   mode: 'local'
  25.   //forceSelection: true,一定不要声明此句 
  26.   triggerAction: 'all'
  27.   allowBlank:false
  28.   emptyText:'请选择' 
  29. }); 
//任务状态JsonStore
var taskstatusStore = new Ext.data.JsonStore({
   id:'optvalue',
        remoteSort: false,
        fields: [
         'optvalue',
         'opttext'
  ],
        proxy: new Ext.data.HttpProxy({
            url: 'operation/task/querytaskstatuslist.jsp'
        })
    });
//给下拉框设置默认值
taskstatusStore.load();
    taskstatusStore.on('load',function(){
     taskstatuscombo.setValue(3);
});
var taskstatuscombo = new Ext.form.MultiSelect({
  width:130,
  editable: false,
  store:taskstatusStore ,
  valueField :"optvalue",
  displayField: "opttext",
  mode: 'local',
  //forceSelection: true,一定不要声明此句
  triggerAction: 'all',
  allowBlank:false,
  emptyText:'请选择'
});

三. 可以多选了,但是,出现了个问题,下拉的 checkbox 没有显示,客户说可以,时间仓促,研究出原因后,再来补齐文档,呵呵。。。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值