Search code examples
javascriptjquerydatatablesbootstrap-selectpicker

how to get column name of a table based on clicked element using Jquery / DataTables


I have a Jquery DataTables and on footer I added a bootstrap-select to filter my data.

Inside the dropdown select, I added a button 'Clear filter' When there is/are option(s) selected.

When I click on that button, I need to get the header name.

So in my example if I click on 'Clear filter' button in the column 'Position' I should alert 'Position'. But it shows always the last column name.

enter image description here

Any suggestions please what am I missing in my code ? I added a detailed explanation of the steps I did. Thank you very much.

$(document).ready(function() {

  var table = $('#example').DataTable({
    searching: false,
    info: false,
    paging: false,

    initComplete: function() {        
      this.api().columns().every(function() {
//add select to each column footer
        var column = this;
        var select = $('<select class="form-control show-tick" data-container="body" data-header="Select option(s)" data-actions-box="true" data-live-search="true" title="All" data-selected-text-format="count > 0" multiple></select>')
          .appendTo($(column.footer()).empty());
// populate the select options with unique values of current column          
        column.data().unique().sort().each(function(d, j) {
          select.append('<option value="' + d + '">' + d + '</option>');
        });

      });
//apply bootstrap selectpicker
      $("select").selectpicker();
//add 'clear filter' button below the search box in the dropdown select      
      var buttonPosition = $('.bs-searchbox');
         $('<div class="text-center"><button type="button" class="btn btn-sm btn-light clearButton">Clear filter</button></div>').appendTo(buttonPosition); 
//        
$(".clearButton").on("click", function(){
//check the closest <th> in the footer to the clicked button 
var tableFoot =$(this).closest('tfoot').find('th');
//console.log(tableFoot);
//we know the position of the button in which <th> on the footer and from it we will check the column name on header
alert('Column:'+$('table thead tr th').eq(tableFoot.index()).html().trim());
});
    }
  });
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.css" rel="stylesheet">
<link href="https://cdn.datatables.net/1.10.21/css/dataTables.bootstrap4.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.17/css/bootstrap-select.min.css">
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.1/umd/popper.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/js/bootstrap.min.js"></script>
<script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.10.21/js/dataTables.bootstrap4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.17/js/bootstrap-select.min.js"></script>

<table id="example" class="table table-bordered table-hover nowrap" style="width:100%">
        <thead>
            <tr>
                <th>Name</th>
                <th>Position</th>
                <th>Office</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>Ashton Cox</td>
                <td>Junior Technical Author</td>
                <td>San Francisco</td>
            </tr>
            <tr>
                <td>Cedric Kelly</td>
                <td>Senior Javascript Developer</td>
                <td>Edinburgh</td>
            </tr>
            <tr>
                <td>Airi Satou</td>
                <td>Accountant</td>
                <td>Tokyo</td>
            </tr>
        </tbody>
        <tfoot>
            <tr>
                <th>Name</th>
                <th>Position</th>
                <th>Office</th>
             </tr>
        </tfoot>
    </table>


Solution

  • The problem is caused by the Bootstrap select not being part of the table it is shown in but rather it is attached to the HTML body and absolutely positioned over the table cell.

    There is a configuration option container: string | false available for the .selectpicker() call so what you could do is to set an ID on the column and set the option to render in this element.

        let cf = $(column.footer()).empty();
        var select = $('<select class="form-control show-tick" data-container="body" data-header="Select option(s)" data-actions-box="true" data-live-search="true" title="All" data-selected-text-format="count > 0" multiple></select>')
          .appendTo(cf).selectpicker({container: '#ci'+ci});
          cf.attr('id',  'ci' + ci).data('col', ci);
    

    And in your clear routine:

      $(".clearButton").on("click", function() {
        var col = $(this).closest('th').data('col');
        alert('Column:' + $('table thead tr th').eq(col).html().trim());
      });
    

    Fiddle with this solution.


    Another option is to create an object with a reference to the current column index in the loop and on showing the select setting the column index via show.bs.select event:

        let obj= { ci: ci};
        var select = $('<select id="ci' + ci + '" class="form-control show-tick" data-container="body" data-header="Select option(s)" data-actions-box="true" data-live-search="true" title="All" data-selected-text-format="count > 0" multiple></select>')
          .appendTo($(column.footer()).empty()).selectpicker().on('show.bs.select',  function() {
            window.currentSelect = obj.ci;
          });
    

    And in the clear routine:

      $(".clearButton").on("click", function() {
        alert('Column:' + $('table thead tr th').eq(window.currentSelect).html().trim());
      });
    

    Fiddle with alternate solution.