AngularJS dirPagination Select all visible lines

I am creating a CRUD data management project using Angular and the dirPagination directive and must have a Select All checkbox that selects all rows that are visible / without / using jQuery.

I started with this - note - I am climbing the Angular learning curve and I know some / all of this may not be the "Angular way", but I also don't want to start messing around (no pun intended) with the guts of dirPagination, ergo the dirPagination directive:

 <tr dir-paginate-start="item in items|filter:filterFunction()|orderBy:sortPredicate:reverse| itemsPerPage: rowsPerPage">

      

and a separate line-checkbox

<input type="checkbox" class="rowSelector" ng-model="item.isSelected"  ng-change="rowSelect($index, $event)"/> status: {{item.isSelected}}

      

and related model elements:

$scope.items = [] //subsequently filled
$scope.rowsPerPage = 5;
$scope.rowSelect = function (ix, $event) {
           var checked = (typeof $event == 'undefined') ? false : true;
           if (!checked) { $scope.masterCheck = false; }
           var rpp = $scope.rowsPerPage;
           var p = $scope.__default__currentPage;  //dirPagination current page
           var start = ((Math.max(0, p - 1) * rpp));
           $scope.items[start + ix].isSelected = checked;
       };

      

works as expected. Check / uncheck the checkbox and the {{item.isSelected}} value will be updated in the model and displayed next to this checkbox.

Then I added this / outside / dirPagination repeat block:

<input type="checkbox" id="masterCheckbox" ng-model="masterCheck" ng-click="checkAll()" />

      

and its associated function in the model:

 $scope.masterCheck = false;
 $scope.checkAll = function () {
           var rpp = $scope.rowsPerPage;
           var p = $scope.__default__currentPage;          //dirPagination current page
           var start = ((Math.max(0, p - 1) * rpp));
           var checked = $scope.masterCheck == true;
           var rows = document.getElementsByClassName("rowSelector");
           for (var ix = 0; ix < rows.length; ix++) {
               rows[ix].checked = checked;
               $scope.items[start + ix].isSelected = checked;
           }
       }

      

however, in the checkAll () function checking / unchecking the checkbox, the individual rows are not reflected in the {{item.isSelected}} display of each row.

Explicitly setting a single item with

$scope.items[start + ix].isSelected = checked;

      

seems to set the isSelected property of this element within the checkAll function, but the display of the row does not change.

It is clear that I have something wrong, perhaps a misunderstanding of the problem with Scope, but at the moment I am at a dead end.

Any help is greatly appreciated :-)

+3


source to share


2 answers


The light finally woke up.

checkAll (), as written, tried to access each row by calculating its position using dir-paginate __default__currentPage and Angular row $ index.

Of course this doesn't work because the collection of [] items stored in dir-paginate is filtered and sorted, so when the [] items are actually checked (item.isSelected = true) the selected items / rows were living on invisible pages. those. we selected the wrong indices.

One solution consists of the following:

Main checkbox

<input type="checkbox" id="masterCheckbox" ng-model="masterCheck" ng-click="checkAll()" />

      

Line checkbox (call note function)

<input type="checkbox" class="rowSelector" value="{{sourceIndex('senId',item.senId)}}" ng-model="item.isSelected" ng-click="rowSelect(this)" />

      

the dir-paginate directive controls the tag



 <dir-pagination-controls on-page-change="onPageChange(newPageNumber)" max-size="15" direction-links="true" boundary-links="true" pagination-id="" template-url=""></dir-pagination-controls>

      

and the corresponding $ scope values ​​and functions:

       $scope.items = [];
       $scope.masterCheck = false;
       $scope.onPageChange = function (newPageNumber) {
           //clear all selections on page change
           //dir-paginate provides this hook
           $scope.masterCheck = false;
           for (var i in $scope.items) {
               $scope.items[i].isSelected = false;
           }
       }

       $scope.rowSelect = function (item) {
           //if one is unchecked have to turn master off
           if (!item.isSelected) $scope.masterCheck = false;
       }

       $scope.sourceIndex = function (keyName, key) {
           //gets the actual items index for the row key
           //see here http://stackoverflow.com/questions/21631127/find-the-array-index-of-an-object-with-a-specific-key-value-in-underscore
           //for the 'getIndexBy' prototype extension
           var ix = $scope.items.getIndexBy(keyName, key);
           return ix;

       }

       $scope.checkAll = function () {
           //only visible rows 
           var boxes = document.getElementsByClassName("rowSelector");
           for (var bix in boxes) {
               var ix = boxes[bix].value;
               $scope.items[ix].isSelected = $scope.masterCheck;
           }
       }

      

There is probably a better way, but while not very efficient, it works well enough for regular people.

The $ scope.sourceIndex () function fills the actual source row index in the row cell as value = attribute.

The checkAll () function then grabs all visible rows with the "rowSelector" class, and then iterates over those that grab the data index from the checkbox value and set the corresponding element. Selected.

The value of the $ scope.onPageChange variable is specified in the dir-Paginate controls directive and ensures that all row selections are cleared when the page changes.

Happy happy.

+3


source


Your masterCheck variable is set to false in rowSelect () and then in the checkAll () you set it is checked against masterCheck, which is then used to assign isSelected

This line is wrong:

var checked = $scope.masterCheck == true;

      

Since you want to flip masterCheck so that it is:

$scope.masterCheck = !$scope.masterCheck;

      



and then

.isSelected = $scope.masterCheck;

      

You never set $ scope.masterCheck to true, so it was always false, and since your isSelected values ​​depended on it, they were always false. Also, this works like checkAll / unCheckAll to only check for the following:

$scope.masterCheck = !$scope.masterCheck;
var checked = $scope.masterCheck == true;

      

0


source







All Articles