Srik
Srik

Reputation: 2381

filter search result using angularjs

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

Answers (1)

user1135469
user1135469

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

Related Questions