自定義ExtJS控件之下拉樹(shù)和下拉表格附源碼
更新時(shí)間:2013年10月15日 16:53:57 作者:
在Ext官方的例子中只有下拉列表控件,但是在實(shí)際業(yè)務(wù)中只有下拉列表無(wú)法滿足需求的,對(duì)于剛使用Ext的人來(lái)說(shuō),自定義一個(gè)控件好難,下面是具體的實(shí)現(xiàn)
簡(jiǎn)介
在Ext官方的例子中只有下拉列表控件,但是在實(shí)際業(yè)務(wù)中只有下拉列表無(wú)法滿足需求的,像下拉樹(shù)和下拉表格都是很常見(jiàn)的控件,對(duì)于剛使用Ext的人來(lái)說(shuō),自定義一個(gè)控件好難,其實(shí)多讀官方的源碼有些事情就不會(huì)那么難了。下面是下拉樹(shù)的代碼:
Ext.define('ComboTreeBox',{
extend : 'Ext.form.field.ComboBox',
multiSelect : true,
createPicker : function(){
var me = this;
//創(chuàng)建樹(shù)控件
var picker = Ext.create('Ext.tree.Panel', {
store: me.store,
rootVisible: false,
selModel: {
mode: me.multiSelect ? 'SIMPLE' : 'SINGLE'
},
floating: true,
hidden: true,
focusOnToFront: false
});
//注冊(cè)事件用于選擇用戶選擇的值
me.mon(picker, {
itemclick: me.onItemClick,
refresh: me.onListRefresh,
scope: me
});
me.mon(picker.getSelectionModel(), {
beforeselect: me.onBeforeSelect,
beforedeselect: me.onBeforeDeselect,
selectionchange: me.onListSelectionChange,
scope: me
});
this.picker = picker;
return picker;
},
onItemClick: function(picker, record){
/*
* If we're doing single selection, the selection change events won't fire when
* clicking on the selected element. Detect it here.
*/
var me = this,
selection = me.picker.getSelectionModel().getSelection(),
valueField = me.valueField;
if (!me.multiSelect && selection.length) {
if (record.get(valueField) === selection[0].get(valueField)) {
// Make sure we also update the display value if it's only partial
me.displayTplData = [record.data];
me.setRawValue(me.getDisplayValue());
me.collapse();
}
}
}
});
下拉樹(shù)的代碼很簡(jiǎn)單,只要集成Ext.form.field.ComboBox類,然后重寫createPicker方法就可以了,同理下拉表格也是如此,下面是下拉表格的代碼:
Ext.define('ComboGridBox',{
extend : 'Ext.form.field.ComboBox',
multiSelect : true,
createPicker : function(){
var me = this;
var picker = Ext.create('Ext.grid.Panel', {
title : '下拉表格',
store: me.store,
frame : true,
resizable : true,
columns : [{
text : '#ID',
dataIndex : 'id'
},{
text : '名稱' ,
dataIndex : 'name'
},{
text : '描述' ,
dataIndex : 'desc'
}],
selModel: {
mode: me.multiSelect ? 'SIMPLE' : 'SINGLE'
},
floating: true,
hidden: true,
width : 300,
columnLines : true,
focusOnToFront: false
});
me.mon(picker, {
itemclick: me.onItemClick,
refresh: me.onListRefresh,
scope: me
});
me.mon(picker.getSelectionModel(), {
beforeselect: me.onBeforeSelect,
beforedeselect: me.onBeforeDeselect,
selectionchange: me.onListSelectionChange,
scope: me
});
this.picker = picker;
return picker;
},
onItemClick: function(picker, record){
/*
* If we're doing single selection, the selection change events won't fire when
* clicking on the selected element. Detect it here.
*/
var me = this,
selection = me.picker.getSelectionModel().getSelection(),
valueField = me.valueField;
if (!me.multiSelect && selection.length) {
if (record.get(valueField) === selection[0].get(valueField)) {
// Make sure we also update the display value if it's only partial
me.displayTplData = [record.data];
me.setRawValue(me.getDisplayValue());
me.collapse();
}
}
},
matchFieldWidth : false,
onListSelectionChange: function(list, selectedRecords) {
var me = this,
isMulti = me.multiSelect,
hasRecords = selectedRecords.length > 0;
// Only react to selection if it is not called from setValue, and if our list is
// expanded (ignores changes to the selection model triggered elsewhere)
if (!me.ignoreSelection && me.isExpanded) {
if (!isMulti) {
Ext.defer(me.collapse, 1, me);
}
/*
* Only set the value here if we're in multi selection mode or we have
* a selection. Otherwise setValue will be called with an empty value
* which will cause the change event to fire twice.
*/
if (isMulti || hasRecords) {
me.setValue(selectedRecords, false);
}
if (hasRecords) {
me.fireEvent('select', me, selectedRecords);
}
me.inputEl.focus();
}
console.log(me.getValue());
},
doAutoSelect: function() {
var me = this,
picker = me.picker,
lastSelected, itemNode;
if (picker && me.autoSelect && me.store.getCount() > 0) {
// Highlight the last selected item and scroll it into view
lastSelected = picker.getSelectionModel().lastSelected;
itemNode = picker.view.getNode(lastSelected || 0);
if (itemNode) {
picker.view.highlightItem(itemNode);
picker.view.el.scrollChildIntoView(itemNode, false);
}
}
}
});
下拉表格也是繼承了Ext.form.field.ComboBox這個(gè)類,重寫了createPicker方法。
開(kāi)發(fā)下拉樹(shù)和下拉表格看起來(lái)so easy,只要研究透了Ext的運(yùn)行機(jī)制,一切都會(huì)so easy
控件效果

