带有下拉列表的过滤表

时间:2018-12-20 11:24:21

标签: jquery html filtering dropdown onchange

我有一个table,并且想要过滤最后两列ArchivedFull Entry。归档的第4列将带有日期或为空。第五列完整条目为true或false。我有两个下拉菜单,第一个下拉菜单的逻辑应为:

  1. 如果选择“已存档”,则过滤第4列以仅显示行 第四列为空。

  2. 如果选择了“未归档”,则过滤第4列以仅显示行 第四列不为空。

  3. 如果选择全部,则在此列中显示全部

  1. 如果第二个下拉列表选择True,则过滤第5列以显示 仅第5列包含true的行。

  2. ....如果为false过滤第5列,其中行等于false ...

  3. ...如果全部显示在第5列中。

我无法使脚本适用于存档。感谢您的帮助

$(function() {
  $('#archive').change(function() {
    if ($(this).val() == "archived") {
      $("#filter").find("td:nth-child(3):not(:empty)")
    } else {
      $("#filter").find("td:nth-child(3):empty")
    }
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label for="archive">Filter Archive</label>
<select id="archive" name="archive">
  <option value="all">All</option>
  <option value="archived">Archived</option>
  <option value="not-archived">Not Archived</option>
</select>

<label for="type">Filter Full Entry</label>
<select id="type" name="type">
  <option value="all">All</option>
  <option value="true" selected>True</option>
  <option value="false" selected>False</option>
</select>

<table class="table" style="width: 30%" id="filter">
  <thead>
    <tr>
      <th>Ref</th>
      <th>Edit</th>
      <th>Name</th>
      <th>Archived</th>
      <th>Full Entry</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
      <td>True</td>
    </tr>
    <tr>
      <td>a</td>
      <td>b</td>
      <td>c</td>
      <td></td>
      <td>False</td>
    </tr>
    <tr>
      <td>5</td>
      <td>5</td>
      <td>6</td>
      <td></td>
      <td>True</td>
    </tr>
  </tbody>
</table>

2 个答案:

答案 0 :(得分:2)

您的逻辑是正确的,但只是不完整。还要注意,archived列是nth-child(4),而不是3,因为它是基于1的,而不是基于0的。

为简化逻辑,您可以创建一个函数,该函数在更改任何一个过滤器select元素时运行。此功能将首先显示所有行,然后隐藏所有与所选过滤器选项不匹配的行,如下所示:

$(function() {
  $('#archive, #type').change(function() {
    filterTable($('#archive').val(), $('#type').val());
  });
});

function filterTable(archive, entry) {
  var $rows = $('#filter tbody tr').show();

  if (archive == "archived") {
    $rows.filter(":has(td:nth-child(4):empty)").hide()
  } else if (archive == "not-archived") {
    $rows.filter(":has(td:nth-child(4):not(:empty))").hide()
  }

  if (entry == "true") {
    $rows.filter(":has(td:nth-child(5):contains('False'))").hide()
  } else if (entry == "false") {
    $rows.filter(":has(td:nth-child(5):contains('True'))").hide()
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label for="archive">Filter Archive</label>
<select id="archive" name="archive">
  <option value="all">All</option>
  <option value="archived">Archived</option>
  <option value="not-archived">Not Archived</option>
</select>

<label for="type">Filter Full Entry</label>
<select id="type" name="type">
  <option value="all">All</option>
  <option value="true" selected>True</option>
  <option value="false" selected>False</option>
</select>

<table class="table" style="width: 30%" id="filter">
  <thead>
    <tr>
      <th>Ref</th>
      <th>Edit</th>
      <th>Name</th>
      <th>Archived</th>
      <th>Full Entry</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
      <td>True</td>
    </tr>
    <tr>
      <td>a</td>
      <td>b</td>
      <td>c</td>
      <td></td>
      <td>False</td>
    </tr>
    <tr>
      <td>5</td>
      <td>5</td>
      <td>6</td>
      <td></td>
      <td>True</td>
    </tr>
  </tbody>
</table>

答案 1 :(得分:0)

您可以使用filter

$(function() {

  var $archive = $('#archive');
  var $type = $('#type');
  var $rows = $("#filter").find("tbody tr"); // cache this in a var for better performance (unless you have dynamic added rows)

  $archive.change(filterTable);
  $type.change(filterTable);

  function filterTable() {
    var archiveValue = $archive.val();
    var typeValue = $type.val();

    $rows.hide()                // hide all rows first
      .filter(function() {      // filter out the rows to show

      if (archiveValue === 'all' && typeValue === 'all') {
        return true; // show all rows if no filters selected
      } else if (archiveValue === 'all') {
        return $(this).children().eq(4).text().toLowerCase() === typeValue;  // show only matching type filters if archive filters is all
      } else {
        var text = $(this).children().eq(3).text().trim();
        isArchived = archiveValue === 'archived' ? text !== '' : text === ''; 
        if (typeValue === 'all') {
          return isArchived;             // if type filters is all, just show archive filtered contnt
        } else {
          return $(this).children().eq(4).text().toLowerCase() === typeValue && isArchived;  // filter by both archive and type
        }
      }

    }).show();
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label for="archive">Filter Archive</label>
<select id="archive" name="archive">
  <option value="all">All</option>
  <option value="archived">Archived</option>
  <option value="not-archived">Not Archived</option>
</select>

<label for="type">Filter Full Entry</label>
<select id="type" name="type">
  <option value="all" selected>All</option>
  <option value="true">True</option>
  <option value="false">False</option>
</select>

<table class="table" style="width: 30%" id="filter">
  <thead>
    <tr>
      <th>Ref</th>
      <th>Edit</th>
      <th>Name</th>
      <th>Archived</th>
      <th>Full Entry</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
      <td>True</td>
    </tr>
    <tr>
      <td>a</td>
      <td>b</td>
      <td>c</td>
      <td></td>
      <td>False</td>
    </tr>
    <tr>
      <td>5</td>
      <td>5</td>
      <td>6</td>
      <td></td>
      <td>True</td>
    </tr>
  </tbody>
</table>

相关问题