Well, the solution to the problem is still not added to the PrimeNG repo and so even the latest package does not have it solved.
For time being, use the solution mentioned in the question under Edit
To answer the question that I have asked under the Edit, check below:
// In some service file:
import { Table, TableHeaderCheckbox } from 'primeng/table';
import { ObjectUtils } from 'primeng/components/utils/objectutils';
import { uniq, each, intersection, map, remove } from 'lodash';
@Injectable()
export class BulkSelectAllPagesService {
overridePrimeNGTableMethods() {
TableHeaderCheckbox.prototype.updateCheckedState = function () {
const currentRows = map(this.dt.value, this.dt.dataKey);
const selectedRows = map(this.dt.selection, this.dt.dataKey);
this.rowsPerPageValue = this.dt.rows;
const commonRows = intersection(currentRows, selectedRows);
return commonRows.length === currentRows.length;
};
Table.prototype.toggleRowsWithCheckbox = function (event, check) {
let _selection;
if (!check) {
_selection = this.value.slice();
each(_selection, (row) => {
const match = {}; match[this.dataKey] = row[this.dataKey];
remove(this._selection, match);
});
} else {
_selection = check ? this.filteredValue ? this.filteredValue.slice() : this.value.slice() : [];
each(this._selection, (row) => {
const match = {}; match[this.dataKey] = row[this.dataKey];
remove(_selection, match);
});
this._selection = this._selection.concat(_selection);
}
this.preventSelectionSetterPropagation = true;
this.updateSelectionKeys();
this.selectionChange.emit(this._selection);
this.tableService.onSelectionChange();
this.onHeaderCheckboxToggle.emit({
originalEvent: event,
affectedRows: _selection,
checked: check
});
};
}
// In app.component.ts
import { Component, OnInit } from '@angular/core';
import { BulkSelectAllPagesService } from 'PATH_TO_THE_FILE/bulk-select-all-pages.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent implements OnInit {
constructor(
private bulkSelectAllPagesService: BulkSelectAllPagesService) {
}
ngOnInit() {
this.bulkSelectAllPagesService.overridePrimeNGTableMethods();
}
}
Ofcourse need to include the service file in the providers[]
in the app.module.ts
Will create a stackblitz and add later.
Improved version to handle rowspan grouped data:
overridePrimeNGTableMethods() {
TableHeaderCheckbox.prototype.updateCheckedState = function () {
const currentRows = map(this.dt.value, this.dt.dataKey);
const uniqueCurrentRows = uniq(currentRows);
const selectedRows = map(this.dt.selection, this.dt.dataKey);
this.rowsPerPageValue = this.dt.rows;
const commonRows = intersection(currentRows, selectedRows);
if (currentRows.length) {
return commonRows.length === uniqueCurrentRows.length;
} else {
return false;
}
};
Table.prototype.toggleRowWithCheckbox = function (event, rowData) {
const findIndexesInSelection = (selection: any = [], data: any = {}, dataKey: any) => {
const indexes = [];
if (selection && selection.length) {
selection.forEach((sel: any, i: number) => {
if (data[dataKey] === sel[dataKey]) {
indexes.push(i);
}
});
}
return indexes;
};
this.selection = this.selection || [];
const selected = this.isSelected(rowData);
const dataKeyValue = this.dataKey ? String(ObjectUtils.resolveFieldData(rowData, this.dataKey)) : null;
this.preventSelectionSetterPropagation = true;
if (selected) {
const selectionIndexes = findIndexesInSelection(this.selection, rowData, this.dataKey);
const selectedItems = this.selection.filter((val: any) => {
return val[this.dataKey] === rowData[this.dataKey];
});
this._selection = this.selection.filter((val: any, i: number) => {
return selectionIndexes.indexOf(i) === -1;
});
this.selectionChange.emit(this.selection);
selectedItems.forEach((selectedItem: any, index: number) => {
this.onRowUnselect.emit({ originalEvent: event.originalEvent, index: event.rowIndex + index, data: selectedItem, type: 'checkbox' });
});
delete this.selectionKeys[rowData[this.dataKey]];
} else {
let rows = [rowData];
if (dataKeyValue) {
rows = this.value.filter(val => {
return (val[this.dataKey]).toString() === dataKeyValue;
});
}
this._selection = this.selection ? this.selection.concat(rows) : rows;
this.selectionChange.emit(this.selection);
this.onRowSelect.emit({ originalEvent: event.originalEvent, index: event.rowIndex, data: rowData, type: 'checkbox' });
if (dataKeyValue) {
this.selectionKeys[dataKeyValue] = 1;
}
}
this.tableService.onSelectionChange();
if (this.isStateful()) {
this.saveState();
}
};
Table.prototype.toggleRowsWithCheckbox = function (event, check) {
let _selection;
if (!check) {
_selection = this.value.slice();
each(_selection, (row) => {
const match = {}; match[this.dataKey] = row[this.dataKey];
remove(this._selection, match);
});
} else {
_selection = check ? this.filteredValue ? this.filteredValue.slice() : this.value.slice() : [];
each(this._selection, (row) => {
const match = {}; match[this.dataKey] = row[this.dataKey];
remove(_selection, match);
});
this._selection = this._selection.concat(_selection);
}
this.preventSelectionSetterPropagation = true;
this.updateSelectionKeys();
this.selectionChange.emit(this._selection);
this.tableService.onSelectionChange();
this.onHeaderCheckboxToggle.emit({
originalEvent: event,
affectedRows: _selection,
checked: check
});
};
}