Adomas202
Adomas202

Reputation: 99

Table filter multiple checkboxes with Javascript

I have table that when you select certain values from checkboxes some rows gets displayed and other rows are hidden. My problem is that I can only select from one row of instructions. In this case from only countries I can select what my table will look like where as I want that also City would also be an instruction. For example, if I were to select China and Vilnius it should show only ASP.Net instead of ASP.Net and Javascript. Hope everyone can understand.

$("#filter-button").on("click", function(e) {
  // Show all rows (in case any were hidden by a previous filtering)
  jQuery("#values-table > tr:hidden, #values-table > tbody > tr:hidden").show();
  // Get all filtered countries as array
  var selCountries = $("#country-filters input[type='checkbox']:checked").map(function() {
    return $(this).val();
  }).get();
  if (selCountries.length < 1) {
    return; // No countries are selected!
  }
  // Loop through all table rows
  $("#values-table > tr, #values-table > tbody > tr").each(function() {
    // Loop through and return only rows that DO NOT contain a selected country and hide them
    $(this).filter(function(idx) {
      return $(this).find("> td.countries > span.country")
        .filter(function() {
          return selCountries.indexOf($(this).text()) >= 0;
        }).length < 1;
    }).hide();
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="country-filters">
  <input type="checkbox" id="filter-united_states" value="United States" />
  <label for="filter-united_states">Unied States</label>
  <input type="checkbox" id="filter-africa" value="Africa" />
  <label for="filter-africa">Africa</label>
  <input type="checkbox" id="filter-china" value="China" />
  <label for="filter-china">China</label>
</div>
<div id="city-filters">
  <input type="checkbox" id="filter-vilnius" value="Vilnius" />
  <label for="filter-vilnius">Vilnius</label>
  <input type="checkbox" id="filter-kaunas" value="Kaunas" />
  <label for="filter-kaunas">Kaunas</label>
</div>
<button id="filter-button">Filter</button>

<table id="values-table" style="margin-top:20px;">
  <thead>
    <tr>
      <td>Guide</td>
      <td>City</td>
      <td>Languages</td>
      <td>Countries</td>
      <td>Phone Number</td>
      <td>Email</td>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td class="guide">JavaScript</td>
      <td class="city">Vilnius</td>
      <td class="languages"><span class="language">English</span>, <span class="language">Spanish</span></td>
      <td class="countries"><span class="country">United States</span>, <span class="country">China</span></td>
      <td class="phone">555-555-5555</td>
      <td class="email"></td>
    </tr>
    <tr>
      <td class="guide">PHP</td>
      <td class="city">Kaunas</td>
      <td class="languages"><span class="language">English</span></td>
      <td class="countries"><span class="country">Africa</span></td>
      <td class="phone">555-555-5555</td>
      <td class="email"></td>
    </tr>
    <tr>
      <td class="guide">ASP.net</td>
      <td class="city">Vilnius</td>
      <td class="languages"><span class="language">Mandarin</span></td>
      <td class="countries"><span class="country">China</span></td>
      <td class="phone">555-555-5555</td>
      <td class="email"></td>
    </tr>
  </tbody>
</table>

Upvotes: 1

Views: 1477

Answers (1)

gaetanoM
gaetanoM

Reputation: 42054

Your issue is inside the

// Loop through all table rows

You need to get not only the countries but also the cities selected and filter the rows against those values. If the cities and countries related to the row correspond to the selected ones you can deselect that row and hide all the remaining.

$("#filter-button").on("click", function (e) {
    // Show all rows (in case any were hidden by a previous filtering)
    $("#values-table > tr:hidden, #values-table > tbody > tr:hidden").show();
    // Get all filtered countries as array
    var selCountries = $("#country-filters :checkbox:checked").map(function () {
        return $(this).val();
    }).get();
    if (selCountries.length < 1) {
        return; // No countries are selected!
    }
    var selCties = $("#city-filters :checkbox:checked").map(function () {
        return $(this).val();
    }).get();
    // Loop through all table rows
    var x = $("#values-table > tr, #values-table > tbody > tr").filter(function (idx, ele) {
        var countries = $(ele).find('td.countries span.country');
        var nFoundCountries = selCountries.filter(function (ele, idx) {
            return countries.text().indexOf(ele) != -1;
        }).length;
        if (selCties.length == 0) {
            return (nFoundCountries == 0);
        } else {
            var cities = $(ele).find('td.city');
            var nFoundCities = selCties.filter(function (ele, idx) {
                return cities.text().indexOf(ele) != -1;
            }).length;

            return !(nFoundCities == selCties.length &&
            (nFoundCountries == countries.length && nFoundCountries == selCountries.length));
        }
    }).hide();
});

//
// Original Filter: the old one
//
$("#Orig-filter-button").on("click", function(e) {
    // Show all rows (in case any were hidden by a previous filtering)
    jQuery("#values-table > tr:hidden, #values-table > tbody > tr:hidden").show();
    // Get all filtered countries as array
    var selCountries = $("#country-filters input[type='checkbox']:checked").map(function() {
        return $(this).val();
    }).get();
    if (selCountries.length < 1) {
        return; // No countries are selected!
    }
    // Loop through all table rows
    $("#values-table > tr, #values-table > tbody > tr").each(function() {
        // Loop through and return only rows that DO NOT contain a selected country and hide them
        $(this).filter(function(idx) {
            return $(this).find("> td.countries > span.country")
                            .filter(function() {
                                return selCountries.indexOf($(this).text()) >= 0;
                            }).length < 1;
        }).hide();
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<div id="country-filters">
    <input type="checkbox" id="filter-united_states" value="United States"/>
    <label for="filter-united_states">Unied States</label>
    <input type="checkbox" id="filter-africa" value="Africa"/>
    <label for="filter-africa">Africa</label>
    <input type="checkbox" id="filter-china" value="China"/>
    <label for="filter-china">China</label>
</div>
<div id="city-filters">
    <input type="checkbox" id="filter-vilnius" value="Vilnius"/>
    <label for="filter-vilnius">Vilnius</label>
    <input type="checkbox" id="filter-kaunas" value="Kaunas"/>
    <label for="filter-kaunas">Kaunas</label>
</div>
<button id="filter-button">Filter</button>
<button id="Orig-filter-button">Original Filter</button>

<table id="values-table" style="margin-top:20px;">
    <thead>
    <tr>
        <td>Guide</td>
        <td>City</td>
        <td>Languages</td>
        <td>Countries</td>
        <td>Phone Number</td>
        <td>Email</td>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td class="guide">JavaScript</td>
        <td class="city">Vilnius</td>
        <td class="languages"><span class="language">English</span>, <span class="language">Spanish</span></td>
        <td class="countries"><span class="country">United States</span>, <span class="country">China</span></td>
        <td class="phone">555-555-5555</td>
        <td class="email"></td>
    </tr>
    <tr>
        <td class="guide">PHP</td>
        <td class="city">Kaunas</td>
        <td class="languages"><span class="language">English</span></td>
        <td class="countries"><span class="country">Africa</span></td>
        <td class="phone">555-555-5555</td>
        <td class="email"></td>
    </tr>
    <tr>
        <td class="guide">ASP.net</td>
        <td class="city">Vilnius</td>
        <td class="languages"><span class="language">Mandarin</span></td>
        <td class="countries"><span class="country">China</span></td>
        <td class="phone">555-555-5555</td>
        <td class="email"></td>
    </tr>
    </tbody>
</table>

Upvotes: 1

Related Questions