combotree的總結(這個好)


1:最近有這個需求,就是ext下的combo下拉是樹,網上的例子很多,封裝的也很好,基本都可以滿足下拉框下出現想要的樹,但是我的使用情況是比如在用戶編輯的時候,要把用戶已經選擇過的數值自動再賦值到下拉框內,比如之前選擇了id為5的節點,那么編輯用戶的時候combo中自動顯示這個值

2:網上發現這樣的例子不多,有一個是iteye上面寫的,地址為http://zxlaiye.iteye.com/blog/1310556。經過測試這個里面有幾個問題所在,並且有幾個作者也沒有說明白雜用,經過修改可以用了。

3:發個實例代碼:

 

[javascript]  view plain copy print ?
  1. new Ext.ux.ComboBoxTree({  
  2.      fieldLabel : '父菜單',  
  3.      hiddenName : 'testTreeName',  
  4.      value : 11,  
  5.      height : 180,  
  6.      width : 200,  
  7.      dataUrl : PATH  
  8.        + '/do.php?mod=util&action=query_parent_department_tree',  
  9.      nodePathUrl : PATH  
  10.        + '/do.php?mod=util&action=query_department_path&id=11',  
  11.      rootVisible : false,  
  12.      rootSelectable : false,  
  13.      showFullPath : false,  
  14.      allowBlank : false,  
  15.      emptyText : '請選擇'  
  16.     })  

 

 

 

其中hiddenName 是post過去的字段

dataUrl就是生成一般的樹的路徑了,這個都和平時一樣,不一樣的地方時多了個nodePathUrl,看這個我的例子中我給初始化的value為11,這個節點在我數據庫中對應的父親節點只推到最上的路徑分別為/root/8/7/11  也就是說這個節點從剛才的路徑利用treepanel的selectPath方法直接找到這個節點,然后把這個節點text對應到combo中,把value設置給name。之前這個問題是里面有個路徑問題不可以找到,還有個地方時一個cu的函數的封裝,cu函數就是請求nodePathUrl的。里面還有個問題是如果當前tree中沒有root節點的話是對應不到的,總之我給修整好是可以用了,大家看源代碼:

 

 

 

[html]  view plain copy print ?
  1. /**  
  2.  * 自定義下拉樹,支持初始化值時自動定位樹節點。 還沒有考慮性能問題。繼承自Ext.form.ComboBox也很浪費。  
  3.  * 代碼中的cu.get()是自定義的異步請求方法。  
  4.  */  
  5. /*  
  6.  * 例子 new Ext.ux.ComboBoxTree({ fieldLabel:'父菜單', hiddenName: 'parentId', value:  
  7.  * this.modifyId ? '' : this.parentMenu.id, height: 180, dataUrl:  
  8.  * 'sys/menu/getMenus.do', 就是獲取一般tree的url nodePathUrl:  
  9.  * 'sys/util/getEntityIdPath.do?c=sys.entity.Menu',獲取需要默認選中的那個節點的路徑parentId/parentId/.../被選中節點的id  
  10.  * root: {id:'root', text:'根菜單', expanded: true}, rootVisible: true,  
  11.  * rootSelectable: true, rootValue: null, showFullPath: true, allowBlank: false,  
  12.  * });  
  13.  */  
  14. /**  
  15.  * @author Linzongxue  
  16.  * @create_date 2011-12-13  
  17.  */  
  18. Ext.ux.ComboBoxTree = Ext.extend(Ext.form.ComboBox, {  
  19.     // 樹的配置項  
  20.     dataUrl : null, // 獲取樹所有節點的url  
  21.     // 通過id獲取某個節點的id全路徑的url,返回值的格式應該是:parentId1/parentId2/parentId3/../節點id  
  22.     // 如果不設置這個值,下拉樹不會自動定位節點並在初始化時顯示文本  
  23.     nodePathUrl : null,  
  24.     loader : null,  
  25.     root : {},  
  26.     rootVisible : false,  
  27.     // 樹的選擇模式  
  28.     rootSelectable : false, // 根節點是否可選,默認為false  
  29.     folderSelectable : true, // 目錄是否可選,默認為true  
  30.     leafSelectable : true, // 葉子是否可選,默認為true  
  31.     showFullPath : false, // 是否顯示全路徑  
  32.     rootValue : undefined, // 根節點的值(通常根節點的取值與普通節點的取值不一樣,如果一樣則不需要設置此值)  
  33.     // 原combo類的配置項  
  34.     store : new Ext.data.SimpleStore({  
  35.                 fields : [],  
  36.                 data : [[]]  
  37.             }),  
  38.     mode : 'local',  
  39.     triggerAction : 'all',  
  40.     editable : false,  
  41.     forceSelection : true,  
  42.     tree : null, // 樹控件,在expand方法中初始化  
  43.     // private: 用於防止combo收縮,在樹的事件中控制此屬性值  
  44.     preventCollapse : false,  
  45.   
  46.     initComponent : function() {  
  47.         this.treeId = Ext.id();  
  48.         this.height = this.height || 200;  
  49.         this.tpl = String.format(  
  50.                 '<tpl for="."><div id="{0}" style="height:{1}px"></div></tpl>',  
  51.                 this.treeId, this.height);  
  52.         Ext.ux.ComboBoxTree.superclass.initComponent.call(this);  
  53.     },  
  54.     setValue : function(value) {  
  55.         if (Ext.isObject(value)) { // 點擊樹節點時的選擇  
  56.             this.doSetValue(value);  
  57.         } else { // 只是設置一個值,從后台獲取這個值的路徑,並在樹中選中這個節點  
  58.             if (!this.tree)  
  59.                 this.initTree();  
  60.   
  61.             if (value === this.tree.root.id  
  62.                     || (Ext.isDefined(this.rootValue) && value === this.rootValue)) { // 根節點  
  63.                 this.tree.root.select();  
  64.                 this.doSetValue(this.root);  
  65.                 return;  
  66.             }  
  67.             var url = this.nodePathUrl;  
  68.             if (!url) {  
  69.                 this.doSetValue({  
  70.                             id : value  
  71.                         });  
  72.                 return;  
  73.             }  
  74.             Ext.Ajax.request({  
  75.                         url : url,  
  76.                         async : false,  
  77.                         scope : this,  
  78.                         success : function(resp, opts) {  
  79.                             var comboTree = this;  
  80.                             path = resp.responseText;  
  81.                             path = (path.indexOf('/') == 0 ? '' : '/')  
  82.                                     +comboTree.tree.root.id+'/'+ path;  
  83.                             this.tree.selectPath(path, 'id', function(success,  
  84.                                             node) {  
  85.                                         comboTree.doSetValue(success  
  86.                                                 ? node  
  87.                                                 : null);  
  88.                                     });  
  89.                         },  
  90.                         faliure : function() {  
  91.                             alert(3)  
  92.                         }  
  93.                     });  
  94.             /*  
  95.              * cu.get(url, {id: value}).done(function(path){//從后台發起請求獲取id路徑 path =  
  96.              * '/' + this.root.id + (path.indexOf('/') == 0 ? '' : '/') + path;  
  97.              * var comboTree = this; this.tree.selectPath(path, 'id',  
  98.              * function(success, node){ comboTree.doSetValue(success ? node :  
  99.              * null); }); }, this);  
  100.              */  
  101.         }  
  102.     },  
  103.     // private:設置值,參數value應該是一個對象  
  104.     doSetValue : function(value) {  
  105.         var id = value ? value.id : '';  
  106.         var text = value ? value.text : '';  
  107.         if (value && (value.loader || value.attributes)) { // 是樹節點  
  108.             var isRootNode = (value.id == this.tree.root.id);  
  109.             if (isRootNode && Ext.isDefined(this.rootValue)) {  
  110.                 id = this.rootValue;  
  111.             }  
  112.             if (this.showFullPath) {  
  113.                 text = isRootNode ? '/' : value.getPath('text').replace(  
  114.                         '/' + this.tree.root.text, '');  
  115.             }  
  116.         }  
  117.         this.value = id;  
  118.         if (this.hiddenField) {  
  119.             this.hiddenField.value = id; // 設置表單域  
  120.         }  
  121.         this.lastSelectionText = text;  
  122.         this.el.dom.value = text; // 顯示的值  
  123.         this.fireEvent('select', this, value);  
  124.     },  
  125.     getValue : function() {  
  126.         return Ext.isDefined(this.value) ? this.value : '';  
  127.     },  
  128.     // 取得選中的樹節點  
  129.     getValueNode : function() {  
  130.         return this.tree  
  131.                 ? this.tree.getSelectionModel().getSelectedNode()  
  132.                 : null;  
  133.     },  
  134.     getText : function() {  
  135.         return this.lastSelectionText || '';  
  136.     },  
  137.     reload : function() {  
  138.         if (!this.tree)  
  139.             return;  
  140.         var node = this.tree.getSelectionModel().getSelectedNode();  
  141.         var path = node ? node.getPath() : null;  
  142.         this.tree.getLoader().load(this.tree.root, function() {  
  143.                     if (path) {  
  144.                         this.tree.selectPath(path);  
  145.                     }  
  146.                 }, this);  
  147.         this.preventCollapse = true;  
  148.     },  
  149.     // private: 根據preventCollapse屬性判斷是否要收縮  
  150.     collapse : function() {  
  151.         if (this.preventCollapse) {  
  152.             this.preventCollapse = false;  
  153.             return;  
  154.         }  
  155.         Ext.ux.ComboBoxTree.superclass.collapse.call(this);  
  156.     },  
  157.     // private:  
  158.     expand : function() {  
  159.         Ext.ux.ComboBoxTree.superclass.expand.call(this);  
  160.         if (!this.tree) {  
  161.             this.initTree();  
  162.         }  
  163.     },  
  164.     // private:  
  165.     destroy : function() {  
  166.         if (this.tree && this.tree.rendered)  
  167.             this.tree.destroy();  
  168.         Ext.form.ComboBox.superclass.destroy.call(this);  
  169.     },  
  170.     // private  
  171.     initTree : function() {  
  172.         if (!this.list) { // 必須先初始化列表,在一開始就設置了combotree的值時尤其重要,發現這個問題花了半天時間  
  173.             this.initList();  
  174.         }  
  175.         // 設置this.preventCollapse=true,防止combo收縮  
  176.         var enableCollapse = function() {  
  177.             this.preventCollapse = false;  
  178.         };  
  179.         // 設置this.preventCollapse=false,允許combo收縮  
  180.         var disableCollapse = function() {  
  181.             this.preventCollapse = true;  
  182.         };  
  183.         this.tree = new Ext.tree.TreePanel({  
  184.                     renderTo : this.treeId,  
  185.                     useArrows : false,  
  186.                     autoScroll : true,  
  187.                     height : this.height, // 修復IE的bug  
  188.                     animate : true,  
  189.                     enableDD : false,  
  190.                     containerScroll : true,  
  191.                     border : false,  
  192.                     dataUrl : this.dataUrl,  
  193.                     loader : this.loader,  
  194.                     root : this.root,  
  195.                     rootVisible : this.rootVisible,  
  196.                     // bbar:[  
  197.                     // '->', {text: '刷新', handler: this.reload, iconCls:  
  198.                     // 'icon-refresh', scope: this} //由於寬度問題取消此功能  
  199.                     // ],  
  200.                     listeners : {  
  201.                         click : function(node) {  
  202.                             disableCollapse();  
  203.                             if (node == this.tree.root) { // 選中根節點  
  204.                                 if (!this.rootSelectable)  
  205.                                     return;  
  206.                             } else if (!node.isLeaf()) { // 選中目錄節點  
  207.                                 if (!this.folderSelectable)  
  208.                                     return;  
  209.                             } else { // 選中葉子節點  
  210.                                 if (!this.leafSelectable)  
  211.                                     return;  
  212.                             }  
  213.                             // 先選擇節點,再設置value,讓getNodeValue方法在select事件中取到正確的值  
  214.                             node.select();  
  215.                             this.setValue(node);  
  216.                             enableCollapse();  
  217.                         },  
  218.                         // 展開和收縮節點時防止combo收縮  
  219.                         beforeexpandnode : disableCollapse,  
  220.                         beforecollapsenode : disableCollapse,  
  221.                         beforeload : disableCollapse,  
  222.                         // 節點加載和展開后允許combo收縮  
  223.                         load : enableCollapse,  
  224.                         expandnode : enableCollapse,  
  225.                         scope : this  
  226.                     }  
  227.                 });  
  228.     }  
  229. });  
  230. Ext.reg('combotree', Ext.ux.ComboBoxTree); 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM