【问题标题】:Jquery - Filter list box based on the comboboxJquery - 基于组合框过滤列表框
【发布时间】:2011-04-21 18:58:09
【问题描述】:

我有两个列表,一个显示汽车公司,第二个显示所有汽车

这是第一个组合框(第一个选项是 ALL)

<select id="company">
     <option selected="true" >ALL</option>
    <option>GM</option>
    <option>Honda</option>
    <option>Ford</option>
</select>

这是我的第二个 lisbox

<select id="names" multiple="multiple" size="8">
    <option>Chevy [GM]</option>
    <option>Buick [GM]</option>
    <option>Civic [Honda]</option>
    <option>Accord [Honda]</option>
    <option>Focus [Ford]</option>
</select>

基于第一个组合框选择,我应该在第二个列表中只显示该汽车公司的汽车。甚至第二个列表的括号中也有汽车公司的名称。这是固定格式。如果用户选择“ALL”,则再次从第一个列表中显示所有车辆。

任何人都可以给我一个想法来实现这个或为此编写代码 sn-p 吗?

感谢您的帮助

问候

基兰

【问题讨论】:

    标签: jquery list combobox filter


    【解决方案1】:

    并非所有浏览器都允许您隐藏下拉列表中的单个项目,因此您需要保留一个主列表,然后根据该列表重新填充。

    var names = $('#names option').clone();
    
    $('#company').change(function() {
        var val = $(this).val();  
        $('#names').empty();
        names.filter(function(idx, el) {
            return val === 'ALL' || $(el).text().indexOf('[' + val + ']') >= 0;
        }).appendTo('#names');
    });
    

    http://jsfiddle.net/alnitak/WsHvS/ 的工作演示

    【讨论】:

    • 感谢@Alnitak 提供的出色解决方案。我正在测试大约 12oo 条记录并让您知道结果
    • FWIW 如果需要,可以通过将 make 存储在单独的字段中来加快速度,这样每次刷新列表时不会为每一行调用 .text().indexOf() 。我也刚刚将 .html() 更改为 .text()
    • 再次感谢。刚刚测试了 1500 辆汽车,一切都很顺利。
    【解决方案2】:

    据我所知,隐藏选择选项仅适用于 Firefox,因此为了实现跨浏览器兼容性,您需要使用更多技巧(请参阅 this SO questionthis question 等)。这是我的建议:

    对于 HTML,拥有您选择的隐藏副本以及您当前提供的版本:

    <select id="company">
        <option selected="true" >ALL</option>
        <option>GM</option>
        <option>Honda</option>
        <option>Ford</option>
    </select>
    <br />
    <div id="namesDiv">
        <select id="names" multiple="multiple" size="8">
            <option>Chevy [GM]</option>
            <option>Buick [GM]</option>
            <option>Civic [Honda]</option>
            <option>Accord [Honda]</option>
            <option>Focus [Ford]</option>
        </select>
    </div>
    <select id="baseNames" multiple="multiple" size="8">
        <option>Chevy [GM]</option>
        <option>Buick [GM]</option>
        <option>Civic [Honda]</option>
        <option>Accord [Honda]</option>
        <option>Focus [Ford]</option>
    </select>
    

    使用 CSS display:none 隐藏 basenames

    然后,对于您的 jQuery,您将定期将 names 替换为 baseNames 的克隆版本并对其进行过滤。

    $(document).ready(function() {
        $("#company").change(function() {
            $("#namesDiv").empty();
            $("#baseNames").clone().appendTo("#namesDiv").attr("id", "names");
            var val = $(this).find("option:selected").val();
            if(val !== "ALL") {
                $("#names option").each(function() {
                    if($(this).val().indexOf(val) < 0) {
                        $(this).remove();
                    }
                });
            }
        });
    });
    

    你可以see this in action

    【讨论】:

    • 为什么在加载时可以轻松克隆下拉列表的两个副本[根据我的回答 ;-)]
    • @Alnitak - 我很乐意承认您的解决方案更优雅。我的只是工作。
    • 非常感谢@justkt 的客气话
    【解决方案3】:

    编辑:仅适用于 FF

    试试这个:

    $(function(){
     $("#company").change(function(){
        var val = $(this).val();
        $("#names option").hide().filter(function(){
            var regExp = new RegExp("\\[" + val + "\\]$");
            return (val == "ALL") || regExp.test($(this).text());
        }).show();
     });
    });
    

    示例:http://jsfiddle.net/Chandu/2Zppp/

    【讨论】:

    • AFAIK,仅在 Firefox 上支持隐藏选项。
    • 非常感谢您的快速回复,但不幸的是,这只适用于 Firefox
    • @Bujji:是的,刚刚意识到,检查@justkt 的答案。
    【解决方案4】:

    http://css-tricks.com/dynamic-dropdowns/

    这是您想要尝试使用文本文件的第一个选项,或者替代选项是 JSON

    【讨论】:

    • 该网站上的代码太可怕了 - 在 JSON 中将数组存储为逗号分隔文本而不是 JSON 数组?!
    【解决方案5】:

    另一种选择是为这样的选项分配一个类名:

      <select id="names" multiple="multiple" size="8">
        <option class="gm">Chevy [GM]</option>
        <option class="gm">Buick [GM]</option>
        <option class="honda">Civic [Honda]</option>
        <option class="honda">Accord [Honda]</option>
        <option class="ford">Focus [Ford]</option>
      </select>
    

    然后根据类你可以像这样显示()和隐藏():

     $(document).ready(function(){
       $("#names>option").hide();
       $("#company").change(function(){
         $("#names>option").hide();
         $("#names>." + $(this).val()).show();
         if($(this).val() == "ALL"){
              $("#names>option").show();
         }
       });
    });
    

    【讨论】:

    • 选项的显示和隐藏不是跨浏览器的。
    • @justkt 在这种情况下可以用 addClass 和 removeClass 替换。谢谢
    • .show().hide() 将 CSS 应用于元素。 IE 不支持 &lt;option&gt; 元素上的 displayvisibility,因此即使将其更改为 .addClass() 仍然会失败。
    【解决方案6】:

    您可以在第一个选择的 change() 中对第二个选择的选项进行 each(),搜索子字符串并设置禁用属性。 (但这个解决方案有一个缺陷:并非每个浏览器都支持选项的禁用属性,AFAIK。)

    更新

    如果您想完全隐藏选项,您应该考虑将第二个选择中的项目存储在某个临时存储中,并仅使用符合您条件的项目从存储中重新填充该选择。

    更新2

        var temp = new Array();
    
        $(document).ready(function(){
    
        //save in temp
        $('select#names').children().each(function(){temp.push($(this).val());});
    
        //change handler
        $('select#company').change(function(){
            var pref = $(this).val();
            $('select#names').children().remove();
    
            for(i=0;i<temp.length;i++)
            {
    
                if(pref=='ALL' || temp[i].match('.[\\[]'+pref+'[\\]]$') )
                    $('select#names').append('<option>'+temp[i]+'</option>');
            }
    
            });
        });
    

    【讨论】:

      【解决方案7】:

      编辑:经过测试并在 IE7 和 Firefox 3.6.x 上运行

      Live Demo

      HTML: 注意ALL选项上的value=""

      <select id="company">
          <option selected="true" value="">ALL</option>
          <option>GM</option>
          <option>Honda</option>
          <option>Ford</option>
      </select>
      
      <select id="names" multiple="multiple" size="8">
          <option>Chevy [GM]</option>
          <option>Buick [GM]</option>
          <option>Civic [Honda]</option>
          <option>Accord [Honda]</option>
          <option>Focus [Ford]</option>
      </select>
      

      jQuery:

      $('#company').change(function() {
          var make = $(this).val();
          $('#names').contents().each(function() {
              if (this.nodeType == 8 && this.nodeValue.length > 0 && this.nodeValue.indexOf(make) != -1) {
                  $(this).before('<option>' + this.nodeValue + '</option>');
                  $(this).remove();
              }
              else if ($(this).val().indexOf(make) == -1 && $(this).val().length > 0) {
                  $(this).replaceWith('<!--' + $(this).val() + '-->');
              }
          });
      });
      

      【讨论】:

      • 隐藏选择选项不是跨浏览器。
      • 感谢 jnpcl 。是的,正如 justkt 所说,这在 IE 或 Chrome 上不起作用
      • @Bujji:正在研究替代解决方案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-15
      • 1970-01-01
      • 2011-01-18
      • 1970-01-01
      • 2020-01-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多