Hearaman
Hearaman

Reputation: 8726

Filtering with multiple checkboxes in angularJS

I'm new to AngularJS. I wrote a program to filter the Item list when i check related check boxes. But here my CheckBoxes are behaving like "Radio" buttons. Anyway, program is working but it is not working with multiple check boxes. Please help me.

My Program @ http://plnkr.co/edit/iV7wyYoCNJdY1Ze7J6Pg?p=preview

Upvotes: 7

Views: 34583

Answers (3)

vincent T
vincent T

Reputation: 47

If, like me you are not really familiar with custom filter and prefer a simpler solution, here is a simple example to bind data with ng-model of checkboxes in ng-repeat: tutorial here

It is a good example with ng-value-true and ng-value-false :

<div ng-repeat="fruit in fruits"> 
<input type="checkbox" ng-model="fruit.name" ng-true-value="{{fruit.name}}" ng-false-value="{{fruit-name}} - unchecked" ng-change="filterMultipleSystem()"/><br/> 
</div>

The Javscript function:

 $scope.filterMultipleSystem = function(){ 
    setTimeout(function () { 
    var x = document.getElementsByClassName("firstLoop"); 
    var i; for (i = 0; i < x.length; i++) { 

    if(x[i].title.indexOf("unchecked")!==-1){ 
    x[i].style.display = "none"; 
    } 

    else 
    x[i].style.display = "inherit"; }},10); }`;

Upvotes: 1

Imants Volkovs
Imants Volkovs

Reputation: 836

Here is bit refined filter(edited for my needs from @Maxim Shoustin) where you can select by multiple arguments. If u had 3 types and needed select 2 of 3, you can use this, cause other doesnt work on that(tried myself):

    app.filter('myfilter', function () {
    return function (items, types) {
        var filtered = [];
        for (var i in items)
        {

            if (types.found == true && items[i].type == 'Found') {
                filtered.push(items[i]);
            }                
            else if (types.notfound == true && items[i].type == 'Not found') {
                filtered.push(items[i]);
            }
            else if (types.moved == true && items[i].type == 'Moved') {
                filtered.push(items[i]);
            }
        }

        return filtered;
    };
});

Upvotes: 0

Maxim Shoustin
Maxim Shoustin

Reputation: 77904

Easy way

I would Set different models for both check boxes and add filter like:

<body data-ng-controller="TestController">
        <table id="hotels">
            <tr>
                <th>Hotel Name</th>
                <th>Star Rating</th>
                <th>Hotel type</th>
                <th>Hotel Price</th>
            </tr>
            <tr data-ng-repeat="hotel in hotels | filter:search.type1 | filter:search.type2">
                <td>{{hotel.name}}</td>
                <td>{{hotel.star}}</td>
                <td>{{hotel.type}}</td>
                <td>{{hotel.price}}</td>
            </tr>
        </table>
        <br/>
        <h4>Filters</h4>
        <input type="checkbox" data-ng-model='search.type1' data-ng-true-value='luxury' data-ng-false-value='' /> Luxury &nbsp;&nbsp;&nbsp;
        <input type="checkbox" data-ng-model='search.type2' data-ng-true-value='double suite' data-ng-false-value='' /> Double suite
    </body>

Demo Plunker

Custom filter##

(I like it more)

We can bind the checkboxes to one object like:

$scope.types = {luxury: false, double_suite:false};

and after create custom filter like:

iApp.filter('myfilter', function() {
   return function( items, types) {
    var filtered = [];
    
    angular.forEach(items, function(item) {
       if(types.luxury == false && types.double_suite == false) {
          filtered.push(item);
        }
        else if(types.luxury == true && types.double_suite == false && item.type == 'luxury'){
          filtered.push(item);
        }
        else if(types.double_suite == true && types.luxury == false && item.type == 'double suite'){
          filtered.push(item);
        }
    });
  
    return filtered;
  };
});

So our HTML now seems simple:

 <body data-ng-controller="TestController">
        <table id="hotels">
            <tr>
                <th>Hotel Name</th>
                <th>Star Rating</th>
                <th>Hotel type</th>
                <th>Hotel Price</th>
            </tr>
            <tr data-ng-repeat="hotel in hotels |  myfilter:types">
                <td>{{hotel.name}}</td>
                <td>{{hotel.star}}</td>
                <td>{{hotel.type}}</td>
                <td>{{hotel.price}}</td>
            </tr>
        </table>
        <br/>
        <h4>Filters</h4>
        <input type="checkbox" data-ng-model='types.luxury'  /> Luxury &nbsp;&nbsp;&nbsp;
        <input type="checkbox" data-ng-model='types.double_suite'  /> Double suite
        <pre>{{types|json}}</pre>
    </body>

Demo 2 Plunker

[EDIT for @Mike]

If you interesting to invert the check-box filter, just add directive (grabbed from HERE):

iApp.directive('inverted', function() {
  return {
    require: 'ngModel',
    link: function(scope, element, attrs, ngModel) {
      ngModel.$parsers.push(function(val) { return !val; });
      ngModel.$formatters.push(function(val) { return !val; });
    }
  };
});

sow new HTML form:

 <input type="checkbox" inverted data-ng-model='types.luxury'  /> Luxury &nbsp;&nbsp;&nbsp;
 <input type="checkbox" inverted data-ng-model='types.double_suite'  /> Double suite

Demo 3 Plunker

Upvotes: 23

Related Questions