Open FrancescoBorzi opened 6 years ago
Same problem here. Paginating to page 2, and pressing check all unselects the previous list of items. I would suggest that after paginating the check all box will be shown as unselected, and then you can click check all. I am using [rowidentity] as mentioned. And selecting single items works with pagination
Found a solution using custom checkboxes, and custom select all function. And an object that stores which pages has selected all.
Custom checkbox column taken from http://swimlane.github.io/ngx-datatable/#chkbox-selection-template Here i removed let-allRowsSelected="allRowsSelected" let-selectFn="selectFn" From template, and hooked up my own checkbox function.
<ngx-datatable-column
[width]="30"
[sortable]="false"
[canAutoResize]="false"
[draggable]="false"
[resizeable]="false">
<ng-template
ngx-datatable-header-template
let-value="value">
<input type="checkbox"
[checked]="selectAllOnPage[pageOffset]"
(change)="selectAll($event)"
/>
</ng-template>
<ng-template
ngx-datatable-cell-template
let-value="value"
let-isSelected="isSelected"
let-onCheckboxChangeFn="onCheckboxChangeFn"
>
<input
type="checkbox"
[checked]="isSelected"
(change)="onCheckboxChangeFn($event)"
/>
</ng-template>
</ngx-datatable-column>
With this select all function (CompanyListPaginated are my rows, for the page)
selectAll(event) {
if (!this.selectAllOnPage[this.pageOffset]) {
// Unselect all so we dont get duplicates.
if (this.selected.length > 0) {
this.companyListPaginated.map(company => {
this.selected = this.selected.filter((selected) => selected.uuid !== company.uuid);
})
}
// Select all again
this.selected.push(...this.companyListPaginated);
this.selectAllOnPage[this.pageOffset] = true;
} else {
// Unselect all
this.companyListPaginated.map(company => {
this.selected = this.selected.filter((selected) => selected.uuid !== company.uuid);
});
this.selectAllOnPage[this.pageOffset] = false;
}
}
Remember to remove selectAll page index when unselecting a single item.
onSelect({ selected }) {
// Make sure we are no longer selecting all
this.selectAllOnPage[this.pageOffset] = false;
this.selected.splice(0, this.selected.length);
this.selected.push(...selected);
}
However i really wished i didnt have to handle this manually. One of the reasons i chose ngx datatable is that I wanted to avoid making custom select/select all functions.
@RonjaKnudtsen Thank you so much for the solution 👍
Found a solution using custom checkboxes, and custom select all function. And an object that stores which pages has selected all.
Custom checkbox column taken from http://swimlane.github.io/ngx-datatable/#chkbox-selection-template Here i removed let-allRowsSelected="allRowsSelected" let-selectFn="selectFn" From template, and hooked up my own checkbox function.
<ngx-datatable-column [width]="30" [sortable]="false" [canAutoResize]="false" [draggable]="false" [resizeable]="false"> <ng-template ngx-datatable-header-template let-value="value"> <input type="checkbox" [checked]="selectAllOnPage[pageOffset]" (change)="selectAll($event)" /> </ng-template> <ng-template ngx-datatable-cell-template let-value="value" let-isSelected="isSelected" let-onCheckboxChangeFn="onCheckboxChangeFn" > <input type="checkbox" [checked]="isSelected" (change)="onCheckboxChangeFn($event)" /> </ng-template> </ngx-datatable-column>
With this select all function (CompanyListPaginated are my rows, for the page)
selectAll(event) { if (!this.selectAllOnPage[this.pageOffset]) { // Unselect all so we dont get duplicates. if (this.selected.length > 0) { this.companyListPaginated.map(company => { this.selected = this.selected.filter((selected) => selected.uuid !== company.uuid); }) } // Select all again this.selected.push(...this.companyListPaginated); this.selectAllOnPage[this.pageOffset] = true; } else { // Unselect all this.companyListPaginated.map(company => { this.selected = this.selected.filter((selected) => selected.uuid !== company.uuid); }); this.selectAllOnPage[this.pageOffset] = false; } }
Remember to remove selectAll page index when unselecting a single item.
onSelect({ selected }) { // Make sure we are no longer selecting all this.selectAllOnPage[this.pageOffset] = false; this.selected.splice(0, this.selected.length); this.selected.push(...selected); }
However i really wished i didnt have to handle this manually. One of the reasons i chose ngx datatable is that I wanted to avoid making custom select/select all functions.
Can you please share the complete code? I implemented your method but I am having a weird issue. When I select the "select all" checkbox I can see the "selected" variable has all 10 items in it but the UI checkboxes for each row doesn't update as checked unless until I hover over the table body or row. As soon as I hover over any row all of the checkboxes get changed to checked state.
Also Noticed one more issue. Lets say I check "select all" checkbox on page 1 then I go to page 3 and again I check "select all" on page 3. Now when I go back to page 1 directly only the checkbox in the header (the "select all" checkbox) is checked but not all of the checkboxes in rows in the table body are in checked state.
It is a while ago i made this code, and it has changed on my part and contain a lot of business logic, so i can't share my complete code. I tried to show enough that it would work.
If it works when you hover over it, i could only guess that you need to add [rowIdentity], or that the it is not a true copy in the selected variable. If it is mutated it might not trigger a ui update.
As for your second issue. Are you using server-side pagination? In my "setPage" function where i fetch all my items (since it's server side) i check if the whole page was selected, and if any of the new items i fetched is inside the selected array.
Basically you have one angular collection of selected pages and items, and you have the variable that ngx-datatable uses which you must maintain.
In my case i have a dict with all selected items, in addition to the variable that ngx looks into.
However as i already mentioned. This is a hacky workaround, and i wish that swimlane could make their own solution.
Thank you for your reply. My second issue has been resolved but the first one is still there. I am using [rowIdentity] in my table which solved my second issue, but I can't tell what is the reason behind the first issue.
What type of checkbox are you using? What does your checkAll function look like? I was just using a standard html checkbox.
Here's my checkbox code:
<ngx-datatable-column
[width]="30"
[sortable]="false"
[canAutoResize]="false"
[draggable]="false"
[resizeable]="false">
<ng-template ngx-datatable-header-template let-value="value">
<input type="checkbox" [checked]="selectAllOnPage[page.offset]" (change)="selectAll($event)" />
</ng-template>
<ng-template ngx-datatable-cell-template let-value="value" let-isSelected="isSelected" let-onCheckboxChangeFn="onCheckboxChangeFn">
<input type="checkbox" [checked]="isSelected" (change)="onCheckboxChangeFn($event)" />
</ng-template>
</ngx-datatable-column>
and this is my selectAll function:
selectAll(event) {
if (!this.selectAllOnPage[this.page.offset]) {
// Unselect all so we don't get duplicates.
if (this.selected.length > 0) {
this.userList.map(user => {
this.selected = this.selected.filter((selected) => selected.id !== user.id);
});
}
// Select all again
this.selected.push(...this.userList);
this.selectAllOnPage[this.page.offset] = true;
} else {
// Unselect all
this.userList.map(user => {
this.selected = this.selected.filter((selected) => selected.id !== user.id);
});
this.selectAllOnPage[this.page.offset] = false;
}
}
Im not sure what the issue is.
Do you have these two tags in
[selected]="selected"
[selectAllRowsOnPage]="wholePageSelected"
Where wholepageSelected is some variable, or maybe you can use selectAllOnPage[this.page.offset]
I tried [selectAllRowsOnPage] but problem is still there.
I have the same problem with server-side pagination, the actual problem is, data object identity mismatch. In order to solve this problem use [rowIdentity]="getId"
in <ngx-datatable>
and declare getId
function in TS.
getId(row) {
return row.id;
}
I tried [selectAllRowsOnPage] but problem is still there.
@ghost try adding this in your select all function after
this.selected.push(...this.userList); this.userList = [...userList];
I think data table may not be detecting change
Here's my checkbox code:
<ngx-datatable-column [width]="30" [sortable]="false" [canAutoResize]="false" [draggable]="false" [resizeable]="false"> <ng-template ngx-datatable-header-template let-value="value"> <input type="checkbox" [checked]="selectAllOnPage[page.offset]" (change)="selectAll($event)" /> </ng-template> <ng-template ngx-datatable-cell-template let-value="value" let-isSelected="isSelected" let-onCheckboxChangeFn="onCheckboxChangeFn"> <input type="checkbox" [checked]="isSelected" (change)="onCheckboxChangeFn($event)" /> </ng-template> </ngx-datatable-column>
and this is my selectAll function:
selectAll(event) { if (!this.selectAllOnPage[this.page.offset]) { // Unselect all so we don't get duplicates. if (this.selected.length > 0) { this.userList.map(user => { this.selected = this.selected.filter((selected) => selected.id !== user.id); }); } // Select all again this.selected.push(...this.userList); this.selectAllOnPage[this.page.offset] = true; } else { // Unselect all this.userList.map(user => { this.selected = this.selected.filter((selected) => selected.id !== user.id); }); this.selectAllOnPage[this.page.offset] = false; } }
The solution is:
// Select all again this.selectAllOnPage[this.pageOffset] = true; this.selected.push(...this.userList); this.userList = {...this.userList}; this.selected = [...this.selected];
Found a solution using custom checkboxes, and custom select all function. And an object that stores which pages has selected all.
Custom checkbox column taken from http://swimlane.github.io/ngx-datatable/#chkbox-selection-template Here i removed let-allRowsSelected="allRowsSelected" let-selectFn="selectFn" From template, and hooked up my own checkbox function.
<ngx-datatable-column [width]="30" [sortable]="false" [canAutoResize]="false" [draggable]="false" [resizeable]="false"> <ng-template ngx-datatable-header-template let-value="value"> <input type="checkbox" [checked]="selectAllOnPage[pageOffset]" (change)="selectAll($event)" /> </ng-template> <ng-template ngx-datatable-cell-template let-value="value" let-isSelected="isSelected" let-onCheckboxChangeFn="onCheckboxChangeFn" > <input type="checkbox" [checked]="isSelected" (change)="onCheckboxChangeFn($event)" /> </ng-template> </ngx-datatable-column>
With this select all function (CompanyListPaginated are my rows, for the page)
selectAll(event) { if (!this.selectAllOnPage[this.pageOffset]) { // Unselect all so we dont get duplicates. if (this.selected.length > 0) { this.companyListPaginated.map(company => { this.selected = this.selected.filter((selected) => selected.uuid !== company.uuid); }) } // Select all again this.selected.push(...this.companyListPaginated); this.selectAllOnPage[this.pageOffset] = true; } else { // Unselect all this.companyListPaginated.map(company => { this.selected = this.selected.filter((selected) => selected.uuid !== company.uuid); }); this.selectAllOnPage[this.pageOffset] = false; } }
Remember to remove selectAll page index when unselecting a single item.
onSelect({ selected }) { // Make sure we are no longer selecting all this.selectAllOnPage[this.pageOffset] = false; this.selected.splice(0, this.selected.length); this.selected.push(...selected); }
However i really wished i didnt have to handle this manually. One of the reasons i chose ngx datatable is that I wanted to avoid making custom select/select all functions.
Thanks for your answer here I'm confused that what is selectAllOnPage & pageOffset in this code and also I'm facing one more issue that if I click on select all checkbox then when I'm hovering on list then my records are getting selected otherwise my records are not getting selected can you please help me
I'm submitting a ... (check one with "x")
Using server side pagination and checkbox selection:
Current behavior
Expected behavior
Reproduction of the problem The reproduction steps are listed above. Also, I need to specify that this is NOT related with https://github.com/swimlane/ngx-datatable/issues/874 , since I set the
[rowIdentity]
function and the single selection works fine even across different pages (except for the "select all" button).Please tell us about your environment:
Table version: 0.8.x
Angular version: 5.2.9
Browser: Google Chrome 65.0.3325.181 (Official Build) (64-bit)
Language: TypeScript 2.6.2