I want to implement checkbox based filters. I have restaurants which has multiple specialties which i have stored in an array.Also one or more restaurants may have same specialty.
I have stored the specialties in different object.Along with the id and name.
Now whenever i select a specialty i want to check if this specialty is present in the specialty array of a restaurant. if yes then return this restaurant.
This is what i managed to do so far.
Html
<div ng-app="myApp" ng-controller="myCtrl">
<input type="text" ng-model="search_cat.name">
<br>
<b>Category:</b>
<div ng-repeat="cat in cuisines">
<b><input type="checkbox" ng-model="filterxyz[cat.id]" /> {{cat.name}}</b>
</div>
<hr />
<div ng-repeat="w in filtered=(restaurants | filter:filterByCategory) ">
{{w.name}}
</div>
<hr />
Number of results: {{filtered.length}}
</div>
JS
var app = angular.module('myApp', []);
app.controller('myCtrl', function ($scope) {
$scope.restaurants = [
{ name: "Restaurant A", specialities:['1','2','3'] },
{ name: "Restaurant B", specialities:['1','2'] },
{ name: "Restaurant C", specialities:['1','2','3','4']},
{ name: "Restaurant D", specialities:['1','2','3','4','5']},
{ name: "Restaurant E", specialities:['1']},
{ name: "Restaurant F", specialities:['3'] },
{ name: "Restaurant G", specialities:['1','4']},
{ name: "Restaurant H", specialities:['1','2','3','4'] }
];
$scope.cuisines=[
{ name: "Speciality A1", id: "1"},
{ name: "Speciality A2", id: "2"},
{ name: "Speciality A3", id: "3"},
{ name: "Speciality A4", id: "4"},
{ name: "Speciality A5", id: "5"}
];
$scope.filterxyz = {};
$scope.filterByCategory = function (restaurant) {
return $scope.filterxyz[restaurant.specialities] || noFilter($scope.filterxyz);
};
function noFilter(filterObj) {
for (var key in filterObj) {
if (filterObj[key]) {
return false;
}
}
return true;
}
});
You are on the right track by using a function to get the filter.
The function you are trying to implement is called a predicate function.
function(value, index): A predicate function can be used to write arbitrary filters. The function is called for each element of array. The final result is an array of those elements that the predicate returned true for.
Please see working example here
Example code below:
$scope.filterByCategory = function(value, index) {
var selectedCategories = getFilterCategories();
if (selectedCategories.length === 0) {
// no filter selected return true
return true;
}
for (var i = 0; i < selectedCategories.length; i++) {
if (value.specialities.indexOf(selectedCategories[i]) > -1) {
return true;
}
}
return false;
};
function getFilterCategories() {
var selectedCategories = [];
for (var i = 0; i < $scope.cuisines.length; i++) {
if ($scope.cuisines[i].checked) {
selectedCategories.push($scope.cuisines[i].id);
}
}
return selectedCategories;
}
You will have to update your html to bind the checkboxes to a checked value, please see below:
<div ng-repeat="cat in cuisines">
<b><input type="checkbox" ng-model="cat.checked" /> {{cat.name}}</b>
</div>