分享

Extjs 多选下拉框 Ext.ux.form.LovCombo默认选择及其它BUG修复版支持多选/全选/全不选ext3.x

 snafkin 2013-12-21

文件名:LovCombo.js

[javascript] view plaincopy
  1. if ('function' !== typeof RegExp.escape) {  
  2.     RegExp.escape = function(s) {  
  3.         if ('string' !== typeof s) {  
  4.             return s  
  5.         }  
  6.         return s.replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1')  
  7.     }  
  8. }  
  9. Ext.ns('Ext.ux.form');  
  10. Ext.ux.form.LovCombo = Ext.extend(Ext.form.ComboBox, {  
  11.     checkField: 'checked',  
  12.     separator: ',',  
  13.     initComponent: function() {  
  14.         Ext.ux.form.LovCombo.superclass.initComponent.call(this);  
  15.         this.tpl = ['<tpl for=".">',  
  16.                     '<div class="x-combo-list-item">',  
  17.                     '<img src="' + Ext.BLANK_IMAGE_URL + '" class="ux-lovcombo-icon ux-lovcombo-icon-',  
  18.                     '{[values.' + this.checkField + '?"checked":"unchecked"]}">',  
  19.                     '<div class="ux-lovcombo-item-text">{' + (this.displayField || 'text') + '}</div>',  
  20.                     '</div>',  
  21.                     '</tpl>'  
  22.                 ].join("");  
  23.   
  24.         this.on({  
  25.             scope: this,  
  26.             expand : function(){  
  27.                 this.getValue()&&this.setValue(this.getValue());  
  28.             }  
  29.         });  
  30.           
  31.         this.onLoad = this.onLoad.createSequence(function() {  
  32.             if (this.el) {  
  33.                 var v = this.el.dom.value;  
  34.                 this.el.dom.value = v  
  35.             }  
  36.         });  
  37.         this.store.on("load",function(){  
  38.             this.getValue()&&this.setValue(this.getValue());  
  39.         },this);  
  40.     },  
  41.     initEvents: function() {  
  42.         Ext.ux.form.LovCombo.superclass.initEvents.apply(this, arguments);  
  43.         this.keyNav.tab = false  
  44.     },  
  45.     clearValue: function() {  
  46.         this.value = '';  
  47.         this.setRawValue(this.value);  
  48.         this.store.clearFilter();  
  49.         this.store.each(function(r) {  
  50.             r.set(this.checkField, false)  
  51.         },this);  
  52.         if(this.hiddenField) {  
  53.             this.hiddenField.value = ''  
  54.         }  
  55.         this.applyEmptyText()  
  56.     },  
  57.     getCheckedDisplay: function() {  
  58.         var re = new RegExp(this.separator, "g");  
  59.         return this.getCheckedValue(this.displayField).replace(re, this.separator + ' ')  
  60.     },  
  61.     getCheckedValue: function(field) {  
  62.         field = field || this.valueField;  
  63.         var c = [];  
  64.         var snapshot = this.store.snapshot || this.store.data;  
  65.         snapshot.each(function(r) {  
  66.             if (r.get(this.checkField)) {  
  67.                 c.push(r.get(field))  
  68.             }  
  69.         },this);  
  70.         return c.join(this.separator)  
  71.     },  
  72.   
  73.     onBeforeQuery: function(qe) {  
  74.         qe.query = qe.query.replace(new RegExp(this.getCheckedDisplay() + '[ ' + this.separator + ']*'), '')  
  75.     },  
  76.   
  77.     onSelect: function(record, index) {  
  78.         if (this.fireEvent('beforeselect', this, record, index) !== false){  
  79.             record.set(this.checkField, !record.get(this.checkField));  
  80.             if (this.store.isFiltered()) {  
  81.                 this.doQuery(this.allQuery)  
  82.             }  
  83.             this.setValue(this.getCheckedValue());  
  84.             this.fireEvent('select', this, record, index)  
  85.         }  
  86.     },  
  87.     setValue: function(v) {  
  88.         if (v) {  
  89.             v = '' + v;  
  90.             if (this.valueField) {  
  91.                 this.store.clearFilter();  
  92.                 this.store.each(function(r) {  
  93.                     var checked = !(!v.match('(^|' + this.separator + ')' + RegExp.escape(r.get(this.valueField)) + '(' + this.separator + '|$)'));  
  94.                     r.set(this.checkField, checked)  
  95.                 },this);  
  96.                 this.value = this.getCheckedValue() || v;  
  97.                 this.setRawValue(this.store.getCount()>0 ? this.getCheckedDisplay() : this.value);  
  98.                 if (this.hiddenField) {  
  99.                     this.hiddenField.value = this.value  
  100.                 }  
  101.             } else {  
  102.                 this.value = v;  
  103.                 this.setRawValue(v);  
  104.                 if (this.hiddenField) {  
  105.                     this.hiddenField.value = v  
  106.                 }  
  107.             }  
  108.             if (this.el) {  
  109.                 this.el.removeClass(this.emptyClass)  
  110.             }  
  111.             if(this.selectall){  
  112.                 if(this.getCheckedValue().split(",").length == this.store.getCount()){  
  113.                     this.selectall.replaceClass("ux-combo-selectall-icon-unchecked","ux-combo-selectall-icon-checked");  
  114.                 }else{  
  115.                     this.selectall.replaceClass("ux-combo-selectall-icon-checked","ux-combo-selectall-icon-unchecked")  
  116.                 }  
  117.             }  
  118.         } else {  
  119.             this.clearValue()  
  120.         }  
  121.           
  122.     },  
  123.     initList : function(){  
  124.         if(!this.list){  
  125.             var cls = 'x-combo-list';  
  126.   
  127.             this.list = new Ext.Layer({  
  128.                 parentEl: this.getListParent(),  
  129.                 shadow: this.shadow,  
  130.                 cls: [cls, this.listClass].join(' '),  
  131.                 constrain:false  
  132.             });  
  133.   
  134.             var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth);  
  135.             this.list.setSize(lw, 0);  
  136.             this.list.swallowEvent('mousewheel');  
  137.             this.assetHeight = 0;  
  138.             if(this.syncFont !== false){  
  139.                 this.list.setStyle('font-size', this.el.getStyle('font-size'));  
  140.             }  
  141.             if(this.title){  
  142.                 this.header = this.list.createChild({cls:cls+'-hd', html: this.title});  
  143.                 this.assetHeight += this.header.getHeight();  
  144.             }  
  145.               
  146.             if(this.showSelectAll){  
  147.                 this.selectall = this.list.createChild({  
  148.                     cls:cls + 'item ux-combo-selectall-icon-unchecked ux-combo-selectall-icon',  
  149.                     html: "选择全部"  
  150.                 });  
  151.                 this.selectall.on("click",function(el){  
  152.                     if(this.selectall.hasClass("ux-combo-selectall-icon-checked")){  
  153.                         this.selectall.replaceClass("ux-combo-selectall-icon-checked","ux-combo-selectall-icon-unchecked");  
  154.                         this.deselectAll();  
  155.                     }else{  
  156.                         this.selectall.replaceClass("ux-combo-selectall-icon-unchecked","ux-combo-selectall-icon-checked")  
  157.                         this.selectAll();  
  158.                     }  
  159.                 },this);  
  160.                 this.assetHeight += this.selectall.getHeight();  
  161.             }  
  162.   
  163.             this.innerList = this.list.createChild({cls:cls+'-inner'});  
  164.             this.mon(this.innerList, 'mouseover', this.onViewOver, this);  
  165.             this.mon(this.innerList, 'mousemove', this.onViewMove, this);  
  166.             this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));  
  167.   
  168.             if(this.pageSize){  
  169.                 this.footer = this.list.createChild({cls:cls+'-ft'});  
  170.                 this.pageTb = new Ext.PagingToolbar({  
  171.                     store: this.store,  
  172.                     pageSize: this.pageSize,  
  173.                     renderTo:this.footer  
  174.                 });  
  175.                 this.assetHeight += this.footer.getHeight();  
  176.             }  
  177.   
  178.             if(!this.tpl){  
  179.                 this.tpl = '<tpl for="."><div class="'+cls+'-item">{' + this.displayField + '}</div></tpl>';  
  180.             }  
  181.   
  182.             this.view = new Ext.DataView({  
  183.                 applyTo: this.innerList,  
  184.                 tpl: this.tpl,  
  185.                 singleSelect: true,  
  186.                 selectedClass: this.selectedClass,  
  187.                 itemSelector: this.itemSelector || '.' + cls + '-item',  
  188.                 emptyText: this.listEmptyText  
  189.             });  
  190.   
  191.             this.mon(this.view, 'click', this.onViewClick, this);  
  192.   
  193.             this.bindStore(this.store, true);  
  194.   
  195.             if(this.resizable){  
  196.                 this.resizer = new Ext.Resizable(this.list,  {  
  197.                    pinned:true, handles:'se'  
  198.                 });  
  199.                 this.mon(this.resizer, 'resize', function(r, w, h){  
  200.                     this.maxHeight = h-this.handleHeight-this.list.getFrameWidth('tb')-this.assetHeight;  
  201.                     this.listWidth = w;  
  202.                     this.innerList.setWidth(w - this.list.getFrameWidth('lr'));  
  203.                     this.restrictHeight();  
  204.                 }, this);  
  205.   
  206.                 this[this.pageSize?'footer':'innerList'].setStyle('margin-bottom', this.handleHeight+'px');  
  207.             }  
  208.         }  
  209.     },  
  210.     expand : function(){  
  211.         if(this.isExpanded() || !this.hasFocus){  
  212.             //return;  
  213.         }  
  214.         this.list.alignTo(this.wrap, this.listAlign);  
  215.         this.list.show();  
  216.         if(Ext.isGecko2){  
  217.             this.innerList.setOverflow('auto'); // necessary for FF 2.0/Mac  
  218.         }  
  219.         Ext.getDoc().on({  
  220.             scope: this,  
  221.             mousewheel: this.collapseIf,  
  222.             mousedown: this.collapseIf  
  223.         });  
  224.         this.fireEvent('expand', this);  
  225.     },  
  226.     selectAll: function() {  
  227.         this.store.each(function(record) {  
  228.             record.set(this.checkField, true);  
  229.         },this);  
  230.         this.setValue(this.getCheckedValue());  
  231.         this.doQuery(this.allQuery);  
  232.     },  
  233.     deselectAll: function() {  
  234.         this.clearValue()  
  235.     },  
  236.     assertValue: Ext.emptyFn,  
  237.     beforeBlur: Ext.emptyFn  
  238. });  
  239. Ext.reg('lovcombo', Ext.ux.form.LovCombo);  

  1. .ux-combo-selectall{  
  2.     padding:3px;  
  3. }  
  4. .ux-combo-selectall-icon-checked{  
  5.     background: transparent url(../../ext-3.4.0/resources/images/default/menu/checked.gif);  
  6. }  
  7. .ux-combo-selectall-icon-unchecked {    
  8.     background: transparent url(../../ext-3.4.0/resources/images/default/menu/unchecked.gif);    
  9. }  
  10. .ux-combo-selectall-icon {  
  11.     text-indent:1.8em;  
  12.     background-position: 3px 2px ! important;    
  13.     background-repeat:no-repeat ! important;    
  14.     height:22px;  
  15.     line-height:20px;  
  16.     font-size:12px;  
  17.     font-weight:bold;  
  18.     -moz-user-select:none;  
  19. }   


 

