I have 2 nested ng-repeats to populate a list of categories and items under those categories. I am trying to implement a search filter so:
- If the title of an item contains the string of the search filter, this item and its category should be displayed.
- If the name of the category contains the string of the search filters, this category should be displayed. If non of the items under this category match the filter, all the items under the category should be displayed.
- The search filter is bind to the model of an input field.
I have tried to implement a custon filter to loop through the categories and populate an array based on the title of the items or the name of the category, but it creates an infinite loop.
<li data-ng-repeat="group in vars.filteredCategories = (allCategories | customFilter:filters.searchText)"> {{group.category}} <ul> <li data-ng-repeat="item in group.items | orderBy:'title'">{{item.title}}</li> </ul>
Controller:
$scope.allCategories = [{"category":"cat1","items":[{"id":10015,"title":"Test","category":"cat1"},{"category":"cat2","items":[{"id":10015,"title":"Test2","category":"cat2"}];
Custom filter (which doesn't work)
.filter('customFilter', function () {
return function (categories, search) {
var filtered = [];
var itemsPushed = [];
if (search !== '') {
angular.forEach(categories, function (category) {
if (category.category.toLowerCase().indexOf(search.toLowerCase()) !== -1) {
filtered.push(category);
} else {
if (angular.isDefined(category.items)) {
var itemsInside = angular.copy(category.items);
category.items = [];
for (var x = 0; x < itemsInside.length; x++) {
if (itemsInside[x].title.toLowerCase().indexOf(search.toLowerCase()) != -1 && itemsPushed.indexOf(itemsInside[x].id) == -1) {
category.items.push(itemsInside[x]);
itemsPushed.push(itemsInside[x].id);
}
}
filtered.push(category);
}
}
});
} else {
filtered = categories;
}
return filtered;
};
})