Search code examples
javascripthtmlangularjsangular-uiangularjs-filter

AngularJS Unique Filter then update all Records


I'm tasked with showing a list of records with AngularJS like so:

$scope.colours = [
  {id:'1', name: 'red', active: true },
  {id:'2',  name: 'blue', active: false },
  {id:'3',  name: 'green', active: true },
  {id:'4',  name: 'red', active: false }
];

and giving the user the ability to show/hide them via a checkbox by the category(or in the example colour) they sit under. So I've taken the data and displayed some checkboxes using the Angular-UI Unique filter but when I toggle the "Red" category I want to toggle All Records that have "red" as the value.

I'm guessing I need to loop through the records and do it manually on checkbox change is there a more Angular way to do this?

Also is this even good practice to even use Angular Filters to filter out results in a ng-repeat for large datasets?

See the fiddle http://jsfiddle.net/sjmcpherso/QXk9E/

Regards


Solution

  • You could use a custom filter that sorts by multiple values. This will allow you to remove the active property from all of your data as well. Let's call it manyToMany and have it take three parameters:

    1. an array of objects to sort
    2. a string to specify which property on those objects to sort by
    3. an object hash of boolean properties whose keys correlate to possible values of the property. The value for any given property will be true if the sort property should include results matching that key.

    Here is what the filter would look like:

    .filter('manyToMany',function(){
        return function(arrInput,strProperty,objMany){
            var arrFiltered = [];
            for(var i=0,max=arrInput.length;i<max;i++){
                if(objMany[arrInput[i][strProperty]] === true){
                    arrFiltered.push(arrInput[i]);
                }
            };
            return arrFiltered;
        }
    });
    

    Then create a new object in the scope that will be used for the objMany:

    $scope.activeColors = {};
    

    And in your HTML, have your checkboxes set values on that object based on the color names from the unique repeater:

    <input type="checkbox" ng-model="activeColors[colour.name]" />{{colour.name}}
    

    And use the filter like:

    <div ng-repeat="colour in colours | manyToMany:'name':activeColors">{{colour}}</div> 
    

    Here is a fiddle