實(shí)例下載
實(shí)例中的資源為myeclipse項(xiàng)目,導(dǎo)入即可運(yùn)行,自己添加ext的js和css文件,實(shí)例中沒(méi)有ext的基礎(chǔ)文件。
下載地址
在Ext官方的例子中只有下拉列表控件,但是在實(shí)際業(yè)務(wù)中只有下拉列表無(wú)法滿足需求的,像下拉樹(shù)和下拉表格都是很常見(jiàn)的控件,對(duì)于剛使用Ext的人來(lái)說(shuō),自定義一個(gè)控件好難,其實(shí)多讀官方的源碼有些事情就不會(huì)那么難了。下面是下拉樹(shù)的代碼:
復(fù)制代碼 代碼如下:
Ext.define('ComboTreeBox',{
extend : 'Ext.form.field.ComboBox',
multiSelect : true,
createPicker : function(){
var me = this;
//創(chuàng)建樹(shù)控件
var picker = Ext.create('Ext.tree.Panel', {
store: me.store,
rootVisible: false,
selModel: {
mode: me.multiSelect ? 'SIMPLE' : 'SINGLE'
},
floating: true,
hidden: true,
focusOnToFront: false
});
//注冊(cè)事件用于選擇用戶選擇的值
me.mon(picker, {
itemclick: me.onItemClick,
refresh: me.onListRefresh,
scope: me
});
me.mon(picker.getSelectionModel(), {
beforeselect: me.onBeforeSelect,
beforedeselect: me.onBeforeDeselect,
selectionchange: me.onListSelectionChange,
scope: me
});
this.picker = picker;
return picker;
},
onItemClick: function(picker, record){
/*
* If we're doing single selection, the selection change events won't fire when
* clicking on the selected element. Detect it here.
*/
var me = this,
selection = me.picker.getSelectionModel().getSelection(),
valueField = me.valueField;
if (!me.multiSelect && selection.length) {
if (record.get(valueField) === selection[0].get(valueField)) {
// Make sure we also update the display value if it's only partial
me.displayTplData = [record.data];
me.setRawValue(me.getDisplayValue());
me.collapse();
}
}
}
});
下拉樹(shù)的代碼很簡(jiǎn)單,只要集成Ext.form.field.ComboBox類,然后重寫createPicker方法就可以了,同理下拉表格也是如此,下面是下拉表格的代碼:
復(fù)制代碼 代碼如下:
Ext.define('ComboGridBox',{
extend : 'Ext.form.field.ComboBox',
multiSelect : true,
createPicker : function(){
var me = this;
var picker = Ext.create('Ext.grid.Panel', {
title : '下拉表格',
store: me.store,
frame : true,
resizable : true,
columns : [{
text : '#ID',
dataIndex : 'id'
},{
text : '名稱' ,
dataIndex : 'name'
},{
text : '描述' ,
dataIndex : 'desc'
}],
selModel: {
mode: me.multiSelect ? 'SIMPLE' : 'SINGLE'
},
floating: true,
hidden: true,
width : 300,
columnLines : true,
focusOnToFront: false
});
me.mon(picker, {
itemclick: me.onItemClick,
refresh: me.onListRefresh,
scope: me
});
me.mon(picker.getSelectionModel(), {
beforeselect: me.onBeforeSelect,
beforedeselect: me.onBeforeDeselect,
selectionchange: me.onListSelectionChange,
scope: me
});
this.picker = picker;
return picker;
},
onItemClick: function(picker, record){
/*
* If we're doing single selection, the selection change events won't fire when
* clicking on the selected element. Detect it here.
*/
var me = this,
selection = me.picker.getSelectionModel().getSelection(),
valueField = me.valueField;
if (!me.multiSelect && selection.length) {
if (record.get(valueField) === selection[0].get(valueField)) {
// Make sure we also update the display value if it's only partial
me.displayTplData = [record.data];
me.setRawValue(me.getDisplayValue());
me.collapse();
}
}
},
matchFieldWidth : false,
onListSelectionChange: function(list, selectedRecords) {
var me = this,
isMulti = me.multiSelect,
hasRecords = selectedRecords.length > 0;
// Only react to selection if it is not called from setValue, and if our list is
// expanded (ignores changes to the selection model triggered elsewhere)
if (!me.ignoreSelection && me.isExpanded) {
if (!isMulti) {
Ext.defer(me.collapse, 1, me);
}
/*
* Only set the value here if we're in multi selection mode or we have
* a selection. Otherwise setValue will be called with an empty value
* which will cause the change event to fire twice.
*/
if (isMulti || hasRecords) {
me.setValue(selectedRecords, false);
}
if (hasRecords) {
me.fireEvent('select', me, selectedRecords);
}
me.inputEl.focus();
}
console.log(me.getValue());
},
doAutoSelect: function() {
var me = this,
picker = me.picker,
lastSelected, itemNode;
if (picker && me.autoSelect && me.store.getCount() > 0) {
// Highlight the last selected item and scroll it into view
lastSelected = picker.getSelectionModel().lastSelected;
itemNode = picker.view.getNode(lastSelected || 0);
if (itemNode) {
picker.view.highlightItem(itemNode);
picker.view.el.scrollChildIntoView(itemNode, false);
}
}
}
});
下拉表格也是繼承了Ext.form.field.ComboBox這個(gè)類,重寫了createPicker方法。
開(kāi)發(fā)下拉樹(shù)和下拉表格看起來(lái)so easy,只要研究透了Ext的運(yùn)行機(jī)制,一切都會(huì)so easy
控件效果

