Datatable Filter Individual Column Inputs AND sele

2019-05-30 23:17发布

问题:

My question is simliar to DataTables : filtering different types of filtering on individual columns, however that question was not answered so I'm hoping someone could help us both out.

I'm using jQuery Datatables 1.10.8 and I currently have individual column filtering for the 4 of my 6 columns (last column does not require filtering).

What I'm trying to do is this:
- Columns 1-4: "text input" filter
- Column 5: "select" filter

I'm trying to use multiple filter types in the table, but I cannot find anything to help me out.

This is my current code:

HTML:

<table class='table datatable-column-search-inputs table-hover table-striped table-bordered'>
  <thead>                                           
    <tr>
      <th>ID</th>
      <th>OBJECT ID</th>
      <th>PREFERRED</th>
      <th>DESCRIPTION</th>
      <th>CATEGORY</th>
      <th class='text-center'>EDIT</th>
    </tr>
  </thead>
  <tbody>
    <tr>
     <td>1</td>
     <td>nai_comp_1</td>
     <td>1A-35</td>
     <td>Compressor 1 - Suction</td>
     <td>Analog Input</td>
     <td><button class='btn btn-sm btn-info'><i class='fa fa-edit'></i></button></td>
    </tr>
    <tr>
     <td>2</td>
     <td>nao_comp_1_en</td>
     <td>1B-35</td>
     <td>Compressor 1 - Enable</td>
     <td>Analog Output</td>
     <td><button class='btn btn-sm btn-info'><i class='fa fa-edit'></i></button></td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td class='tfoot_search'>ID</td>
      <td class='tfoot_search'>OBJECT ID</td>
      <td class='tfoot_search'>GROUP</td>
      <td class='tfoot_search'>DESCRIPTION</td>
      <td class='tfoot_select'>CATEGORY</td>
      <td></td>
    </tr>
  </tfoot>
</table>

jQuery:

  //Setup jQuery DataTables
  $(function() {
    $.extend( $.fn.dataTable.defaults, {
      autoWidth: false,
      columnDefs: [{ 
        orderable: false,
        width: '100px',
        targets: [ 5 ]
      }],
      dom: '<"datatable-header"fl><"datatable-scroll"t><"datatable-footer"ip>',
      language: {
        search: '<span>Filter:</span> _INPUT_',
        lengthMenu: '<span>Show:</span> _MENU_',
        paginate: { 'first': 'First', 'last': 'Last', 'next': '&rarr;', 'previous': '&larr;' }
      },
      drawCallback: function () {
        $(this).find('tbody tr').slice(-3).find('.dropdown, .btn-group').addClass('dropup');
      },
      preDrawCallback: function() {
        $(this).find('tbody tr').slice(-3).find('.dropdown, .btn-group').removeClass('dropup');
      }
    });

  //Uses jQuery Datatable API to include <input type='text' searchable filters
  $('.tfoot_search').each(function() {
    var title = $('.datatable-column-search-inputs thead th').eq($(this).index()).text();
    $(this).html('<input type="text" class="form-control input-sm" placeholder="Search '+title+'" />');
  });

  var table = $('.datatable-column-search-inputs').DataTable();

  table.columns().every( function () {
    var that = this;
    $('input', this.footer()).on('keyup change', function () {
        that.search(this.value).draw();
    });                             
  });


////////////// ***** EXPERIMENTAL CODE **** REF ONLY ***** ////////////////
// --- This is to make it to where all "td" elements in a footer have "select" elements for filtering --- //

   $('.datatable-column-search-selects').DataTable({
     initComplete: function () {
       this.api().columns().every( function() {
         var column = this;
         var select = $('<select class="filter-select" data-placeholder="Filter"><option value=""></option></select>')
                      .appendTo($(column.footer()).not(':last-child').empty())
                      .on('change', function() {
                        var val = $.fn.dataTable.util.escapeRegex(
                                    $(this).val()
                                  );
                             column
                                .search( val ? '^'+val+'$' : '', true, false )
                                .draw();
                      });

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

回答1:

****** SOLVED ******

Finally solved it. Here's my entire code now (compare with the above edit)

jQuery:

   //NO CHANGES HERE
   $.extend( $.fn.dataTable.defaults, {
         autoWidth: false,
         columnDefs: [{ 
         orderable: false,
         width: '100px',
         targets: [ 5 ]
       }],
       dom: '<"datatable-header"fl><"datatable-scroll"t><"datatable-footer"ip>',
       language: {
         search: '<span>Filter:</span> _INPUT_',
         lengthMenu: '<span>Show:</span> _MENU_',
         paginate: { 'first': 'First', 'last': 'Last', 'next': '&rarr;', 'previous': '&larr;' }
       },
       drawCallback: function () {
         $(this).find('tbody tr').slice(-3).find('.dropdown, .btn-group').addClass('dropup');
       },
       preDrawCallback: function() {
         $(this).find('tbody tr').slice(-3).find('.dropdown, .btn-group').removeClass('dropup');
       }
    });


   //NO CHANGES HERE
   $('.tfoot_search').each(function() {
     var title = $('.datatable-column-search-inputs thead th').eq($(this).index()).text();
     $(this).html('<input type="text" class="form-control input-sm" placeholder="Search '+title+'" />');
   });

   //**** CHANGES HERE ****
   $('.datatable-column-search-inputs').DataTable({
        initComplete: function () {
          this.api().columns().every( function () {
            var column = this;
            if ($(column.footer()).hasClass('tfoot_search')) {

              var that = this;
              $('input', this.footer()).on('keyup change', function () {
                 that.search(this.value).draw();
              });   

            } else if ($(column.footer()).hasClass('tfoot_select')) {

              var column = this;
              var select = $('<select class="filter-select" data-placeholder="Filter"><option value=""></option></select>')
                .appendTo($('td.tfoot_select').empty())
                .on('change', function() {
              var val = $.fn.dataTable.util.escapeRegex(
                           $(this).val()
                        );

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

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


回答2:

I noticed the above code contains a bug when trying to do multiple select drop downs.

Use code below to use multiple select drop downs:

$('.datatable-column-search-inputs').DataTable({
    initComplete: function() {
        this.api().columns().every(function() {
            var column = this;
            if ($(column.footer()).hasClass('tfoot_search')) {

                var that = this;
                $('input', this.footer()).on('keyup change', function() {
                    that.search(this.value).draw();
                });

            } else if ($(column.footer()).hasClass('tfoot_select')) {
                //Updated this section
                var select = $('<select><option value=""></option></select>')
                    .appendTo($(column.footer()).empty())
                    .on('change', function() {
                        var val = $.fn.dataTable.util.escapeRegex(
                            $(this).val()
                        );

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

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