您的位置:首页 > 其它

多级联动下拉框控件实现

2008-08-28 16:44 531 查看
现在实现控件联动的有纯脚本实现和AJAX,当数据量大时,AJAX的确不错,当数据不是很多时,用AJAX就有点浪费了。
这里我们介绍如何用纯脚本实现多级联动下拉框控件的生成。
希望大家给与建议。

脚本 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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: