// JavaScript Document Ext.namespace('CRM.Panels'); CRM.Panels.UserDetail = Ext.extend(Ext.Panel,{ width:350, height:120, data:{ ID: 0, FirstName: '', LastName: '', Email: '', City: '', Phone:'' }, split:true, tpl: new Ext.XTemplate([ '<div>編號:{ID}</div>', '<div>姓名:{FirstName}-{LastName}</div>', '<div>電話:{Phone}</div>', '<div>城市:{City}</div>', '<div>郵箱:{Email}</div>' ]), initComponent:function(){ CRM.Panels.UserDetail.superclass.initComponent.call(this); if(typeof this.tpl === 'string'){ this.tpl = new Ext.XTemplate(this.tpl); } this.addEvents('UAlert');//註冊新事件 this.addListener({//偵聽函數 www.2cto.com UAlert: { //註冊的新事件 fn:this.onAlert,//調用onAlert方法 scope: this } }); }, ////////////// onAlert: function(){ alert('註冊的新事件'); }, UAlert:function(){ this.fireEvent('UAlert'); }, ///////////////////// onRender: function(ct, position){ CRM.Panels.UserDetail.superclass.onRender.call(this, ct, position); if(this.data){ this.update(this.data); } }, update: function(data){ this.data = data; this.tpl.overwrite(this.body, this.data); // this.fireEvent('update',this.data); } }); //把新建的自定義組件註冊爲一種xtype Ext.reg('UserDetail',CRM.Panels.UserDetail); /*使用: items:[ { region:'west', xtype:'UserDetail', data: userData[0], title:'User Detail' } ]*/ 在頁面上: <script language="javascript"> var userData = [ {ID:1,FirstName:'Zhang',LastName:'Jinshan',Email:'zjs@qq.com',Phone:'123456',City:'ZhangPing'}, {ID:2,FirstName:'Wang',LastName:'wu',Email:'wjf@qq.com',Phone:'123456',City:'ZhangPing'} ]; Ext.onReady(function(){ var userDetail = new CRM.Panels.UserDetail({ applyTo:'body', title:'User Detail', data:userData[0] }); updateContact = function(event, el, data){ userDetail.update(data.data);//調用更新數據 } Ext.get('xt').on('click',updateContact,this,{data:userData[1]}); Ext.get('alert').on('click',function(){ userDetail.UAlert(); }); }) </script> <button id="xt">點擊</button> <button id="alert">註冊的新事件</button> ////////////////////////////////// ExtJS中的面向對象設計,組件化編程思想/** * @author: Lilf * Description: ExtJS中的面向對象設計,組件化變成思想 */ /****************************擴展VTypes類,增長年齡的驗證****************************/ Ext.apply(Ext.form.VTypes, { "age": function(_v){ if (/^\d+$/.test(_v)) { var intExp = parseInt(_v); if (intExp < 200) return true; } return false; }, ageText: "請輸入正確的年齡格式,如:23" }); /****************************繼承自FormPanel的表單組件,用來構件Window***************************/ PersonInfoFormPanel = Ext.extend(Ext.form.FormPanel, { constructor: function(){ PersonInfoFormPanel.superclass.constructor.apply(this, [{ baseCls: "x-plain", buttonAlign: "right", labelWidth: 30, defaultType: "textfield", defaults: { anchor: "95%", labelStyle: "text-align:right" }, items: [{ fieldLabel: "姓名", name: "name" }, { fieldLabel: "年齡", name: "age", vtype: "age"//驗證年齡(經過vtype類型來驗證) }, { xtype: "combo", mode: "local",//本地數據 readOnly: true, fieldLabel: "性別", displayField: "sex",//顯示下拉框的內容 triggerAction: "all",//在選擇時,顯示全部的項 value: "男",//默認值 store: new Ext.data.SimpleStore({ fields: ["sex"], data: [["男"], ["女"]] }), name: "sex"//綁定字段 }] }]) }, //---如下爲PersonInfoFormPanel類對外提供的方法--- getValues: function(){ if (this.getForm().isValid()) return new Ext.data.Record(this.getForm().getValues()); else throw new Error("驗證沒有經過");//自定義異常 }, setValues: function(_r){ this.getForm().loadRecord(_r); }, reset: function(){ this.getForm().reset(); } }); /**************繼承自Window的基類,insertWindow與updateWindow都由此繼承****************/ baseWindow = Ext.extend(Ext.Window, { form: null, constructor: function(){ this.form = new PersonInfoFormPanel();//實例化PersonInfoFormPanel類 baseWindow.superclass.constructor.apply(this, [{ plain: true, width: 350, //title: "新增人員", modal: true, resizable: false, closeAction: "hide", defaults: { style: "padding:5px" }, items: this.form, buttons: [{ text: "確 定", handler: this.onSubmitClick,//提交事件調用 scope: this }, { text: "取 消", handler: this.onCancelClick,//取消事件調用 scope: this }] }]); //給insertWindow對象添加事件(事件冒泡) this.addEvents("submit"); }, //提交事件處理函數 onSubmitClick: function(){ try { //發佈事件 this.fireEvent("submit", this, this.form.getValues());//調用PersonInfoFormPanel類中自定義的方法getValues this.close(); } catch (_err) { Ext.Msg.alert("系統提示", _err.description);//撲捉自定義錯誤或異常 } }, //取消事件處理函數 onCancelClick: function(){ this.close(); }, //重置與隱藏事件處理函數 close: function(){ this.form.reset(); this.hide(); } }); /*******************insertWindow類****************************/ insertWindow = Ext.extend(baseWindow, { title: "新增人員" }); /*****************updateWindow類******************************/ updateWindow = Ext.extend(baseWindow, { title: "修改人員", load: function(_r){ this.form.setValues(_r); } }); /********根據上面組件建立新的GridPanel類,它就像咱們根據不一樣的零件設計出來的汽車************ * ExtJs自定義PersonListGridPanel類 * 該類繼承自GridPanel[使用Ext.extend(superClass,override Object)方法實現繼承], * 並override了該類的構造函?hu數 * 構造函數內部繼承自GridPanel的構造函數[apply(this,arguments)實現繼承] * 該類實現瞭如何對外部公佈一個事件 * 在構造函數中添加一個事件[this.addEvents("事件名稱")] * 而後使用this.fireEvent("事件名稱",參數)來發布此事?件 * 最後在客戶端調用的時候來訂閱該事?jian件 */ PersonListGridPanel = Ext.extend(Ext.grid.GridPanel, { _window: null, _updateWin: null, constructor: function(_url){ this._window = new insertWindow();//insertWindow對象引用 this._updateWin = new updateWindow();//updateWindow對象引用 PersonListGridPanel.superclass.constructor.apply(this, [{ renderTo: Ext.getBody(), width: 550, height: 200, frame: true, layout: "form", //工具欄 tbar: [{ text: "add", handler: function(){ this._window.show(); }, scope: this }, "-", { text: "update", handler: function(){ this._updateWin.show(); try { this._updateWin.load(this.getSelected()); } catch (_err) { Ext.Msg.alert("系統提示", _err.description); this._updateWin.close(); } }, scope: this }, "-", { text: "delete", handler: this.onRemovePerson, scope: this }], enableColumnMove: false, //列模板 columns: [{ header: "Name", menuDisabled: true, dataIndex: "name" }, { header: "Age", menuDisabled: true, dataIndex: "age" }, { header: "Sex", menuDisabled: true, dataIndex: "sex" }], //數據源 store: new Ext.data.JsonStore({ autoLoad: true, url: _url, fields: ["name", "age", "sex"] }), //選中模板 selModel: new Ext.grid.RowSelectionModel({ singleSelect: true, listeners: { "rowselect": { fn: this.onRowSelected, scope: this } } }) }]); //添加事件 this.addEvents("rowselect"); //事件訂閱 this._window.on("submit", this.onInsertWinSubmit, this); this._updateWin.on("submit", this.onUpdateWinSubmit, this); }, //----- 如下爲自定義方法--------- //得到選中的記錄 getSelected: function(){ var _sm = this.getSelectionModel(); if (_sm.getCount() == 0) throw new Error("你沒有選中任何記錄,請選擇一條記錄後重試"); return _sm.getSelected(); }, //插入一條記錄 insert: function(_r){ this.getStore().add(_r); }, //更新選中的記錄 update: function(_r){ try { var _rs = this.getSelected(); var _data = _rs.data; for (var _i in _data) { _rs.set(_i, _r.get(_i)); }; _rs.commit(); } catch (_err) { } }, //刪除選中的記錄 remove: function(){ try { var _rs = this.getSelected(); Ext.Msg.confirm("系統提示", "你肯定刪除嗎?", function(_btn){ if (_btn == "yes") this.getStore().remove(_rs); }, this); } catch (_err) { Ext.Msg.alert("系統提示", _err.description); } }, //-------如下爲自定義事件處理函數------------ //添加事件 onInsertWinSubmit: function(_win, _r){ this.insert(_r); }, //修改事件 onUpdateWinSubmit: function(_win, _r){ this.update(_r); }, //刪除事件 onRemovePerson: function(){ this.remove(); }, //選中事件 onRowSelected: function(_sel, _index, _r){ this.fireEvent("rowselect", _r);//發佈事件 } }) ////////////// 如何編寫ExtJS自定義控件 // 一、引入命名空間 Ext.namespace("ExtUD.Ext");//至關於java中包的做用 // 二、編寫自定義控件類 ExtUD.Ext.UDPanel = Ext.extend(Ext.Panel, { title : '自定義控件', html:'自定義控件面板', layout:'fit', getAlert:function(){alert('自定義控件函數!');} }); // 三、註冊控件 Ext.reg('udpanel', ExtUD.Ext.UDPanel);//第一個參數爲自定義控件的xtype //四、使用自定義控件 Ext.onReady(function() { var temp = new ExtUD.Ext.UDPanel({ renderTo : document.body }); temp.show(); temp.getAlert(); });
如何編寫ExtJS自定義控件 // 一、引入命名空間 Ext.namespace("ExtUD.Ext");//至關於java中包的做用 // 二、編寫自定義控件類 ExtUD.Ext.UDPanel = Ext.extend(Ext.Panel, { title : '自定義控件', html:'自定義控件面板', layout:'fit', getAlert:function(){alert('自定義控件函數!');} }); // 三、註冊控件 Ext.reg('udpanel', ExtUD.Ext.UDPanel);//第一個參數爲自定義控件的xtype //四、使用自定義控件 Ext.onReady(function() { var temp = new ExtUD.Ext.UDPanel({ renderTo : document.body }); temp.show(); temp.getAlert(); });
//單文本加單銨鈕控件 Ext.Diy.GridCodeName1 = Ext.extend(Ext.Panel, { winWidth:500,//定義彈出窗體的大小 id:'',//窗體ID fieldLabel:'', labelWidth:60, allowBlank:false,//驗證是否可爲空 blankText:'This field is required',//空白文本 displayField:'NAME',//值1 valueField:'VALUE',//值2 codeField:'CODE',//值3 oldValue:'',//緩存舊值 autoDoLoad:true,//自動加載 pageSize:10,//頁顯示行數 remoteSort:true,//是否可排序 showLabel: false,//是否顯示label initComponent:function() {//在這裏定義控件樣式與彈出窗體樣式等,並得到值 //暫存調用頁面傳下來的參數 var id=this.id; var tmpNameField=this.displayField; var tmpValueField=this.valueField; var tmpCodeField=this.codeField; var winWidth = this.winWidth; var pageSize = this.pageSize; var remoteSort = this.remoteSort; var tabIndex = -1;//分頁 var cm;//列頭 if(this.tabIndex!==undefined){ tabIndex = this.tabIndex; } if(this.cm!==undefined){ cm = this.cm; }else{ cm = new Ext.grid.ColumnModel([ new Ext.grid.CheckboxSelectionModel({singleSelect:true}), {id:tmpValueField,header: "值", width: 0, sortable: false, dataIndex: tmpValueField, hidden:true}, {header: "編碼", width: 70, sortable: true, dataIndex: tmpCodeField}, {header: "名稱", width: 100, sortable: true, dataIndex: tmpNameField} ]); } var readerPanel;//定義要讀取的列標題 if(this.readerPanel!==undefined){ readerPanel = this.readerPanel; }else{ readerPanel = new Ext.data.Record.create([ {name: tmpNameField}, {name: tmpValueField}, {name: tmpCodeField} ]); } //讀取數據 var reader = new Ext.data.XmlReader({ record: 'ROW', totalRecords: "TOTALCOUNT" }, readerPanel//把數據保存到溶器中 ); //定義存數據的溶器 var tmpStore = new Ext.data.Store({ url: 'servlet/ajaxservlet', reader: reader, remoteSort:remoteSort, listeners:{ load:function(store,records){ Ext.getCmp(id).fireEvent('afterLoad',store,records); } } }); var valueStore = new Ext.data.Store({ url: 'servlet/ajaxservlet', reader: reader, remoteSort:remoteSort, listeners:{ load:function(store,records){ Ext.getCmp(id).setValueByRecord(records[0]); } } }); //判斷排序 if(this.sortInfo!==undefined){ tmpStore.setDefaultSort(this.sortInfo.field,this.sortInfo.direction); } this.valueStore = valueStore; this.store = tmpStore; if(this.autoDoLoad){ this.doLoad();//加載數據 } //數據獲取狀況提示信息 var pagingBar = new Ext.PagingToolbar({ displayInfo:true, emptyMsg:"沒有數據顯示", displayMsg:"顯示從第{0}條數據到第{1}條數據,共{2}條數據", store:tmpStore, pageSize:pageSize }); //數據加載提示 var grid = new Ext.grid.GridPanel({ store: tmpStore, loadMask:{msg:'數據加載中...'}, cm: cm, sm: new Ext.grid.CheckboxSelectionModel({singleSelect:true}), viewConfig: { forceFit:true }, tbar:[{//如下設置查詢 xtype:'tbtext', text:'查詢關鍵字:' },{ xtype:'textfield', id:id+'searchItemKey' },' ',{ xtype:'tbbutton', text:'查詢', handler:function(){ var tmpSearchKey = Ext.getCmp(id+'searchItemKey').getValue(); Ext.getCmp(id).doSearch(tmpStore,tmpSearchKey,'',''); }, pressed:true }], bbar:pagingBar, buttons: [{ text:'肯定', menuAlign:'center', handler : function(){ var record = grid.getSelectionModel().getSelected();// 返回值爲 Record 類型 if(record==null){ //Ext.MessageBox.alert('提示', '請選擇一條數據!'); Ext.getCmp(id).clearValue(); Ext.getCmp(id).fireEvent('onChange',null,'',''); win.hide(); return; }else{ Ext.getCmp(id).setValueByRecord(record);//以value值爲索引填充數據到控件文本框 win.hide(); } } },{ text:'取消', menuAlign:'center', handler : function(){ win.hide(); } } ], autoWidth: true, iconCls:'icon-grid' }); //雙擊數據行填充數據到控件文本框 grid.on("rowdblclick",function(thisGrid,rowIndex,e){ var record = thisGrid.getStore().getAt(rowIndex); Ext.getCmp(id).setValueByRecord(record); win.hide(); }); //定義窗體詳細信息 var win = new Ext.Window({ title: '請選擇', width: winWidth, defaults:{autoHeight: true}, modal: true, closeAction: 'hide', bodyStyle: 'padding:10px;', items:grid }); //定義窗體顯示內容樣式 Ext.apply(this,{ border:false, bodyBorder:false, items:[{ layout:'column', border: false, items:[{ columnWidth:0.9, labelWidth:this.labelWidth, layout: 'form', border: false, items:[{ xtype:'textfield', fieldLabel: this.fieldLabel, anchor:'100%', id:id+'_code', readOnly:true, tabIndex:tabIndex, listeners:{ specialkey : function(field, e){ if (e.getKey() == Ext.EventObject.ENTER) { Ext.getCmp(id).setValueByCode(field.getValue()); } } } }] },{ columnWidth:0.1, border: false, items:[{ xtype:'button', id:id+'_btn', text:' ', handler:function(){ if(Ext.getCmp(id).fireEvent("beforeClick")===false){ return; } win.show(); win.center(); Ext.getCmp(id).fireEvent("afterClick"); }, pressed:true }] }] },{ xtype:'textfield', id:id+'_value', hidden:true }] }); //註冊控件事件 Ext.Diy.GridCodeName1.superclass.initComponent.apply(this, arguments); this.addEvents({'onChange':true},{'codeInvalid':true},{'beforeClick':true},{'afterClick':true},{'afterLoad':true}); }, //如下定義控件事件 setLabelDisplay: function(p_showLabel){ this.showLabel=p_showLabel; if(p_showLabel){ document.getElementByIdx_x(this.id).childNodes[0].style.display="none"; var tmpDiv=document.getElementByIdx_x("mylbl_"+this.id); if(tmpDiv){ document.getElementByIdx_x("mylbl_"+this.id+"_td").innerHTML=document.getElementByIdx_x(this.id+"_name").value; tmpDiv.style.display="block"; }else{ tmpDiv = document.createElement_x("div"); tmpDiv.id="mylbl_"+this.id; tmpDiv.innerHTML="<div style='width:100%;height:25px;' class='diyform-label-div'>"+ "<table width='100%' border='0' cellspacing='0' cellpadding='0'><tr ><td width='"+this.labelWidth+"'>"+this.fieldLabel+ ":</td><td id='mylbl_"+this.id+"_td' class='diyform-label-td'>"+ document.getElementByIdx_x(this.id+"_name").value+"</td></tr></table></div>"; tmpDiv.style.width=document.getElementByIdx_x(this.id).style.width; document.getElementByIdx_x(this.id).appendChild(tmpDiv); } }else{ document.getElementByIdx_x(this.id).childNodes[0].style.display="block"; try{document.getElementByIdx_x(this.id).removeChild(document.getElementByIdx_x("mylbl_"+this.id));}catch(ex){} } }, doLoad:function(addCon){ if(addCon!==undefined){ this.clearValue(); this.condition=addCon; } this.doSearch(this.store,'','',''); }, doSearch:function(store,searchKey,value,code){ var tmpParam=[]; tmpParam.push(searchKey); tmpParam.push(value); tmpParam.push(code); if(this.condition!==undefined){ tmpParam.push(this.condition); } var parmObj=createRequestXml(this.classUrl,"GetData",this.method,tmpParam.join(',')); store.baseParams={ requestType: 'requestData4DiyGrid', requestCharSet:'UTF8', requestLisence: '1', requestXml: parmObj }; var pageSize = this.pageSize; store.load({params:{start:0, limit:pageSize}}); }, unedit:function(flag){ Ext.getCmp(this.id+"_btn").setDisabled(flag); Ext.getCmp(this.id+"_code").setDisabled(flag); }, clearValue:function(){ this.oldValue=Ext.getCmp(this.id+'_value').getValue(); Ext.getCmp(this.id+"_value").setValue(''); Ext.getCmp(this.id+"_code").setValue(''); }, changeValue:function(record,value,oldValue){ if(value!=oldValue){ this.fireEvent('onChange',record,value,oldValue); } }, codeInvalid:function(){ this.fireEvent('codeInvalid'); }, setValue:function(value){ if(value==null||value==""){ return; } var record; var i=0,j=this.store.getCount(); for(;i<j;i++){ record = this.store.getAt(i); if(record.get(this.valueField)==value){ this.setValueByRecord(record); break; } } if(i==j){ this.doSearch(this.valueStore,'',value,''); } }, setDtlValue:function(dtl,ifFireEvent){ this.oldValue=Ext.getCmp(this.id+'_value').getValue(); Ext.getCmp(this.id+"_value").setValue(dtl.value); Ext.getCmp(this.id+"_code").setValue(dtl.code); if(ifFireEvent==false){ }else{ this.changeValue(null,dtl.value,this.oldValue); } }, setValueByCode:function(code){ var record; var i=0,j=this.store.getCount(); for(;i<j;i++){ record = this.store.getAt(i); if(record.get(this.codeField)==code){ this.setValueByRecord(record); break; } } if(i==j){ this.doSearch(this.valueStore,'','',code); } }, setValueByRecord:function(record){ if(record!=null){ this.clearValue(); Ext.getCmp(this.id+'_value').setValue(record.get(this.valueField)); Ext.getCmp(this.id+'_code').setValue(record.get(this.codeField)); this.changeValue(record,record.get(this.valueField),this.oldValue); }else{ if(Ext.getCmp(this.id+'_code').getValue()!=""){ Ext.MessageBox.alert('提示','找不到該信息'); Ext.getCmp(this.id+'_code').focus(); } this.clearValue(); this.fireEvent('codeInvalid'); } }, getValue:function(){return Ext.getCmp(this.id+"_value").getValue();} }); // 四、註冊控件 Ext.reg('diygridcodename1', Ext.Diy.GridCodeName1);//第一個參數爲自定義控件的xtype 調用方式: id:'LM_SPEC', xtype : 'diygridcodename1',//自定義控件 diygridcodename fieldLabel:'規格', labelWidth:80, allowBlank:false, classUrl:classUrl, method:'getSpecInfo', readerPanel:[{name: 'CODE'},{name: 'VALUE'},{name: 'NAME'}], cm:new Ext.grid.ColumnModel([ new Ext.grid.CheckboxSelectionModel(), {header: "編號", width:100, sortable: true,dataIndex: 'NAME'}, {header: "規格", width:120,unedit:false, sortable: true,dataIndex: 'CODE'} ]), listeners:{ onChange:function(p_record,p_value,p_oldValue){ //ifdef = p_record.get("SOM_IFDEFAULT"); }, beforeClick:function(){ if(!checkbaseunit()){ Ext.MessageBox.alert("提示","主要單位不能爲空!"); return; } } }, anchor : '98%'//佔用總寬度的百份比