现在实现控件联动的有纯脚本实现和AJAX,当数据量大时,AJAX的确不错,当数据不是很多时,用AJAX就有点浪费了。
这里我们介绍如何用纯脚本实现多级联动下拉框控件的生成。
希望大家给与建议。
脚本 LinkageControl.js
负责生成多个下拉框,并实现父级控件改变时刷新子列表。
以下是页面文件内容:
这里我们介绍如何用纯脚本实现多级联动下拉框控件的生成。
希望大家给与建议。
脚本 LinkageControl.js
负责生成多个下拉框,并实现父级控件改变时刷新子列表。
- /*********************************
- 描述:多级级联控件基础脚本
- 作者:叶浩恩
- 日期:2008-8-2
- 版本:0.1
- 使用说明:
- 需要在页面进行以下初始化工作
- 1。在脚本定义前,建立脚本输出的容器
- <div id="LinkageContor"></div>
- 2。定义级联控件列表
- 3。如果需要处理最后一层节点改变,定义函数 LastLinkageControlChange()
- 4。调用初始化函数 InitControl("LinkageContor");
- 5. 支持页面回调保持原来选择
- 服务器端根据页面提交的信息,生成脚本
- var LinkageContorBindValues = new Array();
- LinkageContorBindValues[0] = "key1";
- LinkageContorBindValues[1] = "key8";
- ...
- 生成的脚本需要在调用InitControl前
- **********************************/
- // 多级级联控件树结点定义类
- function LinkageControlNode(p_name, p_value, p_level, p_chiltNodes)
- {
- // 定义 tagName 值
- this.tagName = "LinkageControlNode";
- // 节点ID
- this.KeyId = "";
- // 节点名称
- this.Name=p_name;
- // 节点值
- this.Value = p_value;
- // 节点值2,保存额外的数据
- this.Value2 = p_value;
- // 节点深度值
- this.Level = p_level;
- // 子节点列表
- if (p_chiltNodes!=null)
- this.ClientNodes = p_chiltNodes;
- else
- this.ClientNodes = new Array();
- }
- // 根据节点定义创建一个列表的 OPTION 项,并进行必要的付值。
- LinkageControlNode.prototype.CreateOptionElement= function()
- {
- // 创建列表项
- var oOption = document.createElement("OPTION");
- oOption.text = this.Name;
- oOption.value= this.Value;
- // 列表项可以通过 Node 属性访问对应的节点信息
- oOption.Node = this;
- return oOption;
- }
- // 实现多级级联控件列表数据绑定
- // ctrl: 绑定的下拉框控件
- // source:数据源 LinkageControlNode 数组,
- function BindLinkageControl(ctrl, source)
- {
- if (ctrl == null)
- alert("BindLinkageControl:: ctrl 参数为空!");
- if (ctrl.tagName != "SELECT")
- alert("BindLinkageControl:: ctrl 参数不是下拉框控件类型!");
- if (source == null)
- alert("BindLinkageControl:: source 参数为空!");
- // 清空原列表
- var i = 0;
- ctrl.options.length = 0;
- for (i = 0; i < source.length; i++)
- {
- ctrl.options[i] = source[i].CreateOptionElement();
- }
- // 如果列表只有一项,不会触发onchange事件,
- // 我们需要选择他,让它可以自动绑定到下一层空间
- if (ctrl.options.length > 0 && ctrl.options[0].Node != null && ctrl.LinkageLevel < linkageControlLevel - 1)
- {
- BindLinkageControl(ctrl.NextLevelControl, ctrl.options[0].Node.ClientNodes);
- }
- }
- // 级联控件选择变化事件处理函数
- function LinkageControlChange(e)
- {
- var oSource;
- if(e!=null)
- oSource = e.target;
- else
- oSource = window.event.srcElement;
- if (oSource == null)
- {
- alert("LinkageControlChange 无法获得当前事件源控件!");
- return;
- }
- // 取当前值
- var currentControlLevel = oSource.LinkageLevel;
- var selectOption = oSource.options[oSource.selectedIndex];
- if (selectOption == null)
- {
- alert("无法获得当前选择项数据!");
- return;
- }
- //alert("selectOption="+selectOption);
- //alert("selectOption.Node="+selectOption.Node);
- //alert("selectOption.Node.ClientNodes="+selectOption.Node.ClientNodes);
- var selectName = selectOption.text;
- var selectValue = selectOption.value;
- //alert("selectName="+selectName);
- //alert("selectValue="+selectValue);
- oSource.TextField.value = selectName;
- // 取下一个控件
- var nextControl = oSource.NextLevelControl;
- //alert(nextControl);
- if (nextControl == null)
- {
- alert("无法获得下一个级联控件!");
- return;
- }
- if (selectOption.Node == null)
- {
- alert("当前选择项未设置 Node 数据!");
- return;
- }
- // 重新绑定内容
- BindLinkageControl(nextControl, selectOption.Node.ClientNodes);
- }
- // 创建级联控件
- function CreateLinkageControl(obj, level, linkageContorName, linkageContorTitle)
- {
- if (obj == null)
- {
- alert("CreateLinkageControl obj 参数为空!");
- return ;
- }
- if (typeof(level) != "number")
- {
- alert("CreateLinkageControl level 参数为空或不是整数!");
- return;
- }
- if (level < 2)
- {
- alert("CreateLinkageControl level 参数值小于2,无法创建级联控件!");
- return;
- }
- // 存放控件的数组
- var listControls = new Array();
- var i = 0;
- // 检查是否需要显示标题
- var bCreateLabel = (typeof(linkageContorTitle)!="undefined");
- for (i = 0; i < level; i++)
- {
- // 控件名称和ID
- var ctrlName = linkageContorName + "_" + i;
- // 建立一个隐藏域,存放选择项的文本值。
- var textFieldName = ctrlName + "_text";
- var textField = document.createElement("input");
- textField.type = "hidden";
- textField.id = textFieldName;
- textField.name = textFieldName;
- // 加入列表
- obj.appendChild(textField);
- if(bCreateLabel && linkageContorTitle[i] != null)
- {
- // 创建标题字符
- var label = document.createElement("LABEL");
- label.FOR = ctrlName;
- label.innerHTML = linkageContorTitle[i];
- obj.appendChild(label);
- }
- // 创建下拉框
- listControls[i] = document.createElement("select");
- listControls[i].id = ctrlName;
- listControls[i].name = ctrlName;
- listControls[i].LinkageLevel = i;
- listControls[i].TextField = textField;
- if (i > 0){
- listControls[i - 1].NextLevelControl = listControls[i];
- }
- // 加入列表
- obj.appendChild(listControls[i]);
- // 绑定改变选择事件
- // 如果不是最后一层空间,绑定 LinkageControlChange 函数
- if (i < linkageControlLevel - 1){
- listControls[i].onchange = LinkageControlChange;
- }
- else
- { // 最后一层时,如果用户定义了 LastLinkageControlChange 函数,则绑定该函数
- if (typeof(LastLinkageControlChange) == "function")
- {
- listControls[i].onchange = LastLinkageControlChange;
- }
- }
- }
- //alert("创建级联控件"+listControls.length);
- return listControls;
- }
- // 处理页面回传后的控件绑定
- function RebindControl(listControls, linkageControlLevel)
- {
- // 检查由服务器端输出的原控件值。
- // 当页面PostBack后,需要将原控件的值,填写道教本数组 LinkageContorBindValues 中。
- if (typeof(LinkageContorBindValues) == "undefined")
- {
- return;
- }
- var i = 0, j = 0;
- // 检查每个下拉框控件
- for (i = 0; i < linkageControlLevel && i < listControls.length; i++)
- {
- // 将下拉框每个选择项值与服务器绑定值比较
- for (j = 0 ; j < listControls[i].options.length; j++)
- {
- if (listControls[i].options[j].value == LinkageContorBindValues[i])
- {
- // 找到后,让该项选中,刷新下一个联动控件的值,并退出循环
- listControls[i].selectedIndex = j;
- if (i < linkageControlLevel -1)
- {
- BindLinkageControl(listControls[i+1], listControls[i].options[j].Node.ClientNodes);
- }
- break;
- }
- }
- }
- }
- // 初始化并创建多级绑定控件
- function InitControl(divName, linkageControlLevel, linkageContorName, linkageContorTitle, rootNodes)
- {
- var obj = document.getElementById(divName);
- if (obj == null)
- {
- alert("找不到用于填充级联控件的指定元素!");
- return;
- }
- if (rootNodes == null) return;
- // 创建级联控件
- var listControls = CreateLinkageControl(obj, linkageControlLevel, linkageContorName, linkageContorTitle);
- // 绑定第一层空间
- if (listControls != null && listControls.length > 0)
- {
- BindLinkageControl( listControls[0], rootNodes);
- RebindControl(listControls, linkageControlLevel);
- }
- }
以下是页面文件内容:
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml" >
- <head>
- <title>级联控件测试</title>
- <script src="LinkageControl.js" type="text/javascript" language="javascript"></script>
- </head>
- <body>
- <form action="LinkageControl.htm" >
- <div id="LinkageContor"></div>
- <script type="text/javascript" language="javascript">
- <!--
- // 定义级联控件数量
- var linkageControlLevel = 3;
- // 级联控件的名称
- var linkageContorName = "AreaZoneSelect";
- // 控件前面显示的标题
- var linkageContorTitle = new Array();
- i = 0;
- linkageContorTitle[i++] = "省";
- linkageContorTitle[i++] = "市";
- linkageContorTitle[i++] = "地区";
- // <%= GetRebindData() %> 调用服务器端代码。。。输出一下格式数据
- // var LinkageContorBindValues = new Array();
- // LinkageContorBindValues[0] = "key1";
- // LinkageContorBindValues[1] = "key8";
- function CreateData()
- {
- i = 0, j = 0;
- rootNodes = new Array();
- // <%= GetCreateDataScript() %> 调用服务器端代码。。。填充节点内容。。。输出一下格式数据
- rootNodes[i] = new LinkageControlNode("--请选择--", null, 0, null);
- i++;
- j = 0;
- rootNodes[i] = new LinkageControlNode("广东省", "T_guangdong", 0, null);
- rootNodes[i].ClientNodes[j] = new LinkageControlNode("深圳市", "S_shenzhen", 1, null);
- rootNodes[i].ClientNodes[j].ClientNodes[0] = new LinkageControlNode("罗湖区", "S_shenzhen_luohu", 1, null);
- rootNodes[i].ClientNodes[j].ClientNodes[1] = new LinkageControlNode("福田区", "S_shenzhen_futian", 1, null);
- j++;
- rootNodes[i].ClientNodes[j] = new LinkageControlNode("广州市", "S_guangzhou", 1, null);
- rootNodes[i].ClientNodes[j].ClientNodes[0] = new LinkageControlNode("越秀区", "S_guangzhou", 1, null);
- rootNodes[i].ClientNodes[j].ClientNodes[1] = new LinkageControlNode("荔湾区", "S_guangzhou", 1, null);
- i++;
- j = 0;
- rootNodes[i] = new LinkageControlNode("湖南省", "T_hunan", 0, null);
- rootNodes[i].ClientNodes[j] = new LinkageControlNode("长沙市", "S_changsha", 1);
- rootNodes[i].ClientNodes[j].ClientNodes[0] = new LinkageControlNode("芙蓉区", "S_changsha1", 1, null);
- rootNodes[i].ClientNodes[j].ClientNodes[1] = new LinkageControlNode("雨花区", "S_changsha2", 1, null);
- j++;
- rootNodes[i].ClientNodes[j] = new LinkageControlNode("株洲市", "S_zhuzhou", 1);
- rootNodes[i].ClientNodes[j].ClientNodes[0] = new LinkageControlNode("动物园", "S_zhuzhou1", 1, null);
- rootNodes[i].ClientNodes[j].ClientNodes[1] = new LinkageControlNode("火车站", "S_zhuzhou2", 1, null);
- return rootNodes;
- }
- InitControl("LinkageContor", linkageControlLevel, linkageContorName, linkageContorTitle, CreateData());
- --></script>
- <input type="button" value="view" onclick="alert(document.getElementById('AreaZoneSelect_2').value);" />
- </form>
- </body>
- </html>