我需要过滤引导 jQuery 数据表

Posted

技术标签:

【中文标题】我需要过滤引导 jQuery 数据表【英文标题】:I need to filter bootstrap jQuery datatable 【发布时间】:2018-01-16 19:31:18 【问题描述】:

我需要过滤数据表。我已经编写了代码及其工作,但是当我通过单击按钮更改状态时,它就无法工作。

即:如果有启用按钮,我点击它,然后它将更改为禁用按钮。然后,如果我过滤表它不起作用。

同样的方法,如果有禁用按钮,我点击它,它会变成启用按钮,但对过滤数据表没有影响。

虽然我正在更改过滤器值,但过滤器保持不变。

<html>
<head>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.15/css/dataTables.bootstrap.min.css" />

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <script src="https://cdn.datatables.net/1.10.15/js/jquery.dataTables.min.js"></script>
    <script src="https://cdn.datatables.net/1.10.15/js/dataTables.bootstrap.min.js"></script>
</head>

<body>

    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <!-- HTML -->
            <table id="data-table" class="table table-hover table-bordered table-stripped">
                <thead>
                    <tr>
                        <th class="text-center">#</th>
                        <th>Category Name</th>
                        <th class="text-center filterable customFilterColumn">Status</th>
                    </tr>
                <thead>
                <tbody>
                    <tr>
                        <td class="text-center"><input type="checkbox" class="minimal" /></td>
                        <td>Shoes</td>
                        <td class="text-center" data-filter="Disabled"><button class="btn btn-default btn-xs btn-status status-disabled">Disabled</button></td>
                    </tr>
                    <tr>
                        <td class="text-center"><input type="checkbox" class="minimal" /></td>
                        <td>Shoes</td>
                        <td class="text-center" data-filter="Disabled"><button class="btn btn-default btn-xs btn-status status-disabled">Disabled</button></td>
                    </tr>
                    <tr>
                        <td class="text-center"><input type="checkbox" class="minimal" /></td>
                        <td>Shoes</td>
                        <td class="text-center" data-filter="Enabled"><button class="btn btn-default btn-xs btn-status status-enabled">Enabled</button></td>
                    </tr>
                    <tr>
                        <td class="text-center"><input type="checkbox" class="minimal" /></td>
                        <td>Shoes</td>
                        <td class="text-center" data-filter="Disabled"><button class="btn btn-default btn-xs btn-status status-disabled">Disabled</button></td>
                    </tr>
                    <tr>
                        <td class="text-center"><input type="checkbox" class="minimal" /></td>
                        <td>Shoes</td>
                        <td class="text-center" data-filter="Enabled"><button class="btn btn-default btn-xs btn-status status-enabled">Enabled</button></td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>

</body>

<script type="text/javascript">
    $(document).ready(function()
            
        var table = $('#data-table').DataTable(
            "paging": true,
            "lengthChange": true,
            "searching": true,
            "ordering": true,
            "info": true,
            "autoWidth": true,
            "aaSorting": [
                ['1', 'asc']
            ],
            /* "order": [], */
            "columnDefs": [
                /* "targets": [0,-1], */
                "targets": [0,-1],
                "orderable": false
            ]
        );
        
        function filter(source,customFilterColumn)

            var count = 0;
            var tableid = source.split(' ')[0];
            
            $(source).each( function ( k ) 

                if ($(this).text() !== '') 
                
                    if(++count==1)
                        $(tableid).parents("div.row:first").before('<div class="row"><div id="filtercontent"></div></div>');
                    
                    
                    var i = $(this).index();
                
                    var select = $('<select id="filer_'+i+'" class="form-control"><option value="">All</option></select>')
                        .insertBefore('#filtercontent')
                        
                        .on( 'change', function () 
                            var val = $(this).val();
                            
                            table.column( i )
                                .search( val ? '^'+$(this).val()+'$' : val, true, false )
                                .draw();
                         );
                        
                    // Get the Status values a specific way since the status is a anchor/image
                    if ($(this).hasClass(customFilterColumn)) 
                        var dataFilterColumn = [];
                        
                        /* ### IS THERE A BETTER/SIMPLER WAY TO GET A UNIQUE ARRAY OF <TD> data-filter ATTRIBUTES? ### */
                        table.column( i ).nodes().to$().each( function(d, j)
                            var thisStatus = $(j).attr("data-filter");
                            if($.inArray(thisStatus, dataFilterColumn) === -1) dataFilterColumn.push(thisStatus);
                         );
                        
                        dataFilterColumn.sort();
                                        
                        $.each( dataFilterColumn, function(i, item)
                            select.append( '<option value="'+item+'">'+item+'</option>' );
                        );

                    
                    // All other non-Status columns (like the example)
                    else 
                        table.column( i ).data().unique().sort().each( function ( d, j )   
                            select.append( '<option value="'+d+'">'+d+'</option>' );
                        ); 
                    
                    $('#filer_'+i).wrapAll('<div class="col-sm-2 form-group"></div>');
                    $('<label>'+$(this).text()+'</label>').insertBefore('#filer_'+i);
                    
                
            );
            $(tableid+'_wrapper').removeClass('form-inline');
        
        
        filter('#data-table thead th.filterable','customFilterColumn');
        
        $('.btn-status').click(function()
            var id = $(this).val();
            var status = parseInt($(this).attr('status'));
            
            $(this).toggleClass('status-enabled');
            $(this).toggleClass('status-disabled');
            if(status==0)
                $(this).html('Enabled');
                $(this).attr('status','1');
                $(this).parent().attr('data-filter','Enabled');
            
            else
                $(this).html('Disabled');
                $(this).attr('status','0');
                $(this).parent().attr('data-filter','Disabled');
            
        );
        
    );
</script>

【问题讨论】:

检查我的答案。它工作正常。 【参考方案1】:

只需在您的.btn-status 点击事件中使用table.rows().invalidate().draw();。问题是您只更新 html 而不是数据表数据。有关更多详细信息,请参阅此链接Datatable row invalidate

$(document).ready(function() 

  var table = $('#data-table').DataTable(
    "paging": true,
    "lengthChange": true,
    "searching": true,
    "ordering": true,
    "info": true,
    "autoWidth": true,
    "aaSorting": [
      ['1', 'asc']
    ],
    /* "order": [], */
    "columnDefs": [
      /* "targets": [0,-1], */
      "targets": [0, -1],
      "orderable": false
    ]
  );

  function filter(source, customFilterColumn) 

    var count = 0;
    var tableid = source.split(' ')[0];

    $(source).each(function(k) 

      if ($(this).text() !== '') 

        if (++count == 1) 
          $(tableid).parents("div.row:first").before('<div class="row"><div id="filtercontent"></div></div>');
        

        var i = $(this).index();

        var select = $('<select id="filer_' + i + '" class="form-control"><option value="">All</option></select>')
          .insertBefore('#filtercontent')

          .on('change', function() 
            var val = $(this).val();

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

        // Get the Status values a specific way since the status is a anchor/image
        if ($(this).hasClass(customFilterColumn)) 
          var dataFilterColumn = [];

          /* ### IS THERE A BETTER/SIMPLER WAY TO GET A UNIQUE ARRAY OF <TD> data-filter ATTRIBUTES? ### */
          table.column(i).nodes().to$().each(function(d, j) 

            var thisStatus = $(j).attr("data-filter");
            if ($.inArray(thisStatus, dataFilterColumn) === -1) dataFilterColumn.push(thisStatus);
          );

          dataFilterColumn.sort();

          $.each(dataFilterColumn, function(i, item) 
            select.append('<option value="' + item + '">' + item + '</option>');
          );

        
        // All other non-Status columns (like the example)
        else 
          table.column(i).data().unique().sort().each(function(d, j) 
            select.append('<option value="' + d + '">' + d + '</option>');
          );
        
        $('#filer_' + i).wrapAll('<div class="col-sm-2 form-group"></div>');
        $('<label>' + $(this).text() + '</label>').insertBefore('#filer_' + i);

      
    );
    $(tableid + '_wrapper').removeClass('form-inline');
  

  filter('#data-table thead th.filterable', 'customFilterColumn');

  $('.btn-status').click(function() 
    var id = $(this).val();
    var status = parseInt($(this).attr('status'));
    $(this).toggleClass('status-enabled');
    $(this).toggleClass('status-disabled');
    if (status == 0) 
      $(this).html('Enabled');
      $(this).attr('status', '1');
      $(this).parent().attr('data-filter', 'Enabled');
     else 
      $(this).html('Disabled');
      $(this).attr('status', '0');
      $(this).parent().attr('data-filter', 'Disabled');
    

    table.rows().invalidate().draw();
  );

);
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.15/css/dataTables.bootstrap.min.css" />

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdn.datatables.net/1.10.15/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.10.15/js/dataTables.bootstrap.min.js"></script>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <!-- HTML -->
    <table id="data-table" class="table table-hover table-bordered table-stripped">
      <thead>
        <tr>
          <th class="text-center">#</th>
          <th>Category Name</th>
          <th class="text-center filterable customFilterColumn">Status</th>
        </tr>
        <thead>
          <tbody>
            <tr>
              <td class="text-center"><input type="checkbox" class="minimal" /></td>
              <td>Shoes</td>
              <td class="text-center" data-filter="Disabled"><button class="btn btn-default btn-xs btn-status status-disabled" status="0">Disabled</button></td>
            </tr>
            <tr>
              <td class="text-center"><input type="checkbox" class="minimal" /></td>
              <td>Shoes</td>
              <td class="text-center" data-filter="Disabled"><button class="btn btn-default btn-xs btn-status status-disabled" status="0">Disabled</button></td>
            </tr>
            <tr>
              <td class="text-center"><input type="checkbox" class="minimal" /></td>
              <td>Shoes</td>
              <td class="text-center" data-filter="Enabled"><button class="btn btn-default btn-xs btn-status status-enabled" status="1">Enabled</button></td>
            </tr>
            <tr>
              <td class="text-center"><input type="checkbox" class="minimal" /></td>
              <td>Shoes</td>
              <td class="text-center" data-filter="Disabled"><button class="btn btn-default btn-xs btn-status status-disabled" status="0">Disabled</button></td>
            </tr>
            <tr>
              <td class="text-center"><input type="checkbox" class="minimal" /></td>
              <td>Shoes</td>
              <td class="text-center" data-filter="Enabled"><button class="btn btn-default btn-xs btn-status status-enabled" status="1">Enabled</button></td>
            </tr>
          </tbody>
    </table>
  </div>
</div>

【讨论】:

只是一点补充:您的状态切换有点不对劲。为什么不使用if (status == 0) 而不是if ($(this).hasClass('status-enabled')).. 因为您的状态属性一开始是空的。

以上是关于我需要过滤引导 jQuery 数据表的主要内容,如果未能解决你的问题,请参考以下文章

引导数据表自定义下拉过滤器

jQuery数据表过滤具有特定类的行

使用 JQUERY 过滤 JSON 数据

Jquery 数据表日期范围过滤器

Laravel-过滤器不起作用的引导数据表

如何从 Datatables jQuery 插件中提取过滤后的数据?