I wrote a little program in angular using ui-select. And I want to write a filter that do an OR search in different fields (that can be nested fields in a json). In the github of ui-select I found this filter that can do a similar things (but only with simple fields) :
/**
* AngularJS default filter with the following expression:
* "person in people | filter: {name: $select.search, age: $select.search}"
* performs an AND between 'name: $select.search' and 'age: $select.search'.
* We want to perform an OR.
*/
app.filter('propsFilter', function() {
return function(items, props) {
var out = [];
if (angular.isArray(items)) {
var keys = Object.keys(props);
items.forEach(function(item) {
var itemMatches = false;
for (var i = 0; i < keys.length; i++) {
var prop = keys[i];
var text = props[prop].toLowerCase();
if (item[prop].toString().toLowerCase().indexOf(text) !== -1) {
itemMatches = true;
break;
}
}
if (itemMatches) {
out.push(item);
}
});
} else {
// Let the output be the input untouched
out = items;
}
return out;
};
});
My json object where I want to apply this filter has this structure :
$scope.contracts = [{
name: "contract1.00",
value: 10,
id :{
id : 8000,
code : 2
},
policy : {
info : {
name : "test1",
country : "test"
}
}
}
//other elements....
The problem is that this 'propsFilter' only works with simple fields. So, if I write this :
propsFilter: {name: $select.search, value : $select.search}
It will work correcly and do an OR search in these two fields (name OR values). But in my example, I want to do the OR search with two others fields : id.id and policy.info.name.
So, what I want to do is to use a line like this :
propsFilter: {name: $select.search, value : $select.search, id.id : $select.search, policy.info.name : $select.search }
Finally, here is my plunker : http://plnkr.co/edit/ej2r7XqeTPOC5d1NDXJn?p=preview
How can I do that in the same search filter??
I've updated your plunker. First of all, break from the loop caused the filter to work only on first property name
, I've also added a condition in the if item[prop] &&
so your code doesn't throw an error when the property does not exist on the item
http://plnkr.co/edit/CwNANzodvjnuMCNyJYtA?p=preview
app.filter('propsFilter', function($parse) {
return function(items, props) {
var out = [];
if (angular.isArray(items)) {
var keys = Object.keys(props);
items.forEach(function(item) {
var itemMatches = false;
for (var i = 0; i < keys.length; i++) {
var prop = $parse(keys[i])(item);
var text = props[keys[i]].toLowerCase();
if (prop && prop.toString().toLowerCase().indexOf(text) !== -1) {
itemMatches = true;
}
}
if (itemMatches) {
out.push(item);
}
});
} else {
// Let the output be the input untouched
out = items;
}
return out;
};
});