要显示选择全部按钮修改属性 showSelectAll 为true;


示例代码:

文件名: combo.html

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www./TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  2. <html xmlns="http://www./1999/xhtml">  
  3. <head>  
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
  5. <link rel="stylesheet" type="text/css"   href="../../ext-3.4.0/resources/css/ext-all.css" />  
  6. <link rel="stylesheet" type="text/css"   href="../../ext-3.4.0/resources/css/ext-patch.css" />  
  7. <link rel="stylesheet" type="text/css" href="../../css/multiselect.css"/>  
  8. <script type="text/javascript" src="../../ext-3.4.0/adapter/ext/ext-base-debug.js"></script>  
  9. <script type="text/javascript" src="../../ext-3.4.0/ext-all-debug.js"></script>  
  10. <script type="text/javascript" src="../LovCombo.js"></script>  
  11. <title>无标题文档</title>  
  12. </head><body>  
  13. </body>  
  14. </html>  
  15. <script>  
  16. Ext.namespace("Ext.ux.form");  
  17. var ds = new Ext.data.JsonStore({  
  18.     autoLoad: true,  
  19.     url     : "checkCombo.json",  
  20.     fields  : [  
  21.         {name: 'VALUE'},  
  22.         {name: 'TEXT'}  
  23.     ],  
  24.     root    : "datasource"  
  25. });  
  26. Ext.ux.form.LovCombo = Ext.form.LovCombo || Ext.ux.form.LovCombo;  
  27. var combox = new Ext.ux.form.LovCombo({  
  28.     renderTo        : Ext.getBody(),  
  29.     store           : ds,  
  30.     mode            : "local",  
  31.     fieldLabel      : "测试",  
  32.     displayField    : "TEXT",  
  33.     valueField      : "VALUE",  
  34.     hiddenName      : "ces",  
  35.     name            : "ces",  
  36.     triggerAction   : "all",  
  37.     id              : "cc",  
  38.     //width         : 220,  
  39.     //autoSelect        : true,  
  40.     value           : "8960,8970,8964,8965,8967,8980",  
  41.     //lazyInit      : true,  
  42.     showSelectAll   : true,  
  43.     resizable       : true  
  44. });  
  45. </script>  
测试数据:

文件名:checkCombo.json

[javascript] view plaincopy
  1. {"datasource":[{"VALUE":143360,"TEXT":"灵图软件1"},{"VALUE":143361,"TEXT":"灵图测试"},{"VALUE":8983,"TEXT":"别奇科技"},{"VALUE":8981,"TEXT":"北导科技"},{"VALUE":8982,"TEXT":"航大通讯"},{"VALUE":8984,"TEXT":"金坤老设备"},{"VALUE":8980,"TEXT":"奉节德瑞"},{"VALUE":8970,"TEXT":"四川科泰"},{"VALUE":8973,"TEXT":"重庆朝昇"},{"VALUE":8977,"TEXT":"重庆蓝盾"},{"VALUE":8961,"TEXT":"索美交通"},{"VALUE":8962,"TEXT":"广州亿程"},{"VALUE":8963,"TEXT":"德瑞科技"},{"VALUE":8964,"TEXT":"冀繁科技"},{"VALUE":8965,"TEXT":"移动车务通"},{"VALUE":8966,"TEXT":"金坤科技"},{"VALUE":8960,"TEXT":"运管企业平台"},{"VALUE":8975,"TEXT":"重庆方鼎科技"},{"VALUE":8976,"TEXT":"德瑞3G"},{"VALUE":8978,"TEXT":"宝石花"},{"VALUE":8979,"TEXT":"星软商务"},{"VALUE":8967,"TEXT":"金坤3G"},{"VALUE":8968,"TEXT":"全球鹰"},{"VALUE":8969,"TEXT":"重庆电信"},{"VALUE":8974,"TEXT":"重庆途众"},{"VALUE":8971,"TEXT":"重庆赛格"},{"VALUE":8972,"TEXT":"四川兆益"}]}  



    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约