How to respond to clicks on a checkbox in an AngularJS directive?

Viewed 159913

I have an AngularJS directive that renders a collection of entities in the following template:

<table class="table">
  <thead>
    <tr>
      <th><input type="checkbox" ng-click="selectAll()"></th>
      <th>Title</th>
    </tr>
  </thead>
  <tbody>
    <tr ng-repeat="e in entities">
      <td><input type="checkbox" name="selected" ng-click="updateSelection($event, e.id)"></td>
      <td>{{e.title}}</td>
    </tr>
  </tbody>
</table>

As you can see, it's a <table> where each row can be selected individually with its own checkbox, or all rows can be selected at once with a master checkbox located in the <thead>. Pretty classic UI.

What is the best way to:

  • Select a single row (i.e. when the checkbox is checked, add the id of the selected entity to an internal array, and add a CSS class to the <tr> containing the entity to reflect its selected state)?
  • Select all rows at once? (i.e. do the previously described actions for all rows in the <table>)

My current implementation is to add a custom controller to my directive:

controller: function($scope) {

    // Array of currently selected IDs.
    var selected = $scope.selected = [];

    // Update the selection when a checkbox is clicked.
    $scope.updateSelection = function($event, id) {

        var checkbox = $event.target;
        var action = (checkbox.checked ? 'add' : 'remove');
        if (action == 'add' & selected.indexOf(id) == -1) selected.push(id);
        if (action == 'remove' && selected.indexOf(id) != -1) selected.splice(selected.indexOf(id), 1);

        // Highlight selected row. HOW??
        // $(checkbox).parents('tr').addClass('selected_row', checkbox.checked);
    };

    // Check (or uncheck) all checkboxes.
    $scope.selectAll = function() {
        // Iterate on all checkboxes and call updateSelection() on them??
    };
}

More specifically, I wonder:

  • Does the code above belong in a controller or should it go in a link function?
  • Given that jQuery is not necessarily present (AngularJS doesn't require it), what's the best way to do DOM traversal? Without jQuery, I'm having a hard time just selecting the parent <tr> of a given checkbox, or selecting all checkboxes in the template.
  • Passing $event to updateSelection() doesn't seem very elegant. Isn't there a better way to retrieve the state (checked/unchecked) of an element that was just clicked?

Thank you.

3 Answers
Related