过滤数据表初始化的列下拉列表

时间:2018-03-20 19:56:35

标签: jquery authentication datatables

我有一个行的数据表,每个行都有一个复选框,需要根据客户进行身份验证。到目前为止,我已经在数据表初始化之后立即运行身份验证,并且一切都运行良好,即非有效行很好地灰显,并禁用它们的复选框。现在我想在数据表中添加单个列过滤器。我有这个工作,但问题是下拉列表显示来自所有行的元素,而不是仅来自经过身份验证的行。我猜测我需要在初始化期间而不是之后验证数据表,因为这将允许我使用过滤器或某种if语句附加每个选项值。但在初始化之前,我无法想出一种访问表格来验证它的方法。我认为由于我的经验不足,我现在处于完全混乱状态。我真正想要实现的是每列中经过身份验证(即已过滤)的下拉列表。任何指导非常感谢。我已经简化了小提琴中的代码:https://jsfiddle.net/Lmgwyw9z/

<script src='https://code.jquery.com/jquery-1.11.0.js'></script>
<script src='https://cdn.datatables.net/1.10.12/css/jquery.dataTables.min.css'></script>
<script src='https://cdn.datatables.net/1.10.12/js/jquery.dataTables.min.js'></script>


<div id="TradeCodesPopupProductsCodesStore_tr">
  <form id="frm-example" action="/nosuchpage" method="POST">

    <table id="example" class="display select" cellspacing="0" width="100%">
      <thead>
    <tr>
      <th>Clicks</th>
      <th>Trading Code</th>
      <th>Product Group</th>
      <th>Product description</th>
    </tr>
      </thead>

      <tbody>
        <tr id="row250200">
          <td><input id="HS250200" type="checkbox" value="HS 250200" /></td>
          <td> 250200 </td>
          <td> Raw Materials </td>
          <td> Iron Ore - unroasted </td>
        </tr>
        <tr id="row260111">
          <td><input id="HS260111" type="checkbox" value="HS 260111" /></td>
          <td> 260111 </td>
          <td> Raw Materials - Iron ore </td>
          <td> Iron Ore - fines, concentrate, lump </td>
        </tr>
        <tr id="row730490" class="TypeCarbon_Alloy">
          <td><input id="HS730490" type="checkbox" value="HS 730490" /></td>
          <td> 730490 </td>
          <td> Pipe &amp; tube - Seamless </td>
          <td> Seamless tube - other </td>
        </tr>
        <tr id="row730512" class="TypeCarbon_Alloy">
          <td><input id="HS730512" type="checkbox" value="HS 730512" /></td>
          <td> 730512 </td>
          <td> Pipe &amp; tube - Welded </td>
          <td> Welded tube - line pipe, LW, >406.4mm </td>
        </tr>
        <tr id="row730230" class="TypeCarbon_Alloy_Stainless">
          <td><input id="HS730230" type="checkbox" value="HS 730230" /></td>
          <td> 730230 </td>
          <td> Longs </td>
          <td> Railway Materials </td>
        </tr>
        <tr id="row721921" class="TypeStainless">
          <td><input id="HS721921" type="checkbox" value="HS 721921" /></td>
          <td> 721921 </td>
          <td> Flats - HR plate </td>
          <td> HR plate - discrete or CTL, >10mm </td>
        </tr>
      </tbody>
    </table>

  </form>
</div>

$(function() {

  $('#example').DataTable({

    orderCellsTop: true,
    scrollY: '50vh',
    scrollCollapse: true,

    initComplete: function() {
      this.api().columns([1, 2, 3]).every(function() {
        var column = this;
        var select = $('<select><option value="">Show all</option></select>')

          .appendTo($(column.header()))
          .on('change', function() {
            var val = $.fn.dataTable.util.escapeRegex(
              $(this).val()
            );

            column
              .search(val ? '^' + val + '$' : '', true, false)
              .draw();
          });

        // Create dropdown lists
        column.data().unique().sort().each(function(d, j) {
          select.append('<option value="' + d + '">' + d + '</option>')
        });

      });
    }
  });

  // -------------------

  // Default:  Disable all rows
  $('#example td input').prop("disabled", true).closest('tr').css({
'color': '#dcdcdc'
  }).find(':checkbox').hide();

  // Authenticate relevant rows only
  $("#HS260111, #HS730512, #HS730230").prop("disabled", false).closest('tr').css({
'color': 'black'
  }).find(':checkbox').show();

});

1 个答案:

答案 0 :(得分:1)

首先要做的几件事:

  1. 必须将// Default: Disable all rows// Authenticate relevant rows only移到函数的开头,因为我需要已经变灰的行才能使我的代码正常工作。我认为它没有破坏任何东西。

  2. 在灰色的行中添加了课程grayed-out

  3. 现在是真正的交易:

    要过滤附加了哪些option标记,哪些标记未被添加,我在if(rowsLetMe(i, d))之前添加了select.append('<option value="' + d + '">' + d + '</option>')。该函数将检查每个灰显的tr及其内部,所有td对应于正在检查的select列。

    奖金功能:)

    每次我点击select标签时,事件都会冒泡到其父级,并会触发行排序功能,我认为这不是预期的行为。因此:

    .click(function(e){
        e.stopPropagation();
    });
    

    very useful

    几乎就在那里,最后一件事:这段代码需要重构以提高效率,它只是一个如何实现它的工作示例

    试试并告诉我:https://jsfiddle.net/Lmgwyw9z/55/

    编辑关于你的怀疑

    e.stopPropagation()

    您应该查看我提供的链接以获得更全面的解释,但实质上是:

    将此行添加到处理程序(对于此情况下的单击事件)将停止来自传播 DOM树的事件。在您的示例中,我将其包含在内,因为我注意到了我认为不受欢迎的行为:每次我都会点击<th>标记,无论我是否专门点击它或其包含的<select>标记,执行表的重新排序,这意味着:

    • 点击一下即可展开<select> - &gt;重新排序执行
    • 另一个选择选项的点击 - &gt;重新排序执行

    事件传播从最里面的元素到最外面的元素,图像胜过千言万语:

    event bubbling

    并且一些代码值一百万:

    function highlight(elem) {
      elem.style.backgroundColor = 'yellow'
      alert(elem.className)
      elem.style.backgroundColor = ''
    }
    div{
    position: absolute;
    width: 300px;
    height: 300px;
    background: green;
    }
    
    div div{
    width: 200px;
    height: 200px;
    background: blue;
    left: 50px;
    top: 50px
    }
    
    div div div{
    width: 100px;
    height: 100px;
    background: red;
    left: 50px;
    top: 50px
    }
    <div class="d1" onclick="highlight(this)">1
      <div class="d2" onclick="highlight(this)">2
        <div class="d3" onclick="highlight(this)">3
        </div>
      </div>
    </div>

    同样,还有更多内容,所以对这个主题进行更深入的研究,它真的可以成为救星。

    重构

      

    代码重构是重构现有计算机代码的过程 - 改变因子 - 而不改变其外部行为。重构改进了软件的非功能属性。 More...

    我只是意味着你不应该按原样保留rowsLetMe(i, d)函数,它可以工作但效率不高(如果你关心/需要这样的东西),可能会缓存一些选择器,例如表行,所以$('table tbody tr.grayed-out')不会在每次调用方法时查询DOM,就像那样。简而言之:改变(改进)它是如何做到的,而不是它做什么。