Demo - FlexGridFilter

HTML

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdn.grapecity.com/wijmo/5.latest/styles/wijmo.min.css">
<script src="https://cdn.grapecity.com/wijmo/5.latest/controls/wijmo.min.js"></script>
<script src="https://cdn.grapecity.com/wijmo/5.latest/controls/wijmo.grid.min.js"></script>
<script src="https://cdn.grapecity.com/wijmo/5.latest/controls/wijmo.input.min.js"></script>
<script src="https://cdn.grapecity.com/wijmo/5.latest/controls/wijmo.grid.filter.min.js"></script>
<div class="container">

  <h1>
    FlexGridFilter</h1>
  <p>
    The <b>wijmo.grid.filter</b> module provides a <b>FlexGridFilter</b>
    class that adds an Excel-style filtering UI to each column.</p>
  <p>
    The <b>FlexGridFilter</b> adds filter icons to the column headers.
    Users may click the icons to see a drop-down where they can apply
    filters by value or by condition:</p>
  <div id="theGrid">
  </div>
</div>

CSS

.wj-flexgrid {
  max-height: 250px;
  margin:10px 0;
}
body {
  margin-bottom: 20px;
}

JavaScript

onload = function () {

  // generate some random data
  var countries = 'US,Germany,UK,Japan,Italy,Greece'.split(','),
      data = getTreeData();

	// FlexGridFilter client-side filtering
  var theGrid = new wijmo.grid.FlexGrid('#theGrid', {
    itemsSource: data,
    childItemsPath: 'cities'
  });
  var filter = new wijmo.grid.filter.FlexGridFilter(theGrid);
  
  updateFilterShowValues(filter);
  makeFilterHierarchical(filter, true);
}

function updateFilterShowValues(filter){
    let filterColBindings = filter.filterColumns;

    if (!filterColBindings || !filterColBindings.length) {
      filterColBindings = filter.grid.columns.map(col => col.binding);
    }

    filterColBindings.forEach(colBind => {
      let vals = getUniqueColValues(filter.grid, colBind);
      let fil = filter.getColumnFilter(colBind);
      if(fil && fil.valueFilter){
        fil.valueFilter.uniqueValues = vals;
      }
    });
  }
  
function getUniqueColValues(grid, colBind){
    let col = grid.columns.getColumn(colBind);
    if(!col){
      return null;
    }else if(col.dataMap && col.dataMap.getDisplayValues){
        return col.dataMap.getDisplayValues();
    }

    let uniquesVals = [];
    fillUniqueValues(uniquesVals,grid.collectionView.sourceCollection, col.binding, grid.childItemsPath);

    return uniquesVals;
  }
  
 function fillUniqueValues(uVals, list, binding, childsPath){
    list.forEach(item => {
      if(childsPath && item[childsPath] && item[childsPath].length){
        fillUniqueValues(uVals, item[childsPath], binding, childsPath);
      }
      if(item[binding] !== undefined && uVals.indexOf(item[binding]) < 0){
        uVals.push(item[binding]);
      }
    });
  }
  

function makeFilterHierarchical(filter, showChildRowsIfParentPassesFilter){
    filter.filterApplied.addHandler((s, e) => {
      filter.grid.collectionView.filter = null;
    });

    filter.grid.collectionView.collectionChanged.addHandler((s,e)=>{
      updateRowsVisibility(filter);
    });

   ...