Extjs ComboBox的擴展

 作用:          

         在程序中,经常会遇到这种情况:即获取其它地方的参数,在本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_();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值