http://blog.csdn.net/kunoy/article/details/8067801
首先主要代码源自网络,对那些无私的奉献者表示感谢!
笔者对这些代码做了二次修改,并总结如下:
Extjs3.x版本下拉树代码:
- Ext.ux.TreeCombo = Ext.extend(Ext.form.ComboBox, {
- constructor : function(cfg) {
- cfg = cfg || {};
- Ext.ux.TreeCombo.superclass.constructor.call(this, Ext.apply({
- maxHeight : 300,
- editable : false,
- mode : 'local',
- triggerAction : 'all',
- rootVisible : false,
- selectMode : 'all'
- }, cfg));
- },
- store : new Ext.data.SimpleStore({
- fields : [],
- data : [[]]
- }),
- // 重写onViewClick,使展开树结点是不关闭下拉框
- onViewClick : function(doFocus) {
- var index = this.view.getSelectedIndexes()[0], s = this.store, r = s.getAt(index);
- if (r) {
- this.onSelect(r, index);
- }
- if (doFocus !== false) {
- this.el.focus();
- }
- },
- tree : null,
- // 隐藏值
- hiddenValue : null,
- getHiddenValue : function() {
- return this.hiddenValue;
- },
- getValue : function() { //增加适用性,与原来combo组件一样
- return this.hiddenValue;
- },
- setHiddenValue : function(code, dispText) {
- this.setValue(code);
- Ext.form.ComboBox.superclass.setValue.call(this, dispText);
- this.hiddenValue = code;
- },
- initComponent : function() {
- var _this = this;
- var tplRandomId = 'deptcombo_' + Math.floor(Math.random() * 1000) + this.tplId
- this.tpl = "<div style='height:" + _this.maxHeight + "px' id='" + tplRandomId + "'></div>"
- this.tree = new Ext.tree.TreePanel({
- border : false,
- enableDD : false,
- enableDrag : false,
- rootVisible : _this.rootVisible || false,
- autoScroll : true,
- trackMouseOver : true,
- height : _this.maxHeight,
- lines : true,
- singleExpand : true,
- root : new Ext.tree.AsyncTreeNode({
- id : _this.rootId,
- text : _this.rootText,
- iconCls:'ico-root',
- expanded:true,
- leaf : false,
- border : false,
- draggable : false,
- singleClickExpand : false,
- hide : true
- }),
- loader : new Ext.tree.TreeLoader({
- nodeParameter:'ID',
- requestMethod:'GET',
- dataUrl : _this.url
- })
- });
- this.tree.on('click', function(node) {
- if ((_this.selectMode == 'leaf' && node.leaf == true) || _this.selectMode == 'all') {
- if(_this.fireEvent('beforeselect',_this,node)){
- _this.fireEvent('select',_this,node);
- }
- }
- });
- this.on('select',function(obj,node){
- var dispText = node.text;
- var code = node.id;
- obj.setHiddenValue(code, dispText);
- obj.collapse();
- });
- this.on('expand', function() {
- this.tree.render(tplRandomId);
- });
- Ext.ux.TreeCombo.superclass.initComponent.call(this);
- }
- })
- Ext.reg("treecombo", Ext.ux.TreeCombo);
使用方法:
- var treecombo=new Ext.ux.TreeCombo({
- name : 'areaName',
- tplId : 'tree_tpl',
- rootVisible : true,
- rootText : '/',
- rootId:'root',
- url : 'getTreeData.aspx', maxHeight :300,
- id: 'cmbJS',
- allowBlank: true,
- selectMode:'leaf',
- width : '200'
- });
Extjs4.x版本下拉树代码一:
- Ext.define('Ext.ux.TreeComboBox',{
- extend : 'Ext.form.field.ComboBox',
- alias: 'widget.treecombo',
- store : new Ext.data.ArrayStore({fields:[],data:[[]]}),
- editable : false,
- listConfig : {resizable:true,minWidth:100,maxWidth:400,minHeight:200,maxHeight:400},
- _idValue : null,
- _txtValue : null,
- treeObj: null,
- initComponent : function(){
- var _this = this;
- this.treeObj= new Ext.tree.Panel({
- border : false,
- id:Ext.id(),
- height : 380,
- width : 400,
- autoScroll : true,
- store : Ext.create('Ext.data.TreeStore', {
- fields : ['id','text','leaf'],
- autoLoad : false,
- nodeParam: 'ID',
- proxy: {
- type: 'ajax',
- url : _this.url
- },
- root: {
- expanded: _this.expanded||false,
- id:_this.rootId||'root',
- text : _this.rootText||'/'
- }
- })
- });
- this.treeRenderId = Ext.id();
- this.tpl = "<div id='"+this.treeRenderId+"'></div>";
- this.callParent(arguments);
- this.on({
- 'expand' : function(){
- if(!this.treeObj.rendered&&this.treeObj&&!this.readOnly){
- Ext.defer(function(){
- this.treeObj.render(this.treeRenderId);
- },300,this);
- }
- }
- });
- this.treeObj.on('itemclick',function(view,rec){
- if(rec&&((_this.selectMode == 'leaf' && rec.isLeaf() == true) || _this.selectMode == 'all')){
- this.setValue(this._txtValue = rec.get('text'));
- this._idValue = rec.get('id');
- this.collapse();
- _this.fireEvent('select',_this,rec);
- }
- },this);
- },
- getValue : function(){//获取id值
- return this._idValue;
- },
- getTextValue : function(){//获取text值
- return this._txtValue;
- },
- setLocalValue : function(id,txt){//设值
- this._idValue = id;
- this.setValue(this._txtValue = txt);
- },
- reLoad:function(id,url){
- this.treeObj.getStore().proxy.url =url;
- this.treeObj.setRootNode({
- id:id,
- text:'/',
- expanded:true
- });
- }
- });
使用方法与前面基本相同。这个版本存在很多问题,当一个界面存在两个下拉树时,其中一个下拉树在第二次下拉操作时,树不会显示,如图:
另外由于tree渲染到div上,当节点过多出现滚动条时,会显示两条滚动条,一条是div本身的,一条是treepanel的,如图:
所以此版本不采用,其中添加了一个reLoad()方法,这是由于两个下拉树需要联动才添加的。
Extjs4.x版本下拉树代码二:
- Ext.define("Ext.ux.ComboTree", {
- extend : "Ext.form.field.Picker",
- alias : 'widget.combotree',
- requires : ["Ext.tree.Panel"],
- _idValue : '',
- _txtValue : '',
- initComponent : function() {
- this.callParent();
- var self = this;
- var store = Ext.create('Ext.data.TreeStore', {
- proxy : {
- type : 'ajax',
- url : self.storeUrl
- },
- nodeParam: 'ID',
- root : {
- id : self.rootId,
- text : self.rootText,
- expanded:self.expanded||false
- }
- });
- self.picker = new Ext.tree.Panel({
- id:Ext.id(),
- height : self.treeHeight||300,
- resizable:true,minWidth:100,maxWidth:400,minHeight:200,maxHeight:500,
- autoScroll : true,
- floating : true,
- focusOnToFront : false,
- shadow : true,
- ownerCt : this.ownerCt,
- useArrows : self.useArrows||true,
- store : store,
- rootVisible : true
- });
- self.picker.on({
- 'itemclick' : function(view,rec) {
- if(rec&&((self.selectMode == 'leaf' && rec.isLeaf() == true) || self.selectMode == 'all')){
- //self.setRawValue(rec.get('id'));// 隐藏值
- self._idValue = rec.get('id');
- self.setValue(self._txtValue=rec.get('text'));// 显示值
- self.collapse();
- self.fireEvent('select',self,rec);
- }
- }
- });
- },
- // createPicker : function() {
- // var self = this;
- // var store = Ext.create('Ext.data.TreeStore', {
- // proxy : {
- // type : 'ajax',
- // url : self.storeUrl
- // },
- // nodeParam: 'ID',
- // root : {
- // id : self.rootId,
- // text : self.rootText,
- // expanded:self.expanded||true
- // }
- // });
- // self.picker = new Ext.tree.Panel({
- // id:Ext.id(),
- // height : 300,
- // //resizable:true,minWidth:100,maxWidth:400,minHeight:200,maxHeight:400,
- // autoScroll : true,
- // floating : true,
- // focusOnToFront : false,
- // shadow : true,
- // ownerCt : this.ownerCt,
- // useArrows : self.useArrows||true,
- // store : store,
- // rootVisible : true
- // });
- // self.picker.on({
- // 'itemclick' : function(view,rec) {
- // if(rec&&((self.selectMode == 'leaf' && rec.isLeaf() == true) || self.selectMode == 'all')){
- // //self.setRawValue(rec.get('id'));// 隐藏值
- // self._idValue = rec.get('id');
- // self.setValue(self._txtValue=rec.get('text'));// 显示值
- // self.collapse();
- // self.fireEvent('select',self,rec);
- // }
- // }
- // });
- // return self.picker;
- // },
- getValue : function(){//获取id值
- return this._idValue;
- },
- getTextValue : function(){//获取text值
- return this._txtValue;
- },
- reLoad:function(id,url){
- var store=this.picker.getStore();
- var root=this.picker.getRootNode();
- store.proxy.url =url;
- root.set('id',id);
- store.load();
- },
- alignPicker : function() {
- var me = this, picker, isAbove, aboveSfx = '-above';
- if (this.isExpanded) {
- picker = me.getPicker();
- if (me.matchFieldWidth) {
- picker.setWidth(me.bodyEl.getWidth());
- }
- if (picker.isFloating()) {
- picker.alignTo(me.inputEl, "", me.pickerOffset);
- isAbove = picker.el.getY() < me.inputEl.getY();
- me.bodyEl[isAbove ? 'addCls' : 'removeCls'](me.openCls+ aboveSfx);
- picker.el[isAbove ? 'addCls' : 'removeCls'](picker.baseCls+ aboveSfx);
- }
- }
- }
- });
此版本解决了上述两大问题,其中注解的部分为原作者代码,使用createPicker存在一个问题,必须点击下拉操作后,treepanel才会进行渲染,那么数据联动也就谈不上了(需要联动的tree没有渲染,如何进行数据加载?),所以笔者移到initComponent下执行,另外也解决了resize的问题。
使用方法:
- var treecombo=new Ext.ux.ComboTree({
- fieldLabel: 'Test',
- labelWidth: 60,
- rootText : '/',
- rootId:'root',
- expanded:true,
- storeUrl : 'getTreeData.aspx',
- id: 'cmbJS',
- selectMode:'leaf',
- treeHeight:300,
- width : 200
- });
到此,Extjs4.1的下拉树完美了,世界太平了!