pobliska
pobliska

Reputation: 247

Filter html table by 2 select lists

I would like to filter (hide all except choosen) mulitple entries in table rows by 2 select lists. The 1st one contains countries and the 2nd one holds years.

I am able to write a script which filters by single parameter but how extend functionality when for example user choose Germany and 2017 (show all projects from Germany in 2017)?

<select class="form-control" id="filter-by-country">
  <option selected="selected">COUNTRY</option>
  <option>ALL</option>
  <option>Belgium</option>
  <option>Germany</option>
  <option>Russia</option>
</select>

<select class="form-control" id="filter-by-year">
  <option selected="selected">COUNTRY</option>
  <option>ALL</option>
  <option>2018</option>
  <option>2017</option>
  <option>2016</option>
  <option>2015</option>
</select>

<table class="table table-hover all-projects">
  <thead>
    <tr>
      <th scope="col">order date</th>
      <th scope="col">project id</th>
      <th scope="col">full project's name</th>
      <th scope="col">quantity</th>
      <th scope="col">order no</th>
    </tr>
  </thead>
  <tbody>
    <tr class="text-center belgium 2018">
      <td>27.09.2018</td>
      <td></td>
      <td class="text-left">First project</td>
      <td>0</td>
      <td></td>
    </tr>
    <tr class="text-center germany 2017">
      <td>27.09.2017</td>
      <td>5461</td>
      <td class="text-left">Second project</td>
      <td>0</td>
      <td></td>
    </tr>
    <tr class="text-center russia 2016">
      <td>27.09.2016</td>
      <td>5462</td>
      <td class="text-left">Third project</td>
      <td>0</td>
      <td></td>
    </tr>
    <tr class="text-center russia 2018">
      <td>27.09.2018</td>
      <td>5462</td>
      <td class="text-left">Fourth project</td>
      <td>0</td>
      <td></td>
    </tr>
    <tbody>
</table>

Upvotes: 1

Views: 402

Answers (4)

Ercan Peker
Ercan Peker

Reputation: 1662

