摘要:ComboBox是常用控件之一,但由于其数据来源分两种形式:本地和远程,故写的形式难度并不亚于ExtJS中的TreePanel和 GridPanel。鄙人也经常提醒自己的师弟师妹,ExtJS本身是面向对象写的,不能在应用的时候却不按照面向对象来写,面向对象最起码的好处就是代 码的复用,对于网页来讲,代码复用的好处就是加载的JS会少很多,这样网页渲染时就不会很慢。下面我将分别介绍扩展的四种ComboBox。
类图:
扩展一:封装的月份ComboBox组件
效果:
代码:
//
封装的月份ComboBox组件
MonthComboBox = Ext.extend(Ext.form.ComboBox, {
fieldLabel : '月 & nbsp; & nbsp; & nbsp; & nbsp;份', // 标题名称
storeData : null , // ComboxBox数据源(数组形式)
initComponent : function () {
this .storeData = [[ 1 , '1月'], [ 2 , '2月'], [ 3 , '3月'], [ 4 , '4月'],
[ 5 , '5月'], [ 6 , '6月'], [ 7 , '7月'], [ 8 , '8月'], [ 9 , '9月'],
[ 10 , '10月'], [ 11 , '11月'], [ 12 , '12月']];
Ext.apply( this , {
fieldLabel : this .fieldLabel,
anchor : ' 100 % ',
emptyText : '月份',
forceSelection : true , // 值为true时将限定选中的值为列表中的值,值为false则允许用户将任意文本设置到字段(默认为
// false)。
selectOnFocus : true , // 值为 ture
// 时表示字段获取焦点时自动选择字段既有文本(默认为
// false)。
mode : 'local',
store : new Ext.data.SimpleStore({
fields : ['value', 'text'],
data : this .storeData
}),
editable : false ,
triggerAction : 'all',
valueField : 'value',
displayField : 'text'
});
MonthComboBox.superclass.initComponent.call( this );
}
});
MonthComboBox = Ext.extend(Ext.form.ComboBox, {
fieldLabel : '月 & nbsp; & nbsp; & nbsp; & nbsp;份', // 标题名称
storeData : null , // ComboxBox数据源(数组形式)
initComponent : function () {
this .storeData = [[ 1 , '1月'], [ 2 , '2月'], [ 3 , '3月'], [ 4 , '4月'],
[ 5 , '5月'], [ 6 , '6月'], [ 7 , '7月'], [ 8 , '8月'], [ 9 , '9月'],
[ 10 , '10月'], [ 11 , '11月'], [ 12 , '12月']];
Ext.apply( this , {
fieldLabel : this .fieldLabel,
anchor : ' 100 % ',
emptyText : '月份',
forceSelection : true , // 值为true时将限定选中的值为列表中的值,值为false则允许用户将任意文本设置到字段(默认为
// false)。
selectOnFocus : true , // 值为 ture
// 时表示字段获取焦点时自动选择字段既有文本(默认为
// false)。
mode : 'local',
store : new Ext.data.SimpleStore({
fields : ['value', 'text'],
data : this .storeData
}),
editable : false ,
triggerAction : 'all',
valueField : 'value',
displayField : 'text'
});
MonthComboBox.superclass.initComponent.call( this );
}
});
应用:
var
cboMonth
=
new
MonthComboBox({
renderTo : 'monthComboBox',
width : 200
});
renderTo : 'monthComboBox',
width : 200
});
Html:
<div id="monthComboBox"></div><br/>
//
封装的日期ComboBox组件
DayComboBox = Ext.extend(Ext.form.ComboBox, {
fieldLabel : '日 & nbsp; & nbsp; & nbsp; & nbsp;期', // 标题名称
storeData : null , // ComboxBox数据源(数组形式)
initComponent : function () {
this .storeData = [[ 1 , '1日'], [ 2 , '2日'], [ 3 , '3日'], [ 4 , '4日'],
[ 5 , '5日'], [ 6 , '6日'], [ 7 , '7日'], [ 8 , '8日'], [ 9 , '9日'],
[ 10 , '10日'], [ 11 , '11日'], [ 12 , '12日'], [ 13 , '13日'],
[ 14 , '14日'], [ 15 , '15日'], [ 16 , '16日'], [ 17 , '17日'],
[ 18 , '18日'], [ 19 , '19日'], [ 20 , '20日'], [ 21 , '21日'],
[ 22 , '22日'], [ 23 , '23日'], [ 24 , '24日'], [ 25 , '25日'],
[ 26 , '26日'], [ 27 , '27日'], [ 28 , '28日'], [ 29 , '29日'],
[ 30 , '30日'], [ 31 , '31日']];
Ext.apply( this , {
fieldLabel : this .fieldLabel,
anchor : ' 100 % ',
emptyText : '日期',
forceSelection : true ,
// 值为true时将限定选中的值为列表中的值,
// 值为false则允许用户将任意文本设置到字段(默认为false)。
selectOnFocus : true ,
// 值为 ture时表示字段获取焦点时自动选择字段既有文本(默认为false)。
mode : 'local',
store : new Ext.data.SimpleStore({
fields : ['value', 'text'],
data : this .storeData
}),
editable : false ,
triggerAction : 'all',
valueField : 'value',
displayField : 'text'
});
DayComboBox.superclass.initComponent.call( this );
}
});
DayComboBox = Ext.extend(Ext.form.ComboBox, {
fieldLabel : '日 & nbsp; & nbsp; & nbsp; & nbsp;期', // 标题名称
storeData : null , // ComboxBox数据源(数组形式)
initComponent : function () {
this .storeData = [[ 1 , '1日'], [ 2 , '2日'], [ 3 , '3日'], [ 4 , '4日'],
[ 5 , '5日'], [ 6 , '6日'], [ 7 , '7日'], [ 8 , '8日'], [ 9 , '9日'],
[ 10 , '10日'], [ 11 , '11日'], [ 12 , '12日'], [ 13 , '13日'],
[ 14 , '14日'], [ 15 , '15日'], [ 16 , '16日'], [ 17 , '17日'],
[ 18 , '18日'], [ 19 , '19日'], [ 20 , '20日'], [ 21 , '21日'],
[ 22 , '22日'], [ 23 , '23日'], [ 24 , '24日'], [ 25 , '25日'],
[ 26 , '26日'], [ 27 , '27日'], [ 28 , '28日'], [ 29 , '29日'],
[ 30 , '30日'], [ 31 , '31日']];
Ext.apply( this , {
fieldLabel : this .fieldLabel,
anchor : ' 100 % ',
emptyText : '日期',
forceSelection : true ,
// 值为true时将限定选中的值为列表中的值,
// 值为false则允许用户将任意文本设置到字段(默认为false)。
selectOnFocus : true ,
// 值为 ture时表示字段获取焦点时自动选择字段既有文本(默认为false)。
mode : 'local',
store : new Ext.data.SimpleStore({
fields : ['value', 'text'],
data : this .storeData
}),
editable : false ,
triggerAction : 'all',
valueField : 'value',
displayField : 'text'
});
DayComboBox.superclass.initComponent.call( this );
}
});
应用:
var
cboDay
=
new
DayComboBox({
renderTo : 'dayComboBox',
width : 200
});
renderTo : 'dayComboBox',
width : 200
});
Html:
<
div id
=
"
dayComboBox
"
></
div
><
br
/>
//
封装的DynamicCombox组件
DynamicCombox = Ext.extend(Ext.form.ComboBox, {
fieldLabel : '动态ComboBox', // 标题名称
baseUrl : null ,
emptyText : null ,
valueField : null ,
displayField : null ,
initComponent : function () {
Ext.apply( this , {
fieldLabel : this .fieldLabel,
anchor : ' 100 % ',
emptyText : this .emptyText || '请选择',
forceSelection : true ,
// 值为true时将限定选中的值为列表中的值,
// 值为false则允许用户将任意文本设置到字段(默认为false)。
selectOnFocus : true ,
// 值为 ture时表示字段获取焦点时自动选择字段既有文本(默认为false)。
mode : 'remote',
store : new Ext.data.JsonStore({
url : this .baseUrl,
root : " root " ,
remoteSort : true ,
fields : [ this .valueField,
this .displayField]
}),
editable : false , // 是否编辑
triggerAction : 'all',
valueField : this .valueField,
displayField : this .displayField,
hiddenName : this .valueField
});
DynamicCombox.superclass.initComponent.call( this );
}
});
DynamicCombox = Ext.extend(Ext.form.ComboBox, {
fieldLabel : '动态ComboBox', // 标题名称
baseUrl : null ,
emptyText : null ,
valueField : null ,
displayField : null ,
initComponent : function () {
Ext.apply( this , {
fieldLabel : this .fieldLabel,
anchor : ' 100 % ',
emptyText : this .emptyText || '请选择',
forceSelection : true ,
// 值为true时将限定选中的值为列表中的值,
// 值为false则允许用户将任意文本设置到字段(默认为false)。
selectOnFocus : true ,
// 值为 ture时表示字段获取焦点时自动选择字段既有文本(默认为false)。
mode : 'remote',
store : new Ext.data.JsonStore({
url : this .baseUrl,
root : " root " ,
remoteSort : true ,
fields : [ this .valueField,
this .displayField]
}),
editable : false , // 是否编辑
triggerAction : 'all',
valueField : this .valueField,
displayField : this .displayField,
hiddenName : this .valueField
});
DynamicCombox.superclass.initComponent.call( this );
}
});
应用:
var
cboDyna
=
new
DynamicCombox({
renderTo : 'dynamicCombox',
width: 200 ,
baseUrl:'dynadata.json',
valueField:'value',
displayField:'display'
});
renderTo : 'dynamicCombox',
width: 200 ,
baseUrl:'dynadata.json',
valueField:'value',
displayField:'display'
});
Json:
{
root : [{
value : 'v1',
display : '张三'
}, {
value : 'v2',
display : '李四'
}, {
value : 'v3',
display : '王五'
}]
}
root : [{
value : 'v1',
display : '张三'
}, {
value : 'v2',
display : '李四'
}, {
value : 'v3',
display : '王五'
}]
}
Html:
<
div
id
="dynamicCombox"
></
div
><
br
/>
//
封装的ComboBoxTree组件
ComboBoxTree = Ext.extend(Ext.form.ComboBox, {
fieldLabel : 'ComboBoxTree', // 标题名称
baseUrl : null ,
emptyText : null ,
maxHeight : 300 ,
treeId : Ext.id() + ' - tree',
tree : null ,
// all:所有结点都可选中
// exceptRoot:除根结点,其它结点都可选(默认)
// folder:只有目录(非叶子和非根结点)可选
// leaf:只有叶子结点可选
selectNodeModel : 'exceptRoot',
initComponent : function () {
var resultTpl = new Ext.XTemplate(' < tpl for = " . " >< div style = " height:'
+ this.maxHeight + 'px " >< div id = " ' + this.treeId
+ ' " ></ div ></ div ></ tpl > ');
this .addEvents('afterchange');
Ext.apply( this , {
fieldLabel : this .fieldLabel,
anchor : ' 100 % ',
emptyText : this .emptyText || '请选择',
forceSelection : true ,
selectedClass : '',
// 值为true时将限定选中的值为列表中的值,
// 值为false则允许用户将任意文本设置到字段(默认为false)。
selectOnFocus : true ,
// 值为 ture时表示字段获取焦点时自动选择字段既有文本(默认为false)。
mode : 'local',
store : new Ext.data.SimpleStore({
fields : [],
data : [[]]
}),
editable : false , // 是否编辑
triggerAction : 'all',
typeAhead : false ,
tpl : resultTpl,
onSelect : Ext.emptyFn()
});
ComboBoxTree.superclass.initComponent.call( this );
},
expand : function () {
ComboBoxTree.superclass.expand.call( this );
if ( this .tree.rendered) {
return ;
}
Ext.apply( this .tree, {
height : this .maxHeight,
border : false ,
autoScroll : true
});
if ( this .tree.xtype) {
this .tree = Ext.ComponentMgr.create( this .tree, this .tree.xtype);
}
this .tree.render( this .treeId);
var root = this .tree.getRootNode();
if ( ! root.isLoaded()) {
root.reload();
}
this .tree.on('click', function (node) {
var selModel = this .selectNodeModel;
var isLeaf = node.isLeaf();
if ((node == root) && selModel != 'all') {
return ;
} else if (selModel == 'folder' && isLeaf) {
return ;
} else if (selModel == 'leaf' && ! isLeaf) {
return ;
}
var oldNode = this .getNode();
if ( this .fireEvent('beforeselect', this , node, oldNode) !== false ) {
this .setValue(node);
this .collapse();
this .fireEvent('select', this , node, oldNode);
(oldNode !== node) ? this .fireEvent('afterchange',
this , node, oldNode) : '';
}
}, this );
this .tree.expandAll();
},
setValue : function (node) {
this .node = node;
var text = node.text;
this .lastSelectionText = text;
if ( this .hiddenField) {
this .hiddenField.value = node.id;
}
Ext.form.ComboBox.superclass.setValue.call( this , text);
this .value = node.id;
},
getValue : function () {
return typeof this .value != 'undefined' ? this .value : '';
},
getNode : function () {
return this .node;
},
clearValue : function () {
ComboBoxTree.superclass.clearValue.call( this );
this .node = null ;
},
// private
destroy : function () {
ComboBoxTree.superclass.destroy.call( this );
Ext.destroy([ this .node, this .tree]);
delete this .node;
}
});
ComboBoxTree = Ext.extend(Ext.form.ComboBox, {
fieldLabel : 'ComboBoxTree', // 标题名称
baseUrl : null ,
emptyText : null ,
maxHeight : 300 ,
treeId : Ext.id() + ' - tree',
tree : null ,
// all:所有结点都可选中
// exceptRoot:除根结点,其它结点都可选(默认)
// folder:只有目录(非叶子和非根结点)可选
// leaf:只有叶子结点可选
selectNodeModel : 'exceptRoot',
initComponent : function () {
var resultTpl = new Ext.XTemplate(' < tpl for = " . " >< div style = " height:'
+ this.maxHeight + 'px " >< div id = " ' + this.treeId
+ ' " ></ div ></ div ></ tpl > ');
this .addEvents('afterchange');
Ext.apply( this , {
fieldLabel : this .fieldLabel,
anchor : ' 100 % ',
emptyText : this .emptyText || '请选择',
forceSelection : true ,
selectedClass : '',
// 值为true时将限定选中的值为列表中的值,
// 值为false则允许用户将任意文本设置到字段(默认为false)。
selectOnFocus : true ,
// 值为 ture时表示字段获取焦点时自动选择字段既有文本(默认为false)。
mode : 'local',
store : new Ext.data.SimpleStore({
fields : [],
data : [[]]
}),
editable : false , // 是否编辑
triggerAction : 'all',
typeAhead : false ,
tpl : resultTpl,
onSelect : Ext.emptyFn()
});
ComboBoxTree.superclass.initComponent.call( this );
},
expand : function () {
ComboBoxTree.superclass.expand.call( this );
if ( this .tree.rendered) {
return ;
}
Ext.apply( this .tree, {
height : this .maxHeight,
border : false ,
autoScroll : true
});
if ( this .tree.xtype) {
this .tree = Ext.ComponentMgr.create( this .tree, this .tree.xtype);
}
this .tree.render( this .treeId);
var root = this .tree.getRootNode();
if ( ! root.isLoaded()) {
root.reload();
}
this .tree.on('click', function (node) {
var selModel = this .selectNodeModel;
var isLeaf = node.isLeaf();
if ((node == root) && selModel != 'all') {
return ;
} else if (selModel == 'folder' && isLeaf) {
return ;
} else if (selModel == 'leaf' && ! isLeaf) {
return ;
}
var oldNode = this .getNode();
if ( this .fireEvent('beforeselect', this , node, oldNode) !== false ) {
this .setValue(node);
this .collapse();
this .fireEvent('select', this , node, oldNode);
(oldNode !== node) ? this .fireEvent('afterchange',
this , node, oldNode) : '';
}
}, this );
this .tree.expandAll();
},
setValue : function (node) {
this .node = node;
var text = node.text;
this .lastSelectionText = text;
if ( this .hiddenField) {
this .hiddenField.value = node.id;
}
Ext.form.ComboBox.superclass.setValue.call( this , text);
this .value = node.id;
},
getValue : function () {
return typeof this .value != 'undefined' ? this .value : '';
},
getNode : function () {
return this .node;
},
clearValue : function () {
ComboBoxTree.superclass.clearValue.call( this );
this .node = null ;
},
// private
destroy : function () {
ComboBoxTree.superclass.destroy.call( this );
Ext.destroy([ this .node, this .tree]);
delete this .node;
}
});
应用:
var
cboTree
=
new
ComboBoxTree({
renderTo : 'comboBoxTree',
width : 200 ,
tree : {
xtype:'treepanel',
loader: new Ext.tree.TreeLoader({dataUrl:'treedata.json'}),
root : new Ext.tree.AsyncTreeNode({id:' 0 ',text:'根结点'})
},
// all:所有结点都可选中
// exceptRoot:除根结点,其它结点都可选(默认)
// folder:只有目录(非叶子和非根结点)可选
// leaf:只有叶子结点可选
selectNodeModel:'leaf'
});
renderTo : 'comboBoxTree',
width : 200 ,
tree : {
xtype:'treepanel',
loader: new Ext.tree.TreeLoader({dataUrl:'treedata.json'}),
root : new Ext.tree.AsyncTreeNode({id:' 0 ',text:'根结点'})
},
// all:所有结点都可选中
// exceptRoot:除根结点,其它结点都可选(默认)
// folder:只有目录(非叶子和非根结点)可选
// leaf:只有叶子结点可选
selectNodeModel:'leaf'
});
Json:
[{
id : 'root',
text : '单位库',
leaf : false ,
children : [{
id : ' 1002 ',
text : '重庆市气象局',
checked : true ,
leaf : false ,
children : [{
id : ' 1003 ',
text : '机关部门',
checked : true ,
leaf : true
}, {
id : ' 1004 ',
text : '天气办公室',
checked : true ,
leaf : true
}]
},{
id : ' 1005 ',
text : '河北工业大学',
checked : false ,
leaf : true
}]
}]
id : 'root',
text : '单位库',
leaf : false ,
children : [{
id : ' 1002 ',
text : '重庆市气象局',
checked : true ,
leaf : false ,
children : [{
id : ' 1003 ',
text : '机关部门',
checked : true ,
leaf : true
}, {
id : ' 1004 ',
text : '天气办公室',
checked : true ,
leaf : true
}]
},{
id : ' 1005 ',
text : '河北工业大学',
checked : false ,
leaf : true
}]
}]
Html:
<
div
id
="comboBoxTree"
></
div
><
br
/>
原文出自:
http://www.cnblogs.com/xia520pi/archive/2011/11/10/2244133.html