作用:
在程序中,经常会遇到这种情况:即获取其它地方的参数,在本ComboBox中带上参数查询出结果,把结果中的某些字段值设置到所需要的地方(其它地方):
[同时在Grid中也支持],相关参数若不设置即就是普通的ComboBox!
Ext.ns("dnet.base"); dnet.base.AbstractCombo = Ext.extend(Ext.form.ComboBox, { _dataProviderFields_ :null //要顯示的字段即record($Model) ,_dataProviderName_ : null //組件名字 ,fieldMapping : null //設置到哪個Field中 ,paramMapping: null // ex: paramMapping: [{lovField:"...lovFieldName", dsField: "...dsFieldName"} ] ,callFromGrid:null //若此Combo則Grid中則需要設置(required if this combox in grid) ,storeUrl:null ,minChars:0 ,listEmptyText:"Can't find fit data !" /** 創建Store**/ ,_createStore_: function() { this.store = new Ext.data.Store({ remoteSort:true ,reader: new Ext.data.JsonReader( {totalProperty: 'totalCount',idProperty: 'id',root: 'data',messageProperty: 'message'} ,Ext.data.Record.create(this._dataProviderFields_) ) ,listeners: { "exception":{ fn: this.proxyException, scope:this }} ,url:this.storeUrl }) this.store.proxy.getConnection().async = false;//同步 } /** 更改了源碼中的doQuery方法,重寫 !**/ /*源碼中何處調用doQuery()方法 initQuery : function(){ this.doQuery(this.getRawValue()); }, */ ,doQuery : function(q, forceAll){ q = Ext.isEmpty(q) ? '' : q; var qe = { query: q, forceAll: forceAll, combo: this, cancel:false }; if(this.fireEvent('beforequery', qe)===false || qe.cancel){ return false; } q = qe.query; forceAll = qe.forceAll; if(forceAll === true || (q.length >= this.minChars)){ if( (this.lastQuery !== q) || (this.paramMapping != null && this.paramMapping.length>0) ){ this.lastQuery = q; if(this.mode == 'local'){ this.selectedIndex = -1; if(forceAll){ this.store.clearFilter(); }else{ this.store.filter(this.displayField, q); } this.onLoad(); }else{ //this.store.baseParams[this.queryParam] = q;//這是源碼中的code var bp = {} bp[this.queryParam]=q; if (this.paramMapping != null) { this._mapFilterFields_(bp); } /**若想將所有參數作為一個對象傳遞過去的話, * 可下一句改為this.store.baseParams["data"]=Ext.encode(bp) * 其中data是你傳遞過去的對象名. */ this.iteratorSetbaseParam(bp); this.store.load({ params: this.getParams(q) }); this.expand(); } }else{ this.selectedIndex = -1; this.onLoad(); } } } ,iteratorSetbaseParam:function(bp){ this.store.baseParams[this.queryParam]=bp[this.queryParam]; if(this.paramMapping !=null){ for(var i=0;i<this.paramMapping.length;i++){ this.store.baseParams[this.paramMapping[i].param]=bp[this.paramMapping[i].param]; } } } /** 如果設置了分頁pagesize大小,則store加載時會有分頁參數! **/ ,getParams : function(q){ // var p = {}; // //p[this.queryParam] = q; // if(this.pageSize){ // p.start = 0; // p.limit = this.pageSize; // } // return p; var params = {}, paramNames = this.store.paramNames; if(this.pageSize){ params[paramNames.start] = 0; params[paramNames.limit] = this.pageSize; } return params; } /** 更改了源碼中的assertValue()方法!**/ ,assertValue : function(){ var val = this.getRawValue(), rec = this.findRecord(this.displayField, val); if(!rec && this.forceSelection){ this.setRawValue(""); if(val.length > 0 && val != this.emptyText){ //this.el.dom.value = Ext.value(this.lastSelectionText, ''); this.applyEmptyText(); }else{ this.clearValue(); } this._mapReturnFields_(null); }else{ if(rec){ // 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. this._mapReturnFields_(rec); if (val == rec.get(this.displayField) && this.value == rec.get(this.valueField)){ return; } val = rec.get(this.valueField || this.displayField); } else { if (val != this.value ) { this._mapReturnFields_(null); } } if (this.getValue() != val) { this.setValue(val); } } } /** onSelect 暫時更改與源碼中一樣! **/ ,onSelect : function(record, index){ if(this.fireEvent('beforeselect', this, record, index) !== false){ this.setValue(record.data[this.valueField || this.displayField]); if(this.fieldMapping!=null){ this._mapReturnFields_(record);//在select事件中設置一次,失去焦點的時候可以再設置一次(add after) } this.collapse(); this.fireEvent('select', this, record, index); } } /** Return **/ ,_mapReturnFields_: function(crec) { // crec combo selected record[Selected Record] if(!Ext.isEmpty(this.callFromGrid)){ //注意這裡會根據你設置的SelectionModel不同而不同,具體情況根據你設置來定 var mrec=this.callFromGrid.getSelectionModel().getSelected();//獲得選中的第一條記錄(即編輯的紀錄) this._mapReturnFieldsExecute_(crec,mrec);//crec是combo選中的紀錄,mrec是combo所在Grid行的紀錄,即把combo中的紀錄設置到Grid中 }else{ this._mapReturnFieldsExecute_(crec); } } ,_mapReturnFieldsExecute_: function(crec, mrec) { // crec combo selected record if(crec!=null){//若選中紀錄時才設置值到其他字段中 if (this.fieldMapping != null) { for(var i=0, len=this.fieldMapping.length; i<len; i++ ) { if (!Ext.isEmpty(this.callFromGrid)) { mrec.set( this.fieldMapping[i].field ,crec.get(this.fieldMapping[i].column) ) ; }else { Ext.getCmp(this.fieldMapping[i].field).setValue( crec.get(this.fieldMapping[i].column) ); Ext.getCmp(this.fieldMapping[i].field).fireEvent( "change"); } } } }else{//否則不只設置值,並且將之前的值清空. if (this.fieldMapping != null) { for(var i=0, len=this.fieldMapping.length; i<len; i++ ) { if (!Ext.isEmpty(this.callFromGrid)) { mrec.set( this.fieldMapping[i].field ,"") ; }else { Ext.getCmp(this.fieldMapping[i].field).setValue("") ; Ext.getCmp(this.fieldMapping[i].field).fireEvent( "change"); } } } } } /** Filter **/ ,_mapFilterFields_: function(bp) { // empty object which is added to store.baseParams if(!Ext.isEmpty(this.callFromGrid)){//如果是在GridPanel或EditorGridPanel中 //注意這裡會根據你設置的SelectionModel不同而不同,具體情況根據你設置來定 var mrec=this.callFromGrid.getSelectionModel().getSelected();//獲得選中的第一條記錄(即編輯的紀錄) this._mapFilterFieldsExecute_(bp,mrec); }else{ this._mapFilterFieldsExecute_(bp); } } ,_mapFilterFieldsExecute_: function(bp, mrec) { // bp:basePrams for combo query;mrec:Grid Edit Record var newParamVal; var oldParamVal; if (this.paramMapping != null) { for(var i=0, len=this.paramMapping.length; i<len; i++ ) { if(!Ext.isEmpty(this.callFromGrid)){//如果是在GridPanel或是EditorGridPanel中 newParamVal = (!Ext.isEmpty(this.paramMapping[i].field))?mrec.get( this.paramMapping[i].field ):this.paramMapping[i].value ; //從設置的參數字段中讀取值 }else{ newParamVal = (!Ext.isEmpty(this.paramMapping[i].field))?Ext.getCmp(this.paramMapping[i].field).getValue():this.paramMapping[i].value; //從設置的 } oldParamVal = this.store.baseParams[this.paramMapping[i].param];//原來查詢參數baseParam中對應字段值 /*以下不用判斷,若判斷的話則第一次之後就會不帶參數,不符合我們的需要。 if (newParamVal != oldParamVal) {//如果參數有變動則查詢否則不查 bp[this.paramMapping[i].param]=newParamVal; } */ bp[this.paramMapping[i].param]=newParamVal; } } } /** 其實就是調整若配置了大小寫配置,則轉化為大小寫! **/ ,getValue : function(){ var v = null; if(this.valueField){ v= Ext.isDefined(this.value) ? this.value : ''; }else{ v= Ext.form.ComboBox.superclass.getValue.call(this); } if (this.initialConfig["caseRestriction"] == "uppercase" && !Ext.isEmpty(v) )v=v.toUpperCase(); return v; } /** proxy exception**/ , proxyException: function(dataProxy, type, action , options , response , arg ) { if(type=="response") { this.afterAjaxFailure(response , options); } else { alert(response.message.substr(0,1500)); } } , afterAjaxFailure: function(response , options) { this.dc____ajaxfailure(response , options); } /** initEvent **/ ,initEvents : function(){ Ext.form.ComboBox.superclass.initEvents.call(this); this.keyNav = new Ext.KeyNav(this.el, { "up" : function(e){ this.inKeyMode = true; this.selectPrev(); }, "down" : function(e){ if(!this.isExpanded()){ this.onTriggerClick(); }else{ this.inKeyMode = true; this.selectNext(); } }, "enter" : function(e){ this.onViewClick(true); //if(this.isExpanded()){ e.stopEvent(); e.stopPropagation(); e.preventDefault(); //} return false; }, "esc" : function(e){ this.collapse(); }, "tab" : function(e){ if (this.forceSelection === true) { this.collapse(); } else { this.onViewClick(false); } return true; }, scope : this, doRelay : function(e, h, hname){ if(hname == 'down' || this.scope.isExpanded()){ // this MUST be called before ComboBox#fireKey() var relay = Ext.KeyNav.prototype.doRelay.apply(this, arguments); if(!Ext.isIE && Ext.EventManager.useKeydown){ // call Combo#fireKey() for browsers which use keydown event (except IE) this.scope.fireKey(e); } return relay; } return true; }, forceKeyDown : true, defaultEventAction: 'stopEvent' }); this.queryDelay = Math.max(this.queryDelay || 10, this.mode == 'local' ? 10 : 250); this.dqTask = new Ext.util.DelayedTask(this.initQuery, this); if(this.typeAhead){ this.taTask = new Ext.util.DelayedTask(this.onTypeAhead, this); } if(!this.enableKeyEvents){ this.mon(this.el, 'keyup', this.onKeyUp, this); } } ,onRender : function(ct, position){ dnet.base.AbstractCombo.superclass.onRender.call(this, ct, position); } ,dc____ajaxfailure:function(response , options) { Ext.MessageBox.hide(); var msg = response.responseText; if (msg && msg.length > 2000) { msg = msg.substr(0,2000);} Ext.Msg.show({ // title: 'HTTP:'+response.status+' '+ response.statusText msg: msg ,buttons: {ok:'OK'} //, cancel:'Details' ,scope:this ,icon: Ext.MessageBox.ERROR ,_detailedMessage_:response.responseText }); } }); Ext.reg('xcombo', dnet.base.AbstractCombo);
以下是使用的例子:
此种情况是在Grid中的使用情况,即获取brandName列的值赋给参数brandCode,并把参数作为productCategory这个comboBox的Store的参数来查询结果,并把结果中的你选择的comboBox值对应的divisionCode字段值赋给Grid中的divisionCode列,同时comboBox对应的itemCategoryCode字段值赋给Grid中的
itemCategoryCode列!
var productCategory=new dnet.base.AbstractCombo({ _dataProviderFields_:ItemMaster.ProductCategory$Model ,storeUrl:"/ItemMasterManagement/getField.action?field=ProductCategory",tpl:ItemMaster.tpl ,valueField:ItemMaster.valueField,displayField:ItemMaster.displayField ,queryParam:ItemMaster.queryParam ,callFromGrid:p ,paramMapping:[{param:'brandCode',field:'brandName'}] ,fieldMapping:[{field:'divisionCode',column:'divisionCode'},{field:'itemCategoryCode',column:'itemCategoryCode'}] }); productCategory._createStore_();