65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 jQuery 和 XML 创建级联下拉列表

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.46/5 (11投票s)

2010年3月19日

CPOL

6分钟阅读

viewsIcon

66457

downloadIcon

2175

本文介绍了在表示分层数据集中的数据时,如何创建链式下拉列表。

prog-snapshot.jpg

exec-snapshot.jpg

引言

本文将介绍如何创建链式下拉菜单,用于表示分层数据集中的数据。在这里,我将讨论使用客户端 jQuery 脚本填充服务器端 HTML 下拉列表的方法。我的数据库是一个简单的 XML 数据文件。jQuery 通过调用 AJAX 为 XML 数据文件提供了具体支持。使用 jQuery 的 AJAX 调用响应速度更快,并且为大多数 ASP.NET 控件提供了最佳支持。

Using the Code

本文示例程序使用了两个 .JS 文件,第一个是从 jQuery 网站下载的最新版本 jQuery 文件。另一个文件 (dropdown.js) 负责程序的运行。

我的链式下拉菜单从 Level0 开始,一直到 Level2,但可以根据需要增加或减少层级。Level0 处的 DropDownList 中的数据是硬编码在页面上的,包含两个项目:“Cars”和“Bikes”。当用户选择“Cars”时,Level1 处的 DropDownList 中会填充可用“Cars”的列表;对于“Bikes”也是如此,可用自行车的列表会出现并被填充。Level2 处的第三个 DropDownList 将填充 Level1 中选定汽车或自行车的可用“Brands”。所有这些工作都由“dropdown.js”文件中定义的两个函数完成。当用户单击页面上的一个按钮时,将调用同一文件中的另一个函数。此单击操作将从所有下拉列表中提取所选数据,并将其填充到页面上的一个 div 中(例如,Cars --> Tata --> Nano)。最初,Level1Level2 处的下拉列表以及按钮是禁用的。一旦 Level1 处的列表被填充,它就会被启用;当 Level2 处的列表被填充时,按钮和此列表都会被启用。

有一个 XML 文件“Motors.xml”,该文件存储了我们的所有数据。当我们为“Cars”填充数据时,会提取并填充 <motoc> 节点;对于“Bikes”,则提取 <motob> 节点;对于“Cars Brands”,提取 <motocb> 节点;对于“Bikes Brands”,则提取 <motobb> 节点。

我将在页面上使用的四个元素的 ID 分别是:drpMainLevel0 处的下拉列表)、drpMotoLevel1 处的下拉列表)、drpBrandLevel2 处的下拉列表)和 btnGo(单击按钮)。所以当我写到 drpMain 时,就是指 Level0 处的下拉列表,以此类推。

现在,‘dropdown.js’文件中的第一个 jQuery 函数负责填充 Level1 处的列表,如下所示(此函数在‘drpMain’的‘onchange’事件处被调用)。

    $.fillM = function()
    {
        $('#drpMoto option').remove();
        $('#drpBrand option').remove();
        $('#drpMoto').attr('disabled',true);
        $('#drpBrand').attr('disabled',true);
        $('#btnGo').attr('disabled',true);
        if($('#drpMain').val() != "0")
        {
            if($('#drpMain').val() == "1")
            {
                $.ajax({
                    type: "GET",
                    url: "XMLFiles/Motors.xml",
                    dataType: "xml",
                    success: function(xml) {
                    $(xml).find('motoc').each(function(){
                        $('#drpMoto').append($('<option></option>').val
			($(this).attr('mcid')).html($(this).attr('mcname')));
                    });
                 }
              }); 
              
           }
           else if($('#drpMain').val() == "2")
           {
                  $.ajax({
                    type: "GET",
                    url: "XMLFiles/Motors.xml",
                    dataType: "xml",
                    success: function(xml) {
                    $(xml).find('motob').each(function(){
                    $('#drpMoto').append($('<option></option>').val
			($(this).attr('mbid')).html($(this).attr('mbname')));
                    });
                 }
              });  
           }
           $('#drpMoto').removeAttr('disabled');
        }
    }

当‘drpMain’的选择发生变化时,‘drpMoto’和‘drpBrand’中的选项将被移除,并且这两个列表和按钮都会被禁用。这已在上一个函数的开始五行中完成。

第六行有一个条件语句,程序在此处检查选定的值。如果找到非零值,则表示选择了默认选项以外的内容,并且控件进入条件块。否则,控件在不启用任何禁用元素的情况下退出函数。

进入条件块后,会检查所选值是 1(代表‘Cars’)还是 2(代表‘Bikes’)。然后,会执行针对 Motor.xml 的 AJAX 调用,并提取以 <motoc> 开头的节点(针对选定的值 1)或以 <motob> 开头的节点(针对选定的值 2)。从提取的节点中获取的数据现在将填充到‘drpMoto’(Level1 处的下拉列表)中,并且‘drpMoto’将被启用以供选择。

现在,‘dropdown.js’文件中的第二个 jQuery 函数负责填充 Level2 处的列表,如下所示(此函数在‘drpMoto’的‘onchange’事件处被调用)。

    $.fillS = function()
    {
        $('#drpBrand option').remove();
        $('#drpBrand').attr('disabled',true);
        $('#btnGo').attr('disabled',true);
        if($('#drpMoto').val() != "0")
        {
            if($('#drpMain').val() == "1")
            {
              $.ajax({
                    type: "GET",
                    url: "XMLFiles/Motors.xml",
                    dataType: "xml",
                    success: function(xml) {
                    $(xml).find('motocb').each(function(){
                    
                        if($(this).attr('mcid') == $('#drpMoto').val())
                        $('#drpBrand').append($('<option></option>').val
			($(this).attr('mcbid')).html($(this).attr('mcbname')));
                    });
                 }
              }); 
            }
            else if($('#drpMain').val() == "2")
            {
                $.ajax({
                    type: "GET",
                    url: "XMLFiles/Motors.xml",
                    dataType: "xml",
                    success: function(xml) {
                    $(xml).find('motobb').each(function(){
                        
                        if($(this).attr('mbid') ==  $('#drpMoto').val())
                        $('#drpBrand').append($('<option></option>').val
			($(this).attr('mbbid')).html($(this).attr('mbbname')));
                    });
                 }
              }); 
            }
            $('#drpBrand').removeAttr('disabled');
            $('#btnGo').removeAttr('disabled');
        }
    }   

当‘drpMoto’的选择发生变化时,‘drpBrand’中的选项将被移除,并且‘drpBrand’和按钮都会被禁用。这已在上一个函数的开始三行中完成。

第四行有一个条件语句,程序在此处检查选定的值。如果找到非零值,则表示选择了默认选项以外的内容,并且控件进入条件块。否则,控件在不启用任何禁用元素的情况下退出函数。

进入条件块后,会检查在‘drpMain’处选定的值是 1(代表‘Cars’)还是 2(代表‘Bikes’)。然后,会执行针对 Motor.xml 的 AJAX 调用,并提取以 <motocb> 开头的节点(针对选定的值 1)或以 <motobb> 开头的节点(针对选定的值 2)。从提取的节点中获取的数据现在将根据选定的汽车或自行车进行过滤,然后填充到‘drpBrand’(Level2 处的下拉列表)中,并且‘drpBrand’和按钮将被启用。

此函数中还有一个额外的功能,即过滤选定汽车或自行车的品牌数据。这类似于我们在 SQL/Oracle 中使用外键。其目的是提取子表中的数据行,以匹配基表中的特定主键值。但这里没有外键,这是通过使用条件来匹配基元素(mcid/mbid)与子元素来实现的。如果匹配,则填充到‘drpBrand’中;否则,将被忽略。

请看上面函数中的这部分代码。

    $(xml).find('motocb').each(function(){               
       if($(this).attr('mcid') == $('#drpMoto').val())
          $('#drpBrand').append($('<option></option>').val
		($(this).attr('mcbid')).html($(this).attr('mcbname')));
    });   

当循环进行时,在将数据填充到‘drpBrand’之前,会每次检查一个条件。

现在,我们的 Level2 DropDownList 和用于单击的按钮均已可用。当用户单击按钮时,所选结果将显示在页面上的一个 div 中。请看‘dropdown.js’文件中的第三个函数。

    $.redP = function()
    {
        if($('#drpMain').val() != "0" && $('#drpMoto').val() != "0" 
				&& $('#drpBrand').val() != "0")
                $('#dResult').html("Searched for: " + 
		$('#drpMain option:selected').text() + "-->" + 
		$('#drpMoto option:selected').text() + "-->" + 
		$('#drpBrand option:selected').text()); 
    }   

演示程序的结束。

修订

关于这篇文章,我收到一个查询。提问者认为这个程序无法与服务器端回发一起工作。也就是说,当页面回发到服务器时,所有数据都会丢失。这都是因为在通过客户端编程填充控件时缺乏视图状态。不过,我已经为此添加了一个解决方案,其中我使用 Cookie 来管理状态。在 새로 업로드된 예제에서는 쿠키 플러그인인 추가 .JS 파일이 포함되어 있습니다. 자세한 내용은 메시지 게시판에서 Dianal의 쿼리와 제가 제공한 제안을 읽어보시기 바랍니다.

值得思考的点

实际演示文件已附上。您在查看下载文件时会很容易理解。如果您使用的是 ASPX DropDownList,在向其添加数据和收集选定值时可能会遇到困难。因此,最好使用 HTML select 控件,并通过添加 runat="server" 来将其设置为服务器端控件。后者效果很好。您可能对我的另一篇关于使用服务器端编程实现相同功能(链式下拉列表)的文章感兴趣。您可以阅读 使用 AJAX 和 XML 创建链式下拉列表

结束语

希望这些内容对您有所帮助。感谢您的阅读。祝您好运!

© . All rights reserved.