Hide/Show Columns in an HTML Table (with multiple column in the header)

Viewed 701

Can anyone help please, I am trying to hide/show my html table columns, my table has three rows in the header and need to hide/show the columns of the second row with the contained small rows, I used an example found here in Stackoverflow but still can't succeed to do the job, my code is as following:

        $(function() {
  // on init
  $(".table-hideable .hide-col").each(HideColumnIndex);

  // on click
  $('.hide-column').click(HideColumnIndex)

  function HideColumnIndex() {
    var $el = $(this);
    var $cell = $el.closest('th,td')
    var $table = $cell.closest('table')

   
    var colIndex = $cell[0].cellIndex + 1;

    // find and hide col index
    $table.find("tbody tr, thead tr")
      .children(":nth-child(" + colIndex + ")")
      .addClass('hide-col');
      
    // show restore footer
    $table.find(".footer-restore-columns").show()
  }

  // restore columns footer
  $(".restore-columns").click(function(e) {
    var $table = $(this).closest('table')
    $table.find(".footer-restore-columns").hide()
    $table.find("th, td")
      .removeClass('hide-col');

  })

  $('[data-toggle="tooltip"]').tooltip({
    trigger: 'hover'
  })

})
        body {
  padding: 15px;
}

.table-hideable td,
.table-hideable th {
  width: auto;
  transition: width .5s, margin .5s;
}

.btn-condensed.btn-condensed {
  padding: 0 5px;
  box-shadow: none;
}


/* use class to have a little animation */
.hide-col {
  width: 0px !important;
  height: 0px !important;
  display: block !important;
  overflow: hidden !important;
  margin: 0 !important;
  padding: 0 !important;
  border: none !important;
}
<!DOCTYPE html>
<html>
<head>

    <script src="/scripts/snippet-javascript-console.min.js?v=1"></script>
</head>
<body>
    <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.css">
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.7/paper/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>


<table class="table table-condensed table-hover table-bordered table-striped table-hideable">

  <thead>
      <tr>
      <th colspan="4" > 
        
        TOP </th>
        </tr>
        <tr>
      <th colspan="2" > <button class="pull-right btn btn-default btn-condensed hide-column" data-toggle="tooltip" data-placement="bottom" title="Hide Column">
          <i class="fa fa-eye-slash"></i>  
        </button>
        
        A </th>
      <th  colspan="2" > <button class="pull-right btn btn-default btn-condensed hide-column" data-toggle="tooltip" data-placement="bottom" title="Hide Column">
          <i class="fa fa-eye-slash"></i>  
        </button>
       
        B
      </th>
 
      </tr>
       <tr>
       <th>
         
         AA </th>
       <th class="hide-col"> 
        
         AB   </th>
       <th>  
        
         BB </th>
      <th > 
        
        BC </th>

       </tr>
  </thead>
  <tbody>

    <tr>
      <td>Home</td>
      <td>Index</td>
      <td>ActionResult</td>
      <td>Authorize</td>
      
    </tr>

    <tr>
      <td>Client</td>
      <td>Index</td>
      <td>ActionResult</td>
      <td>Authorize</td>
     
    </tr>

    <tr>
      <td>Client</td>
      <td>Edit</td>
      <td>ActionResult</td>
      <td>Authorize</td>
     
    </tr>

  </tbody>
  <tfoot class="footer-restore-columns">
    <tr>
      <th colspan="4"><a class="restore-columns" href="#">Some columns hidden - click to show all</a></th>
    </tr>
  </tfoot>
</table>

Many thanks

1 Answers

Try like this:

$(function() {
  // on click
  $('.hide-column').click(HideColumns)
  
  // on init
  $('.hide-column').eq(0).trigger( "click" );

  function HideColumns() {
    var $el = $(this);
    var $cell = $el.closest('th,td')
    var $table = $cell.closest('table')

    var colIndex = 0;
    var colSpan = 0;

    $cell.parent().children().each(function(index) {
      if ($(this).is($cell)) {
        colSpan = parseInt($cell.attr("colspan") || 1);
        return false;
      } else {
        colIndex += parseInt($(this).attr("colspan") || 1);
      };
    });

    // find and hide col index
    for (var i = colIndex; i < (colIndex + colSpan); i++) {
      $table.find("tbody tr, thead :nth-child(3)")
        .children(":nth-child(" + (i + 1) + ")")
        .addClass('hide-col');
    };
    
    //always show first header
    $table.find("thead :nth-child(1)").children().removeClass('hide-col');
    
    //hide clicked cell
    $cell.addClass('hide-col');

    // show restore footer
    $table.find(".footer-restore-columns").show()
  }

  // restore columns footer
  $(".restore-columns").click(function(e) {
    var $table = $(this).closest('table')
    $table.find(".footer-restore-columns").hide()
    $table.find("th, td")
      .removeClass('hide-col');

  })

  $('[data-toggle="tooltip"]').tooltip({
    trigger: 'hover'
  })

})
body {
  padding: 15px;
}

.table-hideable td,
.table-hideable th {
  width: auto;
  transition: width .5s, margin .5s;
}

.btn-condensed.btn-condensed {
  padding: 0 5px;
  box-shadow: none;
}


/* use class to have a little animation */

.hide-col {
  width: 0px !important;
  height: 0px !important;
  display: block !important;
  overflow: hidden !important;
  margin: 0 !important;
  padding: 0 !important;
  border: none !important;
}
<!DOCTYPE html>
<html>

<head>

  <script src="/scripts/snippet-javascript-console.min.js?v=1"></script>
</head>

<body>
  <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.css">
  <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.7/paper/bootstrap.min.css">
  <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css">
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>


  <table class="table table-condensed table-hover table-bordered table-striped table-hideable">

    <thead>
      <tr>
        <th colspan="4">

          TOP </th>
      </tr>
      <tr>
        <th colspan="2"> <button class="pull-right btn btn-default btn-condensed hide-column" data-toggle="tooltip" data-placement="bottom" title="Hide Column" data>
          <i class="fa fa-eye-slash"></i>  
        </button> A </th>
        <th colspan="2"> <button class="pull-right btn btn-default btn-condensed hide-column" data-toggle="tooltip" data-placement="bottom" title="Hide Column">
          <i class="fa fa-eye-slash"></i>  
        </button> B
        </th>

      </tr>
      <tr>
        <th>

          AA </th>
        <th class="hide-col">

          AB </th>
        <th>

          BB </th>
        <th>

          BC </th>

      </tr>
    </thead>
    <tbody>

      <tr>
        <td>Home</td>
        <td>Index</td>
        <td>ActionResult</td>
        <td>Authorize</td>

      </tr>

      <tr>
        <td>Client</td>
        <td>Index</td>
        <td>ActionResult</td>
        <td>Authorize</td>

      </tr>

      <tr>
        <td>Client</td>
        <td>Edit</td>
        <td>ActionResult</td>
        <td>Authorize</td>

      </tr>

    </tbody>
    <tfoot class="footer-restore-columns">
      <tr>
        <th colspan="4"><a class="restore-columns" href="#">Some columns hidden - click to show all</a></th>
      </tr>
    </tfoot>
  </table>

As th elements with colspan are being used, a different approach is needed. Instead of only considering the current column index, the above solution finds the range of indexes of td cells within tbody according to the th where the button was clicked ($cell).

To hide that span of columns, it first loops through the 2nd row of the table, adding each colspan to colIndex until it gets to $cell. The td indexes to hide on each row are then from colIndex to colIndex + the colspan of $cell (1-based in jQuery).

Related