// 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([ '编号:{ID}', '姓名:{FirstName}-{LastName}', '电话:{Phone}', '城市:{City}', '邮箱:{Email}' ]), 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' } ]*/ 在页面上: ////////////////////////////////// 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自定义控件 // 1、引入命名空间 Ext.namespace("ExtUD.Ext");//相当于java中包的作用 // 2、编写自定义控件类 ExtUD.Ext.UDPanel = Ext.extend(Ext.Panel, { title : '自定义控件', html:'自定义控件面板', layout:'fit', getAlert:function(){alert('自定义控件函数!');} }); // 3、注册控件 Ext.reg('udpanel', ExtUD.Ext.UDPanel);//第一个参数为自定义控件的xtype //4、使用自定义控件 Ext.onReady(function() { var temp = new ExtUD.Ext.UDPanel({ renderTo : document.body }); temp.show(); temp.getAlert(); });
如何编写ExtJS自定义控件 // 1、引入命名空间 Ext.namespace("ExtUD.Ext");//相当于java中包的作用 // 2、编写自定义控件类 ExtUD.Ext.UDPanel = Ext.extend(Ext.Panel, { title : '自定义控件', html:'自定义控件面板', layout:'fit', getAlert:function(){alert('自定义控件函数!');} }); // 3、注册控件 Ext.reg('udpanel', ExtUD.Ext.UDPanel);//第一个参数为自定义控件的xtype //4、使用自定义控件 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=""+
""+this.fieldLabel+
": "+
document.getElementByIdx_x(this.id+"_name").value+"
";
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