Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SlickGrid DataView filter function behaving abnormally

In my custom filter function that I set by calling setFilter() on my DataView, I did the following to troubleshoot a problem with my filtering algorithm:

function myFilter(item) {
    console.dir(item);
    console.dir(arguments);
}

To my surprise, I got the following output (pseudo-output):

  • Object - the actual item object
  • Arguments - a two-item array where the first item is the data set array (that DataView uses) and the second argument is undefined.

How can this (i.e. arguments[0] !== item) be?

like image 947
Ates Goral Avatar asked Feb 03 '12 10:02

Ates Goral


2 Answers

After spending hours scratching my head and contemplating on what I thought I knew about how functions work (while blaming my lack of sleep), I finally thought about checking SlickGrid code. I found out the hard way that SlickGrid recompiles the filtering function (using toString() and string massaging) for caching/optimization and therefore the actual arguments array doesn't match the original method signature.

As another side effect, you cannot use non-global variables that are bound to the closure of the filtering function.

The proper way to bind variables to the closure of the filtering function is to use the setFilterArgs() method of DataView. The undefined I saw as the second item of the arguments array in my (recompiled) filtering function was actually a slot for receiving what's passed through setFilterArgs().

Update

Here's what SlickGrid does to the filter function. Test function:

function (item) {
    // my code here
}

Recompiled version (reformatted for readability):

function (_items, _args) {
    var _retval = [], _idx = 0;
    var item, undefined = _args;

    for (var _i = 0, _il = _items.length; _i < _il; _i++) {
        item = _items[_i];

        // my code here
    }

    return _retval;
}
like image 168
Ates Goral Avatar answered Nov 18 '22 16:11

Ates Goral


FYI: I've made the filter function inlining optional and configurable via "inlineFilters". The setting is off by default.

like image 6
Tin Avatar answered Nov 18 '22 16:11

Tin