0

I need some assistance with changing the filtering from selection to multiple checkbox selection. Below the code currently filters with one selection only. I would like to be able to select multiple ages and terms in a checkbox form. Thank you for any guidance!

<!DOCTYPE html>
<html lang="en">
<link rel="stylesheet" href="/stylesheets/style.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<head>
    <meta charset="utf-8">
    <title>Filter</title>

</head>

</body>
</html>



<table id="myTable" class="table table-striped">

  <thead>
    <tr>
      <th>First Name</th>
      <th>Last Name</th>
      <th class="dropdown-header">Age</th>
      <th>Email</th>
      <th class="dropdown-header">Gender</th>
      <th class="dropdown-header">Term</th>
      <th class="dropdown-header">Enrolled</th>
    </tr>
  </thead>

  <tbody>


    <tr>
      <td>John</td>
      <td>Smith</td>
      <td data-field-name="age">15</td>
      <td>123</td>
      <td data-field-name="gender">Male</td>
      <td data-field-name="term">Summer2017</td>
      <td data-field-name="enrolled">Fall2018</td>
    </tr>
    <tr>
      <td>Jane</td>
      <td>Doe</td>
      <td data-field-name="age">16</td>
      <td>456</td>
      <td data-field-name="gender">Female</td>
      <td data-field-name="term">Fall2018</td>
      <td data-field-name="enrolled">Fall2019</td>
    </tr>
    <tr>
      <td>Bobby</td>
      <td>Adams</td>
      <td data-field-name="age">15</td>
      <td>789</td>
      <td data-field-name="gender">Male</td>
      <td data-field-name="term">Spring2019</td>
      <td data-field-name="enrolled">Fall2018</td>
    </tr>
    <tr>
      <td>Sarah</td>
      <td>Lee</td>
      <td data-field-name="age">15</td>
      <td>456</td>
      <td data-field-name="gender">Female</td>
      <td data-field-name="term">Fall2018</td>
      <td data-field-name="enrolled">Fall2018</td>
    </tr>
  </tbody>
</table>

<script>
    (function($) {
  $.fn.tableFilterHeaders = function(filterFn) {
    this.each((index, header) => {
      let $header = $(header),
          $table = $header.closest('table'),
          text = $header.text(),
          colIndex = $header.closest('th').index(),
          fieldName = $header.attr('data-field-name') || text.toLowerCase(),
      $select = $('<select>')
        .data('fieldName', fieldName)
        .append($('<option>').text(text).val('').prop('disabled', true))
        .append($('<option>').text('All').val('all'))
        .append($table.find('tbody tr')
          .toArray()
          .map(tr => {
            return $(tr).find(`td:eq(${colIndex})`).text();
          })
          .filter(text => text.trim().length > 0)
          .sort()
          .filter((v, i, a) => a.indexOf(v) === i)
          .map(text => {
            return $('<option>').text(text).val(text);
          }));
      $header.empty().append($select.val('').on('change', filterFn));
    });
  };
  $.fn.initRowClasses = function(oddCls, evenCls) {
    this.find('tbody tr').each(function(i) {
      $(this).toggleClass(oddCls, i % 2 == 0).toggleClass(evenCls, i % 2 == 1);
    });
  };
  $.fn.updateRowClasses = function(oddCls, evenCls) {
    this.find('tbody tr:visible:even').addClass(oddCls).removeClass(evenCls);
    this.find('tbody tr:visible:odd').addClass(evenCls).removeClass(oddCls);
  };
})(jQuery);

$('#myTable').initRowClasses('odd', 'even');
$('.dropdown-header').tableFilterHeaders(filterText);

function filterText(e) {
  let $filter = $(e.target),
      $table = $filter.closest('table'),
      $filters = $table.find('.dropdown-header select'),
  filterObj = $filters.toArray().reduce((obj, filter) => {
    let $filter = $(filter);
    return Object.assign(obj, { [$filter.data('fieldName')] : $filter.val() });
  }, {});
  if ($filter.val() === 'all') {
    $filter.val('')
  }
  $table.find('tbody tr').each(function() {
    $(this).toggle($(this).find('td').toArray().every(td => {
      let $td = $(td), fieldName = $td.attr('data-field-name');
      if (fieldName != null) {
        return filterObj[fieldName] === null ||
          filterObj[fieldName] === '' ||
          filterObj[fieldName] === 'all' ||
          filterObj[fieldName] === $td.text();
      }
      return true;
    }));
  });

  $table.updateRowClasses('odd', 'even');
}
</script>

This is what is currently generating with the code above.

enter image description here

blex
  • 24,941
  • 5
  • 39
  • 72
williswin
  • 133
  • 13
  • 1
    What have you tried and what specifically goes wrong? – showdev Feb 26 '20 at 20:50
  • I don't see any check boxes there. – EternalHour Feb 26 '20 at 20:57
  • I think what he's looking for is, "how do I implement multiselect for a column." Suggestion based on current layout: In the "Age" dropdown, add option "multi..." If user selects it, then unhide checkboxes that are hidden (these checkboxes would be to the left of the value in each cell in the column, ideally the checkbox in one div and the value in another so selection is easy). User checks a given box, select the cell it's in, get the value in that cell, and add to filtering as you do now. If the user selects anything other than "multi", remove those values and set the new individual one. – Tim Consolazio Feb 26 '20 at 20:58
  • @TimConsolazio Thanks for your response, would you be able to provide some test code? The example below partially works but it is not part of a selection list. I attempted to edit my example above but it breaks the filtering. https://jsfiddle.net/jakecigar/51wwnyeg/12/ – williswin Feb 27 '20 at 19:04

1 Answers1

0

Are you looking for a multiple choice select?

have you tried this?

$select = $('<select>')
        .data('fieldName', fieldName)
        .attr('multiple')

https://www.w3schools.com/tags/att_select_multiple.asp

PS: If you need to implement this with checkboxes, see this: How to use Checkbox inside Select Option

danielarend
  • 1,379
  • 13
  • 26
  • I attempted to add that for multiple choice select, it removed the drop down menu completely. Thanks for the link, I will take a look at it. – williswin Feb 27 '20 at 17:04