3

enter image description here

I'm working on reproducing a live filter box with handsontable based on the built in search functionality at http://docs.handsontable.com/0.15.0-beta6/demo-search-for-values.html.

Right Now I've got a basic setup working at http://jsfiddle.net/uL3L4teL/4/

As explained in the docs, In this code if you enter a search string, you get the matching cells outputted to the console using the following function:

Handsontable.Dom.addEvent(searchFiled, 'keyup', function (event) {
    var queryResult = hot.search.query(this.value);
    console.log(queryResult);
    // ...
});

I want to grab the rows in the data array that match the search string and filter the original data 'data' by the search string before redisplaying the table. This partially works using:

Handsontable.Dom.addEvent(searchFiled, 'keyup', function (event) {
  // debugger
  hot.loadData(tData);

  var queryResult = hot.search.query(this.value);
  rows = getRowsFromObjects(queryResult);
  console.log('searchFiled',searchFiled.value);
  console.log('rows',rows);

  console.log('tData', tData);
  var filtered = tData.filter(function (d, ix) {
      return rows.indexOf(ix) >= 0;
  });
  console.log('filtered', filtered);

  hot.loadData(filtered);

});

However when I run this I see the following in the console when I enter 'n' followed by backspacing (to empty the searchstring):

enter 'n':

rows [0, 1]
searchFiled n
rows [0, 1]
tData [Array[4], Array[4], Array[4], Array[4]]
filtered [Array[4], Array[4]]

backspace (to empty search value):

rows []
searchFiled 
rows []
tData [Array[4], Array[4], Array[4], Array[4]]
filtered []

How can I fix this so an empty string will again show the entire unfiltered table?

Josh Crozier
  • 233,099
  • 56
  • 391
  • 304
user1592380
  • 34,265
  • 92
  • 284
  • 515

1 Answers1

3

You could add a condition inside of the .filter() method that will return all rows if the value searchFiled.value is empty or undefined:

Updated Example

var filtered = tData.filter(function(_, index) {
  if (searchFiled.value) {
    return rows.indexOf(index) >= 0;
  } else {
    return true;
  }
});

Alternatively, here is a one-liner that does the same thing (although it is less readable):

Updated Example

var filtered = tData.filter(function(_, index) {
  return !searchFiled.value || rows.indexOf(index) >= 0;
});
Josh Crozier
  • 233,099
  • 56
  • 391
  • 304
  • `!searchFiled.value` should be changed to `searchFiles.value != ''`, otherwise '0' would also list all results. – noahnu Jan 16 '16 at 18:03
  • 1
    @noahnu No it won't. The variable `searchFiled.value` is a string. All the rows contain a `0`, which means that they will be selected anyways. If one of the rows *doesn't* contain a `0`, then they won't all be selected. Here is an updated example demonstrating this -> http://jsfiddle.net/awyjnbj6/ – Josh Crozier Jan 16 '16 at 18:05
  • Thanks Josh! I'm new to JS, was the main problem here filtering by an empty string which didn't happen with the initial table load? – user1592380 Jan 16 '16 at 18:40
  • @user61629 Yep, that was the problem. When the table initially loaded, it wasn't being filtered, so there wasn't a problem. In the code you provided, none of the elements were returned when filtering by an empty string (which is why we added the conditional to return `true` if the string is empty). – Josh Crozier Jan 16 '16 at 18:59