0

I'm using the following code to perform a live search of a table. This works for matches in one column, but I'd like it to match multiple columns.

For example, if I have a product called "some product" and a category called "some category", a search for:

"prod cat"

would match both columns. I know that datatables can do it (see screenshot), but would prefer to have as few dependencies as I can:

datatables example

jQuery code:

$("#order_search").keyup(function () {
    var value = this.value.toLowerCase().trim();

    $("table tr").each(function (index) {
        if (!index) return;
        $(this).find("td").each(function () {
            var id = $(this).text().toLowerCase().trim();
            var not_found = (id.indexOf(value) == -1);
            $(this).closest('tr').toggle(!not_found);
            return not_found;
        });
    });
});

Here is the table

<th>Part</th>
<th>Category</th>
<th>Quantity (Stock)</th>
<th>Date Ordered</th>
<th>Date Required (Days)</th>
<th>Date Completed</th>
<th>Update</th>

Thanks!

S1M0N_H
  • 109
  • 3
  • 9

2 Answers2

0

Lets say we have the following html table (with columns Product, category and Customer)

<input type="text" id="order_search" value="" />

<table border="1" padding="5" width="100%">

  <thead>
    <tr>
      <th>Product</th>
      <th>Category</th>
      <th>Customer</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Bananas</td>
      <td>fruits</td>
      <td>Al pacino</td>
    </tr>
   <tr>
     <td>Pork</td>
     <td>Meat</td>
     <td>Nick the americans</td>
    </tr>
   <tr>
     <td>Juice</td>
     <td>Beverages</td>
     <td>The kingo</td>
   </tr>
   <tr>
     <td>Nike SB</td>
     <td>Shoes</td>
     <td>Nike</td>
    </tr>
  </tbody>

We will create function to create and assign a unique data-id to each row so we can reference easier

var uniqueId = 0;
function createUniqueId(){
  return ++uniqueId+'_tr';
}

Loop all tbody>tr and assign a unique data-id

 $('table tbody tr').each(function(index,tr){
   $(tr).attr('data-id',createUniqueId());
 });

On each keyup of the #order_search element we:

  1. Grab the value

  2. Clear any extra spaces

  3. Split with space and create an array of each word

  4. Loop this array and inside this array loop each row and in every row loop each column (like you did before)

  5. If we have a match, save this row (instead of not found a match) in the rows_found array

6.Loop all rows and the rows that are not in the rows_found array hide them

  $("#order_search").keyup(function () {

  //In every keyup restore all rows

  $("table tbody tr").each(function(index, tr){
        $(tr).css({'display':'table-row'})
  });

    var value = $(this).val().toLowerCase().trim();
    //remove extra spaces
    value = value.replace(/\s+/g,' ');

   //Split the search field value by ' ' space and create an array which we will loop

    var value_ar = value.split(' ');

    var rows_found = [];

    for(var v=0;v<value_ar.length;v++){
       var cvalue = value_ar[v];

       $("table tbody tr").each(function (index,tr) {

       $(tr).find("td").each(function (indextd, td) {
         var id = $(td).text().toLowerCase().trim();

         var found = (id.indexOf(cvalue) != -1)?true:false;
         if(found){
          //save a reference of all tr data-ids that found a match
           rows_found.push($(this).parent().attr('data-id'));
         }


       });
     });

   }//end for


   //Loop of rows and hide the one that were not found


      $("table tbody tr").each(function(index, tr){
          var myid = $(tr).attr('data-id');
          if($.inArray(myid,rows_found)<0){
            $(tr).css({'display':'none'});
          }
       });


  });
gijoe
  • 1,159
  • 7
  • 7
  • I have a working example here in codepen https://codepen.io/anon/pen/MqONBr please check if the search is working the way you have asked for – gijoe Sep 08 '18 at 20:03
0

I assume that toggle is the key here.

I would suggest a somewhat simpler approach, that doesn't require any modification of existing data and supporting multiple search words separated by spaces, like this:

$("#order_search").on('keyup', function () {
   var value = $.trim($(this).val());
   var vx = new RegExp('(' + value.split(" ").join(".*") + ')', "ig");
   $("table tr").each(function () {
      $(this).toggle(vx.test(String($(this).children().text())));
   });
});
Jan Andersen
  • 773
  • 1
  • 6
  • 13