Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 868
Hearaman Avatar asked Nov 04 '13 13:11

Hearaman


2 Answers

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

like image 135
Maxim Shoustin Avatar answered Oct 17 '22 08:10

Maxim Shoustin


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); }`;
like image 21
vincent T Avatar answered Oct 17 '22 09:10

vincent T