Filter a store with array of values from one prope

2019-09-05 08:23发布

问题:

I'm trying to apply a constraint on combobox. It's half-working at the moment. On the combobox, I have this listener:

[...]
        listeners: {
            'focus': function (combo, value) {
                var orgComboVal = Ext.getCmp('Org1')
                var getOrgValue = orgComboVal.getValue();
                if (typeof getOrgValue !== undefined) {
                    reseaulist.clearFilter(true);
                    for (var q = 0, l = getOrgValue.length; q < l; q++) {
                        reseaulist.filter([
                            {property:'code_organisme', value: getOrgValue[q]}
                        ]);
                    }
                }
            }
        }

Ext.getCmp('Org1') defines another combobox.
When orgComboVal.getValue() is a single value, the filter is well applying.
but when it's an array of value, eg ["5", "9"], it's not working and the combobox supposed to be filtered shows no value (so I guess a filter is still applied but in an incorrect way).

I guess it's because the reseaulist.filter is called multiple time. How can I achieve this ?

I saw the filterBy method but I don't know how to make it work.

Also, this post is interesting : How to filter a store with multiple values at once? but same, can't make it work since

getOrgValue.split(',') 

is showing an error

(Object Array has no method split)

Any tips ? I'm using ExtJS 4.2.

EDIT

Thanks to @rixo, I've made it. Also, I had to change some of the code he provided me, because the value of the Org1 combobox was always an array, even if empty, so the store filter was never cleared.

Here it is :

            'focus': function (combo, value) {
                var orgComboVal = Ext.getCmp('Org1')
                var values = orgComboVal.getValue();
                console.log(values)
                if (values != null) {
                    reseaulist.clearFilter(false);
                    if (Ext.isArray(values)) {
                        if (0 < values.length) {
                            reseaulist.filterBy(function(record, id) {
                                return Ext.Array.contains(values, record.get('code_organisme'));
                            });
                        } else {
                        reseaulist.clearFilter(true);
                    }   
                    } 
                } 
            }

回答1:

Each filter is applied one after the other on the previously filtered data set, so your code implements a logical AND. That's why all values are filtered out...

Here's an example using filterBy to accept any value that is in your array:

function (combo, value) {
    var orgComboVal = Ext.getCmp('Org1')
    var values = orgComboVal.getValue();
    if (values != null) {
        store.clearFilter(false);
        if (Ext.isArray(values)) {
            store.filterBy(function(record, id) {
                return Ext.Array.contains(values, record.get('code_organisme'));
            });
        } else {
            record.get('code_organisme') === values;
        }
    } else {
        store.clearFilter(true);
    }
}

Or you could also use a regex with the filter method:

function (combo, value) {
    var orgComboVal = Ext.getCmp('Org1')
    var values = orgComboVal.getValue();
    if (values != null) {
        var filterValue = Ext.isArray(values)
            ? new RegExp('^(?:' + Ext.Array.map(values, function(value){return Ext.escapeRe(value)}).join('|') + ')$')
            : values;
        store.clearFilter(false);
        store.filter('code_organisme', filterValue);
    } else {
        store.clearFilter(true);
    }
}

Concerning your error, arrays indeed don't have a split method. Strings can be split into an array. Arrays, on their side, can be joined into a string...



回答2:

Try This....

var getOrgValue = "5,9,4"; // array of value

reseaulist.filterBy(function(rec, id) {
  return getOrgValue.indexOf(rec.get('code_organisme')) !== -1;
});