Reputation: 2381
I am trying to build a search page using angularjs. I need to provide some fields (check box, radio, age range, etc) as filters for search result. For this demo, I am focusing only on check boxes. I have given a demo code in the below plunker list
http://plnkr.co/edit/PMQQzf63uy8Pzq4fVIYQ?p=preview
So basically, in the above page, when user selects "Yellow" then the field "show" for "result 1" should become false. And if the user further selects "Circle" then the field "show" for "result 2" should be false. The user can select more then one color or shape.
Though I have not written the lengthy code, below is pretty much I am thinking of:
whenever there is user action on filters{ //select or deselect
for each result{ //"result 1", "result 2", "result 3"
result.show=true
//The below condition is m:n check and hence is a nested for loop.
if none of the selected colors match the colors in the result
result.show=false
//The below condition can be achieved using a single for loop
if none of the selected shapes match the shape of the result
result.show=false
}
}
I would like to know any design patterns I can refer to for designing the above function. Also if there are any easy alternatives in angularjs to achieve the above.
Edit: Actually I want to hide the results that do not match the filter criteria. I used the field "show" just to demonstrate the example.
Upvotes: 3
Views: 2129
Reputation: 1020
This what you're looking for?
Make <div ng-repeat="result in results">
in your HTML equal to <div ng-repeat="result in results | filter:searchFn">
And this as the js.
var sampleFilter = angular.module('sampleFilter', []);
sampleFilter.service('lookups',function(){
var colors = [
{"id":1, "name":"Red"},
{"id":2, "name":"Green"},
{"id":3, "name":"Yellow"}
];
var shapes = [
{"id":1, "name":"Square"},
{"id":2, "name":"Rectangle"},
{"id":3, "name":"Circle"}
];
this.colors = function(){
return colors;
}
this.shapes = function(){
return shapes;
}
});
sampleFilter.service('search',function(){
var results = [
{"id":1, "colors":[1,2], "shape":2, "show":true},
{"id":2, "colors":[1,3], "shape":1, "show":true},
{"id":3, "colors":[2,3], "shape":3, "show":true}
];
this.results = function(){
return results;
}
});
sampleFilter.controller('FilterController',['$scope', 'lookups', 'search', function($scope, lookups, search){
$scope.colors = lookups.colors();
$scope.shapes = lookups.shapes();
$scope.results = search.results();
$scope.isFilterColor = function(result){
var found = false;
angular.forEach($scope.colors, function(value,index){
if(value.selected){
console.log(value.id);
if(result.colors.indexOf(value.id)!= -1)
found = true;
}
});
return found;
};
$scope.isFilterShape = function(result){
var found = false;
angular.forEach($scope.shapes, function(value,index){
if(value.selected){
if(result.shape == value.id)
found = true;
}
});
return found;
};
$scope.searchFn = function (result) {
if ( $scope.isFilterShape(result) && $scope.isFilterColor(result) ) {
return true;
}
};
}]);
I've turned the 'lookups' dictionaries into arrays so on the html page you'll need to make some slight changes to get the color and shape names to show correctly.
Upvotes: 2