dojodgriddstore

Filtering dstore collection against an array field


I'm trying to filter a dstore collection by a field that has an array of values. My json data looks like the following (simplified):

[{
    user_id: 1,
    user_name: "John Doe",
    teams: [{team_id: 100, team_name: 'Red Sox'}, {team_id: 101, team_name: 'Buccaneers'}]
},
{
    user_id: 2,
    user_name: "Fred Smith",
    teams: [{team_id: 100, team_name: 'Buccaneers'}, {team_id: 102, team_name: 'Rays'}]
}]

I can do a simple filter against the username field and it works perfectly.

this.dstoreFilter = new this.dstore.Filter();

var results = this.dgrid.set('collection', this.dstore.filter(
     this.dstoreFilter.match('user_name',new RegExp(searchTerm, 'i'))
));

How, though, do I construct a filter to show me only those players who play for the Red Sox, for example. I've tried using the filter.contains() method, but I can't find any adequate documentation on how it works. Looking at the dstore code, I see that the filter.contains() method has the following signature: (value, required, object, key), but that's not helping me much.

Any guidance would be much appreciated. Thanks in advance!


Solution

  • You can find documentation on Filtering here.

    In your case, .contains() will not work because it is intended to work on values of array type. What you want to filter here is array of objects. Here is a quote from the doc link:

    contains: Filters for objects where the specified property's value is an array and the array contains any value that equals the provided value or satisfies the provided expression.

    In my opinion, the best way here is to override the filter method where you want to filter by team name. Here is some sample code:

    this.grid.set('collection', this.dstore.filter(lang.hitch(this, function (item) {
        var displayUser = false;
        for(var i=0; i < item.teams.length; i++){
            var team = item.teams[i];
            if(team.team_name == 'Red Sox'){
                displayUser = true;
                break;
            }
        }
        return displayUser;
    })));
    this.grid.refresh();
    

    For each user in the store, if false is returned, it's display is set to false and if true is returned it gets displayed. This is by far the easiest way that I know of to apply complex filtering on dstore.

    Some similar questions that you might want to read up: link, link, link