實(shí)例下載
實(shí)例中的資源為myeclipse項(xiàng)目,導(dǎo)入即可運(yùn)行,自己添加ext的js和css文件,實(shí)例中沒(méi)有ext的基礎(chǔ)文件。
下載地址
您可能感興趣的文章:
相關(guān)文章
Ext中下拉列表ComboBox組件store數(shù)據(jù)格式用法介紹
本文為大家詳細(xì)介紹下Ext中下拉列表ComboBox組件store數(shù)據(jù)格式的基本用法,感興趣的朋友可以參考下哈,希望對(duì)大家有所幫助2013-07-07
ExtJS 2.0實(shí)用簡(jiǎn)明教程之應(yīng)用ExtJS
應(yīng)用extjs需要在頁(yè)面中引入extjs的樣式及extjs庫(kù)文件2009-04-04
Extjs4 關(guān)于Store的一些操作(加載/回調(diào)/添加)
本文詳細(xì)介紹下關(guān)于加載和回調(diào)的問(wèn)題、從一個(gè)store添加符合某條件記錄給另一個(gè)store中,感興趣的朋友可以參考下,希望對(duì)你有所幫助2013-04-04
ExtJs 學(xué)習(xí)筆記 Hello World!
最近學(xué)ajax,接觸到了Extjs這個(gè)強(qiáng)大的框架。我想通過(guò)我的學(xué)習(xí)筆記,最后可以讓大家上手在項(xiàng)目中使用Ext。首先我會(huì)寫一些基本的用于入門Ext的文章,打好基礎(chǔ)是很重要的。2008-12-12
Extjs在exlipse中設(shè)置自動(dòng)提示的方法
spket最好用了,而且它還支持ext,安裝起來(lái)很簡(jiǎn)單.....2010-04-04
extjs關(guān)于treePanel+chekBox全部選中以及清空選中問(wèn)題探討
treePanel+chekBox全部選中以及清空選中,想必大家在學(xué)習(xí)使用過(guò)程中都見(jiàn)過(guò)這種效果吧,接下來(lái)為大家詳細(xì)介紹下實(shí)現(xiàn)過(guò)程及細(xì)節(jié),感興趣的朋友可以參考下哈2013-04-04
入門基礎(chǔ)學(xué)習(xí) ExtJS筆記(一)
這段時(shí)間手中項(xiàng)目已經(jīng)完成,空閑時(shí)間較多。開(kāi)始了學(xué)習(xí)ExtJs之旅。2010-11-11
ExtJs3.0中Store添加 baseParams 的Bug
今天發(fā)現(xiàn)了一個(gè)ExtJS3.0中的Bug 以前用2.0的時(shí)候,喜歡這樣增加參數(shù)2010-03-03