that should do it (a piece of advice: css class names cannot start with digits, it's illegal, filter by select item value, not text)

var filter_c=$('#filter-by-country');
var filter_y=$('#filter-by-year');
$('.filter_control').on('change', function(e){

var class_c=filter_c.val().toLowerCase();
var class_y='y'+filter_y.val().toLowerCase();
$('.all-projects tr.text-center').hide();
if(class_c=='country' || class_c=='all' ){
class_c='text-center'
}
if(class_y=='yyear' || class_y=='yall' ){
class_y='text-center'
}
console.log('.'+class_c+' .'+class_y)
$('.'+class_c+'.'+class_y).show();
});

codepen: https://codepen.io/peker-ercan/pen/jeqpQx

Upvotes: 1

darklightcode
darklightcode

Reputation: 2772

My example does what you want. You can easily adapt it if you plan on adding filters as classes on rows.

$(function() {

  var selectCountry = $('#filter-by-country');
  var selectYear = $('#filter-by-year');

  var countries = [];
  var years = [];

  selectCountry
    .children('option')
    .map(function(idx, item) {
      countries.push($(item).html().toLowerCase());
    });
  selectYear
    .children('option')
    .map(function(idx, item) {
      years.push($(item).html().toLowerCase());
    })

  countries = countries.filter(function(i) {
    return ['country', 'all'].indexOf(i) === -1
  })
  years = years.filter(function(i) {
    return ['country', 'all'].indexOf(i) === -1
  })

  var tableTR = $('.all-projects tbody').find('tr');

  var filterCountries = function() {

    var country = selectCountry.children('option:selected').val().toLowerCase();
    var year = selectYear.children('option:selected').val().toLowerCase();

    var conditionHappens = false;
    var foundCountry = countries.indexOf(country) !== -1;
    var foundYear = years.indexOf(year) !== -1;
    var conditions = [];

    if (foundCountry) {
      conditions.push(country);
    }

    if (foundYear) {
      conditions.push(year);
    }

    $.each(tableTR, function(idx, item) {

      var processCond = conditions.map(function(cond) {
        return $(item).hasClass(cond);
      }).indexOf(false) === -1;

      if (processCond) {
        $(item).show();
      } else {
        $(item).hide();
      }

    })

  }

  $(selectCountry).on('change', filterCountries)
  $(selectYear).on('change', filterCountries)

})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- COUNTRIES -->
<select class="form-control" id="filter-by-country">
  <option selected="selected">COUNTRY</option>
  <option>ALL</option>
  <option>Belgium</option>
  <option>Germany</option>
  <option>Russia</option>
</select>

<!-- YEARS -->
<select class="form-control" id="filter-by-year">
  <option selected="selected">COUNTRY</option>
  <option>ALL</option>
  <option>2018</option>
  <option>2017</option>
  <option>2016</option>
  <option>2015</option>
</select>

<table class="table table-hover all-projects">
  <thead>
    <tr>
      <th scope="col">order date</th>
      <th scope="col">project id</th>
      <th scope="col">full project's name</th>
      <th scope="col">quantity</th>
      <th scope="col">order no</th>

    </tr>
  </thead>
  <tbody>
    <tr class="text-center belgium 2018">
      <td>27.09.2018</td>
      <td></td>
      <td class="text-left">First project</td>
      <td>0</td>
      <td></td>
    </tr>
    <tr class="text-center germany 2017">
      <td>27.09.2017</td>
      <td>5461</td>
      <td class="text-left">Second project</td>
      <td>0</td>
      <td></td>
    </tr>
    <tr class="text-center russia 2016">
      <td>27.09.2016</td>
      <td>5462</td>
      <td class="text-left">Third project</td>
      <td>0</td>
      <td></td>
    </tr>
    <tr class="text-center russia 2018">
      <td>27.09.2018</td>
      <td>5462</td>
      <td class="text-left">Fourth project</td>
      <td>0</td>
      <td></td>
    </tr>
    <tbody>
</table>

Upvotes: 1

Jitendra G2
Jitendra G2

Reputation: 1206

I hope below example will be useful,

var originalContent;

$(document).ready(function() {
  originalContent = $('#allprojects').html();

  $('#filter-by-country').change(function() {
    Loaddata();
  });

  $('#filter-by-year').change(function() {
    Loaddata();
  });
});

function Loaddata() {
  $('#allprojects').html(originalContent);

  var country = $('#filter-by-country').val().toLowerCase();
  var year = $('#filter-by-year').val().toLowerCase();

  var newSelector = "";

  if (country != "all") {
    newSelector += "." + country;
  }
  if (year != "all") {
    newSelector += "." + year;
  }

  var data = $('#allprojects').find("tr" + newSelector + "");
  $('#allprojects').html(data);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select class="form-control" id="filter-by-country">
  <option>ALL</option>
  <option>Belgium</option>
  <option>Germany</option>
  <option>Russia</option>
</select>

<select class="form-control" id="filter-by-year">
  <option>ALL</option>
  <option>2018</option>
  <option>2017</option>
  <option>2016</option>
  <option>2015</option>
</select>

<table id='allprojects' class="table table-hover all-projects">
  <thead>
    <tr>
      <th scope="col">order date</th>
      <th scope="col">project id</th>
      <th scope="col">full project's name</th>
      <th scope="col">quantity</th>
      <th scope="col">order no</th>
    </tr>
  </thead>
  <tbody>
    <tr class="text-center belgium 2018">
      <td>27.09.2018</td>
      <td></td>
      <td class="text-left">First project</td>
      <td>0</td>
      <td></td>
    </tr>
    <tr class="text-center germany 2017">
      <td>27.09.2017</td>
      <td>5461</td>
      <td class="text-left">Second project</td>
      <td>0</td>
      <td></td>
    </tr>
    <tr class="text-center russia 2016">
      <td>27.09.2016</td>
      <td>5462</td>
      <td class="text-left">Third project</td>
      <td>0</td>
      <td></td>
    </tr>
    <tr class="text-center russia 2018">
      <td>27.09.2018</td>
      <td>5462</td>
      <td class="text-left">Fourth project</td>
      <td>0</td>
      <td></td>
    </tr>
    <tbody>
</table>

Upvotes: 1

Stephan T.
Stephan T.

Reputation: 6074

If you approach this with KendoUI, you can do it by adding your data to this, which also has the great feature of autocompletion:

function filterAutoCompleteDataSource(e) {
  var gridFilter = e.sender.dataSource.filter();
  e.sender.element.find(".k-autocomplete input").data("kendoAutoComplete").dataSource.filter(gridFilter);
}

$(document).ready(function() {
  $("#grid").kendoGrid({
    dataSource: {
      type: "odata",
      transport: {
        read: "//demos.telerik.com/kendo-ui/service/Northwind.svc/Orders"
      },
      schema: {
        model: {
          fields: {
            OrderID: {
              type: "number"
            },
            Freight: {
              type: "number"
            },
            ShipName: {
              type: "string"
            },
            OrderDate: {
              type: "date"
            },
            ShipCity: {
              type: "string"
            }
          }
        }
      },
      pageSize: 20,
      serverPaging: true,
      serverFiltering: true,
    },
    dataBound: filterAutoCompleteDataSource,
    height: 550,
    filterable: {
      mode: "row"
    },
    pageable: true,
    columns: [{
      field: "OrderID",
      width: 225,
      filterable: {
        cell: {
          showOperators: false
        }
      }
    }, {
      field: "ShipName",
      width: 500,
      title: "Ship Name",
      filterable: {
        cell: {
          operator: "contains"
        }
      }
    }, {
      field: "Freight",
      width: 255,
      filterable: {
        cell: {
          operator: "gte"
        }
      }
    }, {
      field: "OrderDate",
      title: "Order Date",
      format: "{0:MM/dd/yyyy}"
    }]
  });
});
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />
  <title>Kendo UI Snippet</title>

  <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.3.911/styles/kendo.common.min.css" />
  <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.3.911/styles/kendo.rtl.min.css" />
  <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.3.911/styles/kendo.silver.min.css" />
  <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.3.911/styles/kendo.mobile.all.min.css" />

  <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
  <script src="https://kendo.cdn.telerik.com/2018.3.911/js/kendo.all.min.js"></script>
</head>

<body>
  <div id="grid"></div>
</body>

</html>

That way, your grid will probably even be prettier ;)

Upvotes: 0

Related Questions