Angular CDK Selection Model - issue with checkbox header states with paginated table
Asked Answered
D

2

10

I am working on a paginated table with checkbox row selection using the angular CDK SelectionModel collection.

I have a barebones example with a couple of pages of data to flip between in my table and am facing a problem where after I select all rows on my first page using the checkbox header, when I go to the next page of data, the checkbox header remains checked even though my second page of rows are unchecked initially.

First Page

enter image description here

Second Page

enter image description here

You can see this in action at the following stackblitz

It's easy to see why from my logic for setting the checkbox indeterminate state:

[checked]="this.selectionModel.selected.length > 0"
[indeterminate]="this.selectionModel.selected.length > 0 &&
                  this.selectionModel.selected.length < this.tableData.length"

After initially selecting all rows on the first page of data with the checkbox header and then navigating to the next page of data, this.tableData.length is still equal to this.selectionModel.selected.length and so the [checked] state evaluates to true since I still have items selected from the previous page.

What do I need to do here to ensure that as I flip between pages of data in my table, the checkbox header correctly reflects the state for the selections on the current page displayed, but also correctly reflects the indeterminate state?

I am sure I am missing something simple here, appreciate any help out there!

Doting answered 30/10, 2017 at 10:24 Comment(0)
F
2

the idea is the check everytime new data state you can check this solution :

 isAllNewDataSelected() {

return (
  this.tableData.filter((e) => this.selectionModel.isSelected(e.id))
    .length === this.tableData.length
);

}

newDataHasSelected() {
return (
  this.tableData.some((e) => this.selectionModel.isSelected(e.id)) &&
  this.tableData.filter((e) => this.selectionModel.isSelected(e.id))
    .length < this.tableData.length
);

}

https://stackblitz.com/edit/angular-4v6wh2?file=src%2Fmain.ts

Frogman answered 3/2, 2023 at 16:53 Comment(1)
Ah perfect, that makes sense, I knew it was somehow about comparing the loaded page of data with the selection modelDoting
T
0

I think the problems comes in the condition of the [checked] you are checking if there are more than 0 selected fields but the conditions are overlaping. You have to add the opposite condition to ensure they never overlap.

                [checked]="
                  this.selectionModel.selected.length > 0 &&
                  this.selectionModel.selected.length < this.tableData.length
                "
                [indeterminate]="
                  this.selectionModel.selected.length > 0 &&
                  this.selectionModel.selected.length > this.tableData.length
                "

EDIT: Demo on stackblitz: https://stackblitz.com/edit/angular-qjgtbw.

Twinberry answered 3/2, 2023 at 16:12 Comment(2)
That doesnt make any difference to the behaviour, if you think otherwise, please show me on the stackblitzDoting
But it still does exactly the same thing as my original issueDoting

© 2022 - 2024 — McMap. All rights reserved.