`

多级联动下拉框控件实现

阅读更多
现在实现控件联动的有纯脚本实现和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>


以上文章出自http://blog.csdn.net/greenery/archive/2008/08/28/2844579.aspx
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics