ExtJs 3 自定义combotree
生活随笔
收集整理的這篇文章主要介紹了
ExtJs 3 自定义combotree
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
ExtJs 3 自定義combotree
/*** 自定義下拉樹,支持初始化值時(shí)自動(dòng)定位樹節(jié)點(diǎn)。* 還沒有考慮性能問(wèn)題。繼承自Ext.form.ComboBox也很浪費(fèi)。* 代碼中的cu.get()是自定義的異步請(qǐng)求方法。* @author Linzongxue* @create_date 2011-12-13*/ Ext.ux.ComboBoxTree = Ext.extend(Ext.form.ComboBox, {//樹的配置項(xiàng)dataUrl: null, //獲取樹所有節(jié)點(diǎn)的url//通過(guò)id獲取某個(gè)節(jié)點(diǎn)的id全路徑的url,返回值的格式應(yīng)該是:parentId1/parentId2/parentId3/../節(jié)點(diǎn)id//如果不設(shè)置這個(gè)值,下拉樹不會(huì)自動(dòng)定位節(jié)點(diǎn)并在初始化時(shí)顯示文本nodePathUrl: null,loader: null,root: {},rootVisible: false,//樹的選擇模式rootSelectable: false, //根節(jié)點(diǎn)是否可選,默認(rèn)為falsefolderSelectable: true, //目錄是否可選,默認(rèn)為trueleafSelectable: true, //葉子是否可選,默認(rèn)為trueshowFullPath: false, //是否顯示全路徑rootValue: undefined, //根節(jié)點(diǎn)的值(通常根節(jié)點(diǎn)的取值與普通節(jié)點(diǎn)的取值不一樣,如果一樣則不需要設(shè)置此值)//原combo類的配置項(xiàng)store: new Ext.data.SimpleStore({fields:[],data:[[]]}),mode: 'local',triggerAction: 'all',editable: false,forceSelection: true,tree: null, //樹控件,在expand方法中初始化//private: 用于防止combo收縮,在樹的事件中控制此屬性值preventCollapse: false,initComponent: function(){this.treeId = Ext.id();this.height = this.height || 200;this.tpl = String.format('<tpl for="."><div id="{0}" style="height:{1}px"></div></tpl>', this.treeId, this.height);Ext.ux.ComboBoxTree.superclass.initComponent.call(this);},setValue: function(value){if (Ext.isObject(value)){ //點(diǎn)擊樹節(jié)點(diǎn)時(shí)的選擇this.doSetValue(value);}else{ //只是設(shè)置一個(gè)值,從后臺(tái)獲取這個(gè)值的路徑,并在樹中選中這個(gè)節(jié)點(diǎn)//console.log(value);if (!this.tree) this.initTree();if (value === this.tree.root.id || (Ext.isDefined(this.rootValue) && value === this.rootValue)){ //根節(jié)點(diǎn)this.tree.root.select();this.doSetValue(this.root);return;}var url = this.nodePathUrl;if (!url){this.doSetValue({id: value});return;}cu.get(url, {id: value}).done(function(path){//從后臺(tái)發(fā)起請(qǐng)求獲取id路徑path = '/' + this.root.id + (path.indexOf('/') == 0 ? '' : '/') + path;var comboTree = this;this.tree.selectPath(path, 'id', function(success, node){comboTree.doSetValue(success ? node : null);});}, this);}},//private:設(shè)置值,參數(shù)value應(yīng)該是一個(gè)對(duì)象doSetValue: function(value){var id = value ? value.id : '';var text = value ? value.text : '';if (value && (value.loader || value.attributes)){ //是樹節(jié)點(diǎn)var isRootNode = (value.id == this.tree.root.id);if (isRootNode && Ext.isDefined(this.rootValue)){id = this.rootValue;}if (this.showFullPath){text = isRootNode ? '/' : value.getPath('text').replace('/' + this.tree.root.text, '');}}this.value = id;if(this.hiddenField){this.hiddenField.value = id; //設(shè)置表單域}this.lastSelectionText = text;this.el.dom.value = text; //顯示的值this.fireEvent('select', this, value);},getValue : function(){return Ext.isDefined(this.value) ? this.value : '';},//取得選中的樹節(jié)點(diǎn)getValueNode: function(){return this.tree ? this.tree.getSelectionModel().getSelectedNode() : null;},getText: function(){return this.lastSelectionText || '';},reload: function(){if (!this.tree) return;var node = this.tree.getSelectionModel().getSelectedNode();var path = node ? node.getPath() : null;this.tree.getLoader().load(this.tree.root, function(){if (path) {this.tree.selectPath(path);}}, this);this.preventCollapse = true;},//private: 根據(jù)preventCollapse屬性判斷是否要收縮collapse: function(){if (this.preventCollapse){this.preventCollapse = false;return;}Ext.ux.ComboBoxTree.superclass.collapse.call(this);},//private:expand : function(){Ext.ux.ComboBoxTree.superclass.expand.call(this);if (!this.tree){this.initTree();}},//private:destroy: function(){if (this.tree && this.tree.rendered) this.tree.destroy();Ext.form.ComboBox.superclass.destroy.call(this);},//privateinitTree: function(){if (!this.list){ //必須先初始化列表,在一開始就設(shè)置了combotree的值時(shí)尤其重要,發(fā)現(xiàn)這個(gè)問(wèn)題花了半天時(shí)間this.initList();}//設(shè)置this.preventCollapse=true,防止combo收縮var enableCollapse = function(){this.preventCollapse = false;};//設(shè)置this.preventCollapse=false,允許combo收縮var disableCollapse = function(){this.preventCollapse = true;};this.tree = new Ext.tree.TreePanel({renderTo: this.treeId,useArrows: false,autoScroll: true,height: this.height, //修復(fù)IE的buganimate: true,enableDD: false,containerScroll: true,border: false,dataUrl: this.dataUrl,loader: this.loader,root: this.root,rootVisible: this.rootVisible, // bbar:[ // '->', {text: '刷新', handler: this.reload, iconCls: 'icon-refresh', scope: this} //由于寬度問(wèn)題取消此功能 // ],listeners: {click: function(node){disableCollapse();if (node == this.tree.root){ //選中根節(jié)點(diǎn)if (!this.rootSelectable) return;}else if (!node.isLeaf()){ //選中目錄節(jié)點(diǎn)if (!this.folderSelectable) return;}else{ //選中葉子節(jié)點(diǎn)if (!this.leafSelectable) return;}//先選擇節(jié)點(diǎn),再設(shè)置value,讓getNodeValue方法在select事件中取到正確的值node.select();this.setValue(node);enableCollapse();},//展開和收縮節(jié)點(diǎn)時(shí)防止combo收縮beforeexpandnode: disableCollapse,beforecollapsenode: disableCollapse,beforeload: disableCollapse,//節(jié)點(diǎn)加載和展開后允許combo收縮load: enableCollapse,expandnode: enableCollapse,scope: this}});} }); Ext.reg('combotree', Ext.ux.ComboBoxTree);/**************** 下面是一個(gè)使用例子 ***********************/ new Ext.ux.ComboBoxTree({fieldLabel:'父菜單',hiddenName: 'parentId',value: this.modifyId ? '' : this.parentMenu.id,height: 180,dataUrl: 'sys/menu/getMenus.do',nodePathUrl: 'sys/util/getEntityIdPath.do?c=sys.entity.Menu',root: {id:'root', text:'根菜單', expanded: true},rootVisible: true,rootSelectable: true,rootValue: null,showFullPath: true,allowBlank: false, }); 1 樓 chuanmeiwc 2011-12-29?? cu.get這個(gè)方法能不能一并貼出來(lái)呢? 2 樓 chuanmeiwc 2011-12-29?? chuanmeiwc 寫道 cu.get這個(gè)方法能不能一并貼出來(lái)呢?這個(gè)問(wèn)題可以忽略了,還有個(gè)問(wèn)題想請(qǐng)教下:
如果llowBlank設(shè)置為true,選中某個(gè)節(jié)點(diǎn)之后想清空值怎么辦呢? 3 樓 chuanmeiwc 2011-12-30?? chuanmeiwc 寫道 chuanmeiwc 寫道 cu.get這個(gè)方法能不能一并貼出來(lái)呢?
這個(gè)問(wèn)題可以忽略了,還有個(gè)問(wèn)題想請(qǐng)教下:
如果llowBlank設(shè)置為true,選中某個(gè)節(jié)點(diǎn)之后想清空值怎么辦呢?
我的解決辦法是在構(gòu)造tree的時(shí)候增加一個(gè)帶有清除按鈕的tbar:
var combo = this;this.tree = new Ext.tree.TreePanel({renderTo: this.treeId,useArrows: false,autoScroll: true,height: this.height, //fix IEanimate: true,enableDD: false,containerScroll: true,border: false,dataUrl: this.dataUrl,[color=red]tbar: [{text:'清空',xtype:'button',iconCls:'reset',handler:function(){combo.setValue(null);}}],[/color]loader: this.loader,root: this.root,rootVisible: this.rootVisible
還有沒有更好的解決辦法呢?
另外還有個(gè)問(wèn)題:
獲取某個(gè)節(jié)點(diǎn)的值時(shí)只能用 Ext.getCmp('comboboxtree').getNodeValue().id 嗎?我試了getValue()和getRawValue(),均不能獲取到節(jié)點(diǎn)的id。但是使用這個(gè)方法獲取節(jié)點(diǎn)id有個(gè)問(wèn)題,只有點(diǎn)擊了comboBox之后,才會(huì)異步獲取樹,因此沒有點(diǎn)擊過(guò)comboBox的時(shí)候,Ext.getCmp('comboboxtree').getNodeValue()的值為null,所以使用Ext.getCmp('comboboxtree').getNodeValue().id之前要先判斷Ext.getCmp('comboboxtree').getNodeValue()是否為null,否則會(huì)報(bào)錯(cuò)。
這個(gè)問(wèn)題你有別的辦法解決嗎? 4 樓 chuanmeiwc 2011-12-30?? chuanmeiwc 寫道
如果allowBlank設(shè)置為true,選中某個(gè)節(jié)點(diǎn)之后想清空值怎么辦呢?
我的解決辦法是在構(gòu)造tree的時(shí)候增加一個(gè)帶有清除按鈕的tbar:
var combo = this;
??? this.tree = new Ext.tree.TreePanel({
??? renderTo: this.treeId,
??? useArrows: false,
??? ??? autoScroll: true,
??? ??? height: this.height,? //fix IE
??? ??? animate: true,
??? ??? enableDD: false,
??? ??? containerScroll: true,
??? ??? border: false,
dataUrl: this.dataUrl,
tbar: [{text:'清空',xtype:'button',iconCls:'reset',handler:function(){combo.setValue(null);}}],
loader: this.loader,
root: this.root,
rootVisible: this.rootVisible
還有沒有更好的解決辦法呢?
另外還有個(gè)問(wèn)題:
獲取某個(gè)節(jié)點(diǎn)的值時(shí)只能用 Ext.getCmp('comboboxtree').getNodeValue().id 嗎?我試了getValue()和getRawValue(),均不能獲取到節(jié)點(diǎn)的id。但是使用這個(gè)方法獲取節(jié)點(diǎn)id有個(gè)問(wèn)題,只有點(diǎn)擊了comboBox之后,才會(huì)異步獲取樹,因此沒有點(diǎn)擊過(guò)comboBox的時(shí)候,Ext.getCmp('comboboxtree').getNodeValue()的值為null,所以使用Ext.getCmp('comboboxtree').getNodeValue().id之前要先判斷Ext.getCmp('comboboxtree').getNodeValue()是否為null,否則會(huì)報(bào)錯(cuò)。
這個(gè)問(wèn)題你有別的辦法解決嗎? 5 樓 zxlaiye 2011-12-31?? chuanmeiwc 寫道 chuanmeiwc 寫道 cu.get這個(gè)方法能不能一并貼出來(lái)呢?
這個(gè)問(wèn)題可以忽略了,還有個(gè)問(wèn)題想請(qǐng)教下:
如果llowBlank設(shè)置為true,選中某個(gè)節(jié)點(diǎn)之后想清空值怎么辦呢?
這個(gè)。。還沒有考慮?,因?yàn)椴砰_始使用ExtJs沒多久,很多應(yīng)用細(xì)節(jié)還沒機(jī)會(huì)去嘗試。我覺得你的方法也挺好了,添加“清空”的同時(shí)順便再加上一個(gè)“刷新”樹節(jié)點(diǎn)的控制都不錯(cuò)。 6 樓 zxlaiye 2011-12-31?? to chuanmeiwc
在我貼代碼之后又做了一些修改,但是修改后沒有及時(shí)更新上來(lái),太多事情要處理了啊。。。
你說(shuō)的通過(guò)getValue()取不到值的問(wèn)題,很可能是之后解決的,不用getNodeValue().id那么麻煩。。。,另外,異步發(fā)送請(qǐng)求的方法cu.get(...).done(...)只是對(duì)Ext.ajax.request做了簡(jiǎn)單的封裝,并且添加了全局的異常處理而已。這種寫法是從jquery里學(xué)過(guò)來(lái)的,我還擺脫不了一些jquery的使用習(xí)慣。 7 樓 chuanmeiwc 2011-12-31?? getValue()咋修改的呢? 8 樓 zxlaiye 2011-12-31?? chuanmeiwc 寫道 getValue()咋修改的呢?
getValue()方法只是簡(jiǎn)單地返回this.value,關(guān)鍵是doSetValue()方法中對(duì)value的設(shè)置。現(xiàn)在是不是可以取到正確的值了?如果是就應(yīng)該是之前的doSetValue()方法有問(wèn)題,具體修改了什么地方我想不起來(lái)了。。。太久了。。 9 樓 silence1214 2012-03-15?? 哥們 這個(gè)value的值死活出來(lái)不了 10 樓 silence1214 2012-03-15?? 哥,這個(gè)例子中當(dāng)一個(gè)頁(yè)面多次操作的時(shí)候會(huì)把上次的數(shù)據(jù)附加到這里來(lái),比如之前樹中只有1,2在打開就是1,2,1,2 只有點(diǎn)刷新 才可以 這是怎么回事啊,我死活找不到修改的地方 11 樓 silence1214 2012-03-16?? 經(jīng)過(guò)昨晚一夜奮戰(zhàn),上午奮戰(zhàn)。發(fā)現(xiàn)那個(gè)root一定要配置 哪怕是不需要。否則問(wèn)題一大堆。。。
總結(jié)
以上是生活随笔為你收集整理的ExtJs 3 自定义combotree的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 获取Django所有路由
- 下一篇: gulp学习笔记,基本使用流程,基本函数