【问题标题】:Using jQuery to filter a table from multiple select elements使用 jQuery 从多个选择元素中过滤表格
【发布时间】:2016-12-28 18:18:37
【问题描述】:

我想根据用户从多个选择元素中选择的内容使用 jQuery 隐藏/显示过滤表。

我希望用户能够从 1、2 或 3 个选择元素中选择多个值。因此,也许他们会选择 2 名培训师、1 名新兵和 1 名身份,或者可能只选择 1 名培训师。计划创建一个在用户单击任何选项时将运行的函数。

在我看来,每个选择元素都有一个用户选择的值数组。所以我需要遍历每个数组并将其与该特定列中的文本进行比较。如果选项仅来自 1 个选择元素,那就很容易了。但由于它可能是 1、2 或全部 3,我很难理解它。

任何帮助将不胜感激。

表:

<table id="reportsTable">
  <thead>
    <th>Report Number</th>
    <th>Date</th>
    <th>Name</th>
    <th>Trainer</th>
    <th>Status</th>
  </thead>
  <tbody>
    <tr>
      <td>12345-1</td>
      <td>05/01/2011</td>
      <td>First Recruit</td>
      <td>First Trainer</td>
      <td>Complete</td>
    </tr>
    <tr>
      <td>12345-2</td>
      <td>05/02/2011</td>
      <td>First Recruit</td>
      <td>Second Trainer</td>
      <td>In Progress</td>
    </tr>
    <tr>
      <td>54321-1</td>
      <td>05/03/2011</td>
      <td>Second Recruit</td>
      <td>First Trainer</td>
      <td>Created</td>
    </tr>
  </tbody>
</table>

选择:

<select multiple="multiple" name="trainerFilter">
  <option value="firsttrainer">First Trainer</option>
  <option value="secondtrainer">Second Trainer</option>
</select>
<select multiple="multiple" name="recruitFilter">
  <option value="firstrecruit">First Recruit</option>
  <option value="secondrecruit">Second Recruit</option>
</select>
<select multiple="multiple" name="statusFilter">
  <option value="created">Created</option>
  <option value="inprogress">In Progress</option>
  <option value="complete">Complete</option>
</select>

看起来我无法在 8 小时内发布我的问题的答案,但感谢@Spencer Ruport,这是我想出的。由于必须考虑所有可能的条目,它最终比我预期的要复杂得多。用户可以从第一个选择元素中选择一些东西,从第二个中选择什么,从第三个中选择 2。或者,也许用户没有从第一个中选择任何东西,而从第二个中没有选择 2。对于任何给定的输入,可能需要应用超过 6 个过滤器。

我确信有比这更好的方法,而且看起来 @Alison 可能已链接到一个,但它确实有效。

    function filterReports() {
        $('.report').hide(); //Set all rows to hidden.
        trainerVals = $('#trainerFilter').val();
        recruitVals = $('#recruitFilter').val();
        statusVals = $('#statusFilter').val();
        if (trainerVals) { //Check if any trainers are selected.
            $.each(trainerVals, function(index, trainer) {
                filtered = false; 
                classString = '';
                classString += '.' + trainer;
                if (recruitVals) { //Check if trainers and recruits are selected.
                    $.each(recruitVals, function(index, recruit) {
                        filtered = false;
                        secondString = ''; 
                        secondString = classString + '.' + recruit; //Concat to a new string so we keep the old one intact.
                        if (statusVals) { //Check if trainers, recruits and statuses are selected.
                            $.each(statusVals, function(index, status) {
                                filtered = false;
                                finalString = '';
                                finalString += secondString + '.' + status; //Again concat to a new string.
                                $(finalString).show();
                                filtered = true; //By setting filtered to true, we only run the show once.
                            });
                        }
                        if (!filtered) { //If trainers and recruits are selected, but not a status, we need to apply that filter.
                            $(secondString).show();
                            filtered = true;
                        }
                    });
                }
                if (!filtered && statusVals) { //If only trainers and statuses are selected, go through those.
                    $.each(statusVals, function(index, status) {
                        filtered = false;
                        finalString = '';
                        finalString += classString + '.' + status;
                        $(finalString).show();
                        filtered = true;
                    });
                }
                if (!filtered) { //If only trainers are selected, apply that filter.
                    $(classString).show();
                    filtered = true;
                }
            });
        }
        if (!filtered && recruitVals) { //If trainers are not selected, by recruits are, run through the recruits.
            $.each(recruitVals, function(index, recruit) {
                classString = '';
                classString += '.' + recruit;
                if (statusVals) { //Check if recruits and statuses are selected
                    $.each(statusVals, function(index, status) {
                        finalString = '';
                        finalString += classString + '.' + status;
                        $(finalString).show();
                        filtered = true;
                    });
                }
                if (!filtered) { //If only recruits are selected, apply that filter.
                    $(classString).show();
                    filtered = true;
                }
            });
        }
        if (!filtered && statusVals) { //If both trainers and recruits are not selected, but statuses are, run through those.
            $.each(statusVals, function(index, status) {
                classString = '';
                classString += '.' + status;
                $(classString).show();
                filtered = true;
            });
        }
        if (!filtered) {
            //No filters selected.
        }
        $("tr").removeClass("even"); //Remove current zebra striping.
        $("tr:visible:even").addClass("even"); //Add zebra striping only for rows that are visible.
    }

