2

I am rendering my DataTable the angular way, I added a checkbox per row and a select all checkbox at the top. The problem is that for example, I filter the rows using the search box if I check the select all it checks all the rows. What do I do so that when the select all checkbox is clicked, it only checks the visible rows after the filtering.

Html

<table id="tblAvailable" datatable="ng" dt-options="mainCtrl.dtOptions" dt-instance="mainCtrl.dtInstance" dt-column-defs="mainCtrl.dtColumnDefs" class="table table-responsive table-hover">
    <thead>
        <tr>
            <th>Ref. #</th>
            <th>Type</th>
            <th>Category</th>
            <th>Applied Amount</th>
            <th>New Amount</th>
            <th><input type="checkbox" ng-model="mainCtrl.selectAll" ng-click="mainCtrl.toggleAll(mainCtrl.selectAll)" ng-change="mainCtrl.update()"></th>
        </tr>
    </thead>
    <tbody>
        <tr ng-repeat="Item in mainCtrl.newLineDetails" ng-if="Item.Amount > 0">
            <td>{{Item.Id}}</td>
            <td>{{Item.Type.Name}}</td>
            <td>{{Item.Category.Name}}</td>
            <td>{{Item.Amount | number:2}}</td>
            <td><input type="number" ng-disabled="Item.isSelected == false" id="Amount" name="Amount" class="form-control ng-pristine ng-untouched ng-valid ng-not-empty" ng-model="Item.Amount" ng-min="1" ng-max="Item.Amount" ng-required="Item.isSelected == true" ng-change="mainCtrl.updateForFreeUps()"/></td>
            <td><input type="checkbox" ng-model="Item.isSelected" ng-change="mainCtrl.toggleOne(Item.Id)"></td>
        </tr>
    </tbody>
</table>

Ctrl

self.toggleAll = function(selectAll) {
    angular.forEach(self.newLineDetails, function (value, index) {
        self.newLineDetails[index]["isSelected"] = selectAll;
        if (selectAll == false) {
            self.newLineDetails[index]["Amount"] = null;
        }
    })

}
self.toggleOne = function (Id) {
    for (var i = 0, len = self.newLineDetails.length; i < len; i++) {
        if (self.newLineDetails[i]["Id"] == Id) {
            self.newLineDetails[i]["Amount"] = null;
            self.selectAll = false;
            self.update();
            return;
        }
    }
    self.selectAll = true;
}

2 Answers 2

3
+50

You must go through the DataTables API. DT remove and inject DOM nodes from a "shadow table" so just manipulating DOM will only have apparently (not real) effect until next redraw. Fortunately you have already implemented a dtInstance.

From 1.10.6 the most convenient way to iterate through rows, columns or cells is the every method. See this plunkr -> http://plnkr.co/edit/NOP5u4PUcwVOBFUtBkBi?p=preview

$scope.$watch('settings.selectAll', function(newVal, oldVal) {
  if (newVal == oldVal) return
  var api = $scope.dtInstance.DataTable;
  api.rows({ search:'applied' }).every(function() {
    api.cell({ row:this.index(), column:0 })
     .nodes()
     .to$()
     .find('input')
     .prop('checked', $scope.settings.selectAll);
  })
  $scope.dtInstance.DataTable.draw()
})

Here the checkbox is in column 0; the code can be translated into

  • cycle through all rows
  • get the first column
  • convert to jQuery instance
  • find the <input>
  • update the checked status

Some notes about your selectAll checkbox :

  • best to use an object as ng-model, in the example I have used a settings.selectAll literal
  • ng-click does not work effectively with checkboxes, if you really want to use a directive, use ng-change only
  • since you are using a ng-model, you can just $watch that value, calling mainCtrl.toggleAll(mainCtrl.selectAll) is "obscure"
Sign up to request clarification or add additional context in comments.

8 Comments

I saw your plunker and I searched 'Accountant' in the search box, it returned two results and then when I clicked the checkAll checkbox it checked all the items, not just the filtered items.
@klent, OK, did not thought of that :( Just add { search: applied } as row selector, then it will only iterate over filtered rows. See above. Have updated the plunkr as well.
thanks. my next problem is that even though the checkbox is checked the model of the checkbox remains false.
@klent, OK, have forked the plunkr -> plnkr.co/edit/yvFiYcDmEWvVxgyVMQLl?p=preview where the checkboxes refer to a ng-model, checked . Simply $scope.data[this.index()].checked = $scope.settings.selectAll have commented out the internal update from the loop. Look in the console to see how the checked prop changes.
@UmairRazzaq, I am pretty sure you can do that by api.rows({ search:'applied', page: 'current' }).every(.. ...
|
0

There are many ways for solving this problem: 1) You can write change function for select all checkbox. In that function first you should filter all of your data after that check them. 2) You can copy your main data to another variable (we call it x for now). after that show x in table (not your main resource). when you want to filter the rows using the search box filter main data and past it into the x variable when you want to use it for check or add etc use x variable

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.