• Time to read 1 minute

Tabulator is a Javascript plugin that allows you to display data in a table with many powerful features that will greatly enhance the user interface of your applications, and also the user experience offered. When it comes to filtering, sorting, searching, formatting and displaying complex data structures, not many Javascript plugin can match what Tabulator can do out of the box.

However, if you are building a tree structure display - with parent and children row elements - and need the data tree to be searchable, the logic be comes a bit more complex.

This example shows how to implement a custom callback logic using a recursive function to search a data tree.

1. The recursive filter callback

In the example below, the parent item will always be displayed if a child item is a match - even if the parent itself is not a match - but you can easily adjust the code to your needs by tuning the test in the for loop.

let filterTree = function (data, filter) {
   if (data['_children'] && data['_children'].length > 0) {
      for (let i in data['_children']) {
         let condition1 = data[filter.field] == filter.value;
         let condition2 = filterTree(data['_children'][i], filter);

         return condition1 || condition2;
      }
   }

   return data[filter.field] == filter.value;
};

The function above is embedded into a variable for easy portability but you can of course adapt the logic to the context of your application.

2. Triggering the filter event

You can now call the function function above as a custom filter callback:

table.setFilter(filterTree, {field:'myfield', type:'=', value:'myvalue'});

Note that this is just example code that focuses on the logic of filtering a tree recursively. The above works only for the '=' comparison. In a real situation, you will have to implement more code to handle all other operators supported by tabulator, as dynamic operator assignment is not possible in Javascript. You could maybe consider eval() but that's another story.

More info about dynamic operator assignment here: Are Variable Operators Possible?

Here is an example of implementation handling all tabulator operators:

// Operators
var compare = {
    '=': function(a, b) { return a == b },
    '<': function(a, b) { return a < b },
    '<=': function(a, b) { return a <= b },
    '>': function(a, b) { return a > b },
    '>=': function(a, b) { return a >= b },
    '!=': function(a, b) { return a != b },
    'like': function(a, b) { return a.includes(b)}
};

// Filter function
var filterTree = function (data, filter) {
    if (data['_children'] && data['_children'].length > 0) {
        for (var i in data['_children']) {
            let condition1 = compare[filter.type](data[filter.field], filter.value);
            let condition2 = filterTree(data['_children'][i], filter);

            return condition1 || condition2;
        }
    }

    return compare[filter.type](data[filter.field], filter.value);
};

// Set a filter. The operator can now be provided dynamically
table.setFilter(filterTree, {field:'myfield', type: '>=', value:'myvalue'});

Tabulator.js is one of the best free javascript plugins available on the web for frontend data manipulation and display. The upcoming versions will probably make it easier to implement tree search.

For now, this is a quick and efficient way to implement the feature.