【问题讨论】:

    标签: jquery html filter html-table


    【解决方案1】:

    看看 jQuery Datatables plug-in。它使操作 HTML 表格变得轻而易举。通过一些简单的设置更改,您可以轻松地做您正在寻找的事情(以及更多)。

    请务必查看filtering using select elements上的示例

    【讨论】:

      【解决方案2】:

      使用多个类非常简单(当它们不用于样式时,我通常称它们为标记。)

      <table>
        <thead>
          <th>Report Number</th>
          <th>Date</th>
          <th>Name</th>
          <th>Trainer</th>
          <th>Status</th>
        </thead>
        <tbody>
          <tr class="obj_first_recruit obj_first_trainer obj_complete obj_row_item">
            <td>12345-1</td>
            <td>05/01/2011</td>
            <td>First Recruit</td>
            <td>First Trainer</td>
            <td>Complete</td>
          </tr>
          <tr class="obj_first_recruit obj_second_trainer obj_in_progress obj_row_item">
            <td>12345-2</td>
            <td>05/02/2011</td>
            <td>First Recruit</td>
            <td>Second Trainer</td>
            <td>In Progress</td>
          </tr>
          <tr class="obj_second_recruit obj_first_trainer obj_created obj_row_item">
            <td>54321-1</td>
            <td>05/03/2011</td>
            <td>Second Recruit</td>
            <td>First Trainer</td>
            <td>Created</td>
          </tr>
        </tbody>
      </table>
      

      然后,只要您想过滤,只需将所有相应的标记与句点连接起来,例如:

      $(".obj_row_item").hide();
      $(".obj_first_recruit.obj_second_trainer.obj_in_progress").show();
      

      为简单起见,您可以使下拉列表的值与标记名称相对应,使您的语句看起来像:

      $("." + $("#dropdown1").val() + "." + $("#dropdown2").val() + "." + $("#dropdown3").val()).show();
      

      【讨论】:

      • 我什至没有想到这一点。有时最简单的答案是最好的。我必须在每个选择元素中考虑多个选项。有没有不使用 3 个 $.each 语句的简单方法?
      • 啊,我没注意到你在使用选择。由于所有项目一开始都是隐藏的,我只需要创建一个三层循环,遍历选择并连接每个组合,并在有意义的情况下为每个组合调用 show。只需为包含所选项目的当前迭代的每个级别创建一个变量,然后更改我上面写的连接行以使用变量而不是 vals。
      • 感谢您的帮助!由于可能的用户输入,循环最终变得更加复杂。他们可以从第一个输入中选择一对,例如从第二个输入中什么都没有,或者从第三个输入中选择几个。我用我想出的东西编辑了我的问题。我怀疑它甚至接近最有效的方法,但它确实有效。谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-20
      • 1970-01-01
      • 2010-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-20
      相关资源
      最近更新 更多