So, you’re using AngularJS, and lets say you have a list of items in a repeater. You also have some actions you have bound to some buttons on the page above the list that handle mass deleting or updating in some fashion. Now lets say you only want those page options to be visible when at least one of the list’s checkboxes are checked. In jquery of course you know how you’d handle this, but how do we do it the Angular way? (or my take on the Angular way)

If you’d like to skip the explanations and jump right to practical testing of the code, please see my Plnkr code for it.

Template code

Our page options

This sets up to only show when the scope variable “listActions” is true.

  

The repeater code

What we’re doing here on our checkboxes are to set them to a model name of “selected” which, because this is a list of checkboxes for page actions, shouldn’t be set in our JSON data, because it’s not important to the backend. All that’s important to that is the list we’ll send it for the action.

Next attribute we set on the checkbox is a “change” event handler ng-change(), and we pass it a reference to the repeater list we’re iterating over. Because when a checkbox is checked, Angular is going to update the binding to the item and automatically add the “selected” key/value to the item’s JSON. When checked, it will equal true, when not obviously false.

  
  id title
{{item.id}} {{item.title}}

AngularJS code

Going through the controller code item by item we get this type of setup

The data set -

$scope.itemList = [
    {
      id:"1",
      title:"first item"
    },
    {
      id:"2",
      title:"second item"
    },
    {
      id:"3",
      title:"third item"
    }
  ];

Our initial on view load definition of the list actions hidden state.

$scope.listActions = false;

Similar to above, the initial view state of the selected items array.

$scope.selectedItems = [];

listActionsHandler anonymous function that’s called when we click on any checkbox.

$scope.listActionsHandler = function(list) {
      var has = [];

      angular.forEach(list, function(item) {
          if ( angular.isDefined(item.selected) && item.selected === true ) {
              has.push(item);
          }
      });

      if ( has.length > 0 ) $scope.listActions = true;
      else $scope.listActions = false;

      $scope.selectedItems = has;
  };

Just to understand what’s going on in that function, lets step through it

Here we’re defining the Angular function that we’re calling on the ng-change=”lisActionsHandler(itemList)”

$scope.listActionsHandler = function(list) {

});

This, obviously we’re initializing a private array inside the function. This will hold all the items that are found to be checked.

var has = [];

Utilizing an Angular version of a “foreach” loop, we iterate over the list that was passed into the listActionsHandler function. We check to see if the current item has an attribute of “selected” in it, as items that haven’t been checked yet on the page won’t have the attribute in their JSON, but ones that you’ve checked and unchecked will have it, but they’ll have a boolean set as true or false.

If we have the “selected” attribute, and it’s set to “true” because the checkbox equivalent to the JSON item was checked, then push this item into the “has” array. Lather-rinse-repeat.

angular.forEach(list, function(item) {
   if ( angular.isDefined(item.selected) && item.selected === true ) {
      has.push(item);
   }
});

A quick check to see if we have any items in the “has” array. If so, set $scope.listActions to true. Else reset it to false. Remember the ng-show=”listActions” flag on the page options div will show or hide depending on what this is set to.

if ( has.length > 0 ) $scope.listActions = true;
else $scope.listActions = false;

Finally we set the scope variable $scope.selectedItems to equal the “has” array so it can be used to pass along to any back end you have for processing.

$scope.selectedItems = has;

The complete app module -

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

app.controller('MainCtrl', function($scope) {
  
  $scope.itemList = [
    {
      id:"1",
      title:"first item"
    },
    {
      id:"2",
      title:"second item"
    },
    {
      id:"3",
      title:"third item"
    }
  ];
  
  $scope.listActions = false;
  $scope.selectedItems = [];

  $scope.listActionsHandler = function(list) {
      var has = [];

      angular.forEach(list, function(item) {
          if ( angular.isDefined(item.selected) && item.selected === true ) {
              has.push(item);
          }
      });

      if ( has.length > 0 ) $scope.listActions = true;
      else $scope.listActions = false;

      $scope.selectedItems = has;
  };
  
  $scope.deleteSelected = function(){
    
    // do your deletion api calls here pass the
    // selected list:
    
    // $scope.selectedItems
    
    console.log($scope.selectedItems);
    
  };
  
});

Again Plnkr code.

 

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Set your Twitter account name in your settings to use the TwitterBar Section.