当前位置: 代码迷 >> Web前端 >> Ext TreeCombo 树形 上拉框
  详细解决方案

Ext TreeCombo 树形 上拉框

热度:527   发布时间:2012-11-12 12:31:57.0
Ext TreeCombo 树形 下拉框

?

参考:http://www.extjs.com/forum/showthread.php?38654-Tree-in-a-Combo./page4

在别人基础上稍作修改

1.添加hiddenName,使传值时跟Ext.form.ComboBox类似;

2.设值时展开整棵树(在TreeCombo外实现),使弹出下拉框时默认选中节点;

?

代码如下:

/**
 * @version Base on Ext3.0
 * @class Ext.ux.TreeCombo
 * @extends Ext.form.TriggerField
 */

Ext.ux.TreeCombo = Ext.extend(Ext.form.TriggerField, {

	// triggerClass: 'x-form-tree-trigger',

	initComponent : function() {
		this.readOnly = true;
		Ext.ux.TreeCombo.superclass.initComponent.call(this);
		this.on('specialkey', function(f, e) {
					if (e.getKey() == e.ENTER) {
						this.onTriggerClick();
					}
				}, this);
		this.getTree();
	},

	onTriggerClick : function() {
		this.getTree().show();
		this.getTree().getEl().alignTo(this.wrap, 'tl-bl?');
	},

	getTree : function() {
		if (!this.treePanel) {
			if (!this.treeWidth) {
				this.treeWidth = Math.max(150, this.width || 200);
			}
			if (!this.treeHeight) {
				this.treeHeight = 200;
			}
			this.treePanel = new Ext.tree.TreePanel({
				renderTo : Ext.getBody(),
				loader : this.loader || new Ext.tree.TreeLoader({
							preloadChildren : (typeof this.root == 'undefined'),
							url : this.dataUrl || this.url
						}),
				root : this.root || new Ext.tree.AsyncTreeNode({
							children : this.children
						}),
				rootVisible : (typeof this.rootVisible != 'undefined')
						? this.rootVisible
						: (this.root ? true : false),
				floating : true,
				autoScroll : true,
				minWidth : 200,
				minHeight : 200,
				width : this.treeWidth,
				height : this.treeHeight,
				listeners : {
					hide : this.onTreeHide,
					show : this.onTreeShow,
					click : this.onTreeNodeClick,
					expandnode : this.onExpandOrCollapseNode,
					collapsenode : this.onExpandOrCollapseNode,
					resize : this.onTreeResize,
					scope : this
				}
			});
			this.treePanel.show();
			this.treePanel.hide();
			this.relayEvents(this.treePanel.loader, ['beforeload', 'load',
							'loadexception']);
			if (this.resizable) {
				this.resizer = new Ext.Resizable(this.treePanel.getEl(), {
							pinned : true,
							handles : 'se'
						});
				this.mon(this.resizer, 'resize', function(r, w, h) {
							this.treePanel.setSize(w, h);
						}, this);
			}
		}
		return this.treePanel;
	},

	onExpandOrCollapseNode : function() {
		if (!this.maxHeight || this.resizable)
			return; // -----------------------------> RETURN
		var treeEl = this.treePanel.getTreeEl();
		var heightPadding = treeEl.getHeight() - treeEl.dom.clientHeight;
		var ulEl = treeEl.child('ul'); // Get the underlying tree element
		var heightRequired = ulEl.getHeight() + heightPadding;
		if (heightRequired > this.maxHeight)
			heightRequired = this.maxHeight;
		this.treePanel.setHeight(heightRequired);
	},

	onTreeResize : function() {
		if (this.treePanel)
			this.treePanel.getEl().alignTo(this.wrap, 'tl-bl?');
	},

	onTreeShow : function() {
		Ext.getDoc().on('mousewheel', this.collapseIf, this);
		Ext.getDoc().on('mousedown', this.collapseIf, this);
	},

	onTreeHide : function() {
		Ext.getDoc().un('mousewheel', this.collapseIf, this);
		Ext.getDoc().un('mousedown', this.collapseIf, this);
	},

	collapseIf : function(e) {
		if (!e.within(this.wrap) && !e.within(this.getTree().getEl())) {
			this.collapse();
		}
	},

	collapse : function() {
		this.getTree().hide();
		if (this.resizer)
			this.resizer.resizeTo(this.treeWidth, this.treeHeight);
	},

	// private
	validateBlur : function() {
		return !this.treePanel || !this.treePanel.isVisible();
	},

	setValue : function(v) {
		this.startValue = this.value = v;
		if (this.treePanel) {
			var n = this.treePanel.getNodeById(v);//位于一级以下节点要树全部展开时才可用
			if (n) {
				n.select();//默认选中节点
				this.setRawValue(n.text);
				if (this.hiddenField)
					this.hiddenField.value = v;
			}
		}
	},

	getValue : function() {
		return this.value;
	},

	onTreeNodeClick : function(node, e) {
		this.setRawValue(node.text);
		this.value = node.id;
		if (this.hiddenField)
			this.hiddenField.value = node.id;
		this.fireEvent('select', this, node);
		this.collapse();
	},
	onRender : function(ct, position) {
		Ext.ux.TreeCombo.superclass.onRender.call(this, ct, position);
		if (this.hiddenName) {
			this.hiddenField = this.el.insertSibling({
						tag : 'input',
						type : 'hidden',
						name : this.hiddenName,
						id : (this.hiddenId || this.hiddenName)
					}, 'before', true);

			// prevent input submission
			this.el.dom.removeAttribute('name');
		}
	}
});

?

示例:

1:选择页面,在定义了根节点的情况下逐级加载

?

var businessId = new Ext.ux.TreeCombo({
			fieldLabel : '业务名称',
			width : 120,
			allowBlank : false,
			//name : 'param.businessId',
			hiddenName : 'param.businessId',
			rootVisible : true,
			root : new Ext.tree.AsyncTreeNode({
						text : '业务列表',
						expanded : true,
						levelNum : 0,
						id : '100000'
					}),
			dataUrl : 'getChild_business.do?param.superId=100000'
		});

businessId.treePanel.on('beforeload', function(node) {
	businessId.treePanel.loader.dataUrl = 'getChild_business.do?param.superId='
			+ node.id;});
后台请求回来的数据如: [{text:'业务23',id:'200024'},{text:'业务2',id:'200043'}]


?

???

?

?2.显示并修改(expandAll后再setValue)

var businessId = new Ext.ux.TreeCombo({
			fieldLabel : '业务名称',
			width : 120,
			allowBlank : false,
			hiddenName : 'param.businessId',
			rootVisible : false,
			dataUrl : 'getAllJson_business.do'
		});

businessId.treePanel.on('load', function() {
			businessId.setValue('<s:property value="#param.businessId" />');
		});
businessId.treePanel.expandAll();

?

后台请求返回的json如:
[{
			"id" : 100000,
			"text" : "业务列表",
			"leaf" : false,
			"superId" : 0,
			"children" : [{

						"id" : 200024,
						"text" : "业务23",
						"leaf" : false,
						"superId" : 100000,
						"children" : [...略]
					}, {

						"id" : 200043,
						"text" : "业务2",
						"leaf" : false,
						"superId" : 100000,
						"children" : [...略]
					}]
		}]

?

?

?
3.只读(直接用Ext.form.ComboBox)
?

后台数据返回对应项即可
[{"value":"200043","display":"业务2"}]

?


?
?

1 楼 59471032 2011-02-21  
能否把demo的附件发上来,学习下
2 楼 fireinjava 2011-02-22  
59471032 写道
能否把demo的附件发上来,学习下

你如果用Struts的话,直接在调用.do访问Action的方法
return "[{text:'业务23',id:'200024'},{text:'业务2',id:'200043'}]"即可
其它Ajax调用的类似。
3 楼 zhylfhy 2011-12-14  
能否把demo的附件发上来,谢谢
  相关解决方案