Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS 1 multiple true/false filters in ng-repeat

I learn best by having a "project" to work on. I'm learning angular 1.x by making a golf course listing app. golf app I have a json file I'm using with all the data. This app has a general text search, and 8 switches one can set to filter the region of the state and the type of golf course. I've got text search working great. I hacked up some of that code to make a single filter for "course type" and it actually works. But as soon as I try to make a second filter it breaks. I'll post my code below, but it is probably hacky.

What's the best way to put together EIGHT true/false switches into a filter or filters, and also combine that with a text search? I figure filter first, then text search the filtered results.

The html ng-repeat (if I take out the 2nd "private" filter, the public one works:

<div ng-repeat="course in items | searchFor:data.searchString | orderBy: 'name' | publicFilter:data.publicCourse | privateFilter:data.privateCourse " >

The filters (first one works by itself):

 .filter('publicFilter', function(){

      return function(arr, publicCourse){
           var result = [];
                if(publicCourse == true ){
                     angular.forEach(arr, function(item){
                         if(item.coursetype.toLowerCase().indexOf('public') !== -1){result.push(item);}
                     });
                     return result;
                };
      }
 })

 .filter('privateFilter', function(){

      return function(arr, privateCourse){
           var result = [];
                if(privateCourse == true ){
                     angular.forEach(arr, function(item){
                         if(item.coursetype.toLowerCase().indexOf('private') !== -1){result.push(item);}
                     });
                     return result;
                };
      }
 })
like image 469
mediaguru Avatar asked Feb 06 '26 04:02

mediaguru


1 Answers

var app = angular.module('app', []);

app.controller('mainController', function($scope) {
    // Data object
    $scope.courses = [
        {name:'Course 1', courseType:'Public', region:'Northern'},
        {name:'Course 2', courseType:'Public', region:'Northern'},
        {name:'Course 3', courseType:'Private', region:'Northern'},
        {name:'Links 4', courseType:'Private', regionmode:'Northern'},
        {name:'Links 5', courseType:'Private', region:'Northern'},
        {name:'Links 6', courseType:'Public', region:'Southern'},
        {name:'Links 7', courseType:'Public', region:'Southern'},
        {name:'Links 8', courseType:'Military', region:'Southern'},
        {name:'Course 9', courseType:'Private', region:'Southern'},
        {name:'Course 10', courseType:'Private', region:'Southern'}
    ];
    // Filter defaults
    $scope.Filter = new Object();
    $scope.Filter.courseType = {'public':'public',
                            'private':'private',
                            'military': 'military'
                        };
    $scope.Filter.region = {'northern':'northern',
                            'southern':'southern'
                        };
    // Default order
    $scope.OrderFilter = 'region';
});

// Global search filter
app.filter('searchFilter',function($filter) {
        return function(items,searchfilter) {
             var isSearchFilterEmpty = true;
              angular.forEach(searchfilter, function(searchstring) {   
                  if(searchstring !=null && searchstring !=""){
                      isSearchFilterEmpty= false;
                  }
              });
        if(!isSearchFilterEmpty){
                var result = [];  
                angular.forEach(items, function(item) {  
                    var isFound = false;
                     angular.forEach(item, function(term,key) {                         
                         if(term != null &&  !isFound){
                             term = term.toString();
                             term = term.toLowerCase();
                                angular.forEach(searchfilter, function(searchstring) {      
                                    searchstring = searchstring.toLowerCase();
                                    if(searchstring !="" && term.indexOf(searchstring) !=-1 && !isFound){
                                       result.push(item);
                                        isFound = true;
                                    }
                                });
                         }
                            });
                       });
            return result;
        }else{
        return items;
        }
    }
});
body{
    font-family:calibri,arial;
    line-height: 1em;
}
h2{
    font-size:14pt;
    font-weight:bold;
}
li{
    font-family:courier;
}

th{
    font-weight:bold;
    cursor:pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
    <div  ng-controller="mainController">
    <label>Search: <input ng-model="searchText"></label>
        <h2>Course Type</h2>
        <label>Public</label>
        <input type="checkbox" ng-model="Filter.courseType.public" ng-true-value="public"  ng-false-value="!public" />&nbsp;
        <label>Private</label>
        <input type="checkbox" ng-model="Filter.courseType.private" ng-true-value="private"  ng-false-value="!private" />&nbsp;
        <label>Military</label>
        <input type="checkbox" ng-model="Filter.courseType.military" ng-true-value="military"  ng-false-value="!military" />&nbsp;
        <hr />
        <h2>Region</h2>
        <label>Northern</label>
        <input  type="checkbox" ng-model="Filter.region.northern" ng-true-value="northern"  ng-false-value="!northern" />&nbsp;
        <label>Southern</label>
        <input  type="checkbox" ng-model="Filter.region.southern" ng-true-value="southern"  ng-false-value="!southern" />
        <hr />
        <h2>Results:</h2>
        <table width="100%" cellpadding="5">
          <thead>
            <tr style="text-align:left">
                <th ng-click="OrderFilter='name'">Name</th>
                <th ng-click="OrderFilter='courseType'">Course Type</th>
                <th ng-click="OrderFilter='region'">Region</th>
            </tr>
          </thead>
          <tbody>
            <tr ng-repeat="course in courses | filter:searchText | searchFilter:Filter.name | searchFilter:Filter.courseType | searchFilter:Filter.region | orderBy:OrderFilter">
                <td>{{course.name}}</td>
                <td>{{course.courseType}}</td>
                <td>{{course.region}}</td>
            </tr>
          </tbody>
        </table>
    </div>
</div>

Here's a jsfiddle of the above: http://jsfiddle.net/j6cgovjh/2/

Disclosure: this code was based on reworking someone else's jsfiddle - http://jsfiddle.net/w01edye9/ (I added a search box amongst other minor changes).

like image 194
K Scandrett Avatar answered Feb 07 '26 21:02

K Scandrett



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!