How to filter through a table using ng-repeat checkboxes with Angularjs

It used to work, but somehow it broke. I want to be able to create checkboxes using ng-repeat to get as many checkboxes as possible based on the stored data and use them to filter through a prepared table.

Also, I don't want identical values ​​for checkboxes to be repeated.

I made plnkr with code.

<div class="row">
    <label data-ng-repeat="x in projects">
        <input
        type="checkbox"
        data-ng-true-value="{{x.b}}"
        data-ng-false-value=''
        ng-model="quer[queryBy]" />
        {{x.b}}
    </label>
</div>

      

http://plnkr.co/edit/RBjSNweUskAtLUH3Ss6r?p=preview

So, in a nutshell.

  • Filtering checkboxes Ref

    .

  • The flags will be unique.

  • Checkboxes to be rendered on the canvas ng-repeat

    with Ref

    .

+3


source to share


2 answers


Ok, here's how to do it.

First add a few lines of CSS to yours to make sure all checkboxes are visible:

<style>
  .row { margin-left: 0px }
  input[type=checkbox] { margin-left: 30px; }
</style>

      

Then add the following lines to your controller:

app.filter('unique', function() {

  return function (arr, field) {
    var o = {}, i, l = arr.length, r = [];
    for(i=0; i<l;i+=1) {
      o[arr[i][field]] = arr[i];
    }
    for(i in o) {
      r.push(o[i]);
    }
    return r;
  };
})

  app.controller("maincontroller",function($scope){
    $scope.query = {};
    $scope.quer = {};
    $scope.queryBy = '$';
    $scope.isCollapsed = true;
    $scope.selectedRefs = [];

  $scope.myFilter = function (item) { 
    var idx = $scope.selectedRefs.indexOf(item.b);
    return idx != -1; 
  };

  $scope.toggleSelection = function toggleSelection(id) {
    var idx = $scope.selectedRefs.indexOf(id);
    if (idx > -1) {
      $scope.selectedRefs.splice(idx, 1);
    }
    else {
      $scope.selectedRefs.push(id);
    }
  };

      

Uf.

For some reason, your Plunkr version of AngularJS didn't recognize the attribute unique

, so I added it to your controller.

Finally, change your html to this:

<div class="row">
    <label data-ng-repeat="x in projects | unique:'b' | orderBy:'b'" >
        <input
        id="x.b"
        type="checkbox"
        ng-click="toggleSelection(x.b)"
        ng-init="selectedRefs.push(x.b)"
        ng-checked="selectedRefs.indexOf(x.b) > -1" />
        {{x.b}} 
    </label>
</div>

      

... and your ng-repeat to that ...

<tr ng-click="isCollapsed = !isCollapsed" ng-repeat-start="x in projects | filter:myFilter | orderBy:orderProp">

      

If you're curious about how it works, add the following lines:

<div style="margin:10px 10px 30px 10px">
  <pre>{{ selectedRefs }} </pre>
</div>

      

I love this trick: you can see the exact contents of our array " selectedRefs

" and see how it changes when we check / uncheck our boxes. It really helps when developing / testing our bindings!

Binding



As you can see, these changes use a new function unique

to get a list of different values ​​from your array project

, and when the page is loaded first, we push all the values ​​into our new <<> ".

["123","321","456","654","789","987"] 

      

Then when you check boxes or check boxes we add / remove that item from this list.

Finally, we use this filter in ng-repeat

.

ng-repeat-start="x in projects | filter:myFilter | orderBy:orderProp"

      

Mission completed!

Update

If you want to start with all the check boxes not read, then this is a simple change. Just remove this line ...

ng-init="selectedRefs.push(x.b)"

      

.. and change the function myFilter

to display all elements first.

$scope.myFilter = function (item) { 
    if ($scope.selectedRefs.length == 0)
        return true;

    var idx = $scope.selectedRefs.indexOf(item.b);
    return idx != -1; 
};

      

And to add a Clear All button, just add a button to your form that calls a function in your AngularJS controller like this.

$scope.clearAll = function () { 
    $scope.selectedRefs = [];
};

      

(I have not tested these suggestions.)

+2


source


Directive

ng-false-value

requires value. Try ng-false-value='false'

or ng-false-value='null'

(in fact, you can skip this entirely if it should just be a fake value and not something specific like a string or a specific number).

As you noted in the comments, after selecting and removing the checkboxes, all rows are filtered. This is because unchecking the checkbox sets its value to false and this is inconsistent with your entity values ​​(as you probably know by just pointing out others).



Therefore, you need to set this value to the empty string at the end. It will be like this:

$scope.$watch('quer.$', function () {
  if ($scope.quer.$ === false) {
    $scope.quer.$ = '';
  }
});

      

+2


source







All Articles