I have data within Mat table with pagination and checkbox where i can select master checkbox to select or deselect checkboxes at a time. My issue is when i'm on 1st page and mastercheckbox is selected ,everything seems to work properly like all the checkbox of each page are selected and is i deselect any checckbox it remains as it is,but when i select master checkbox other than 1st page it doesnot select all checkboxes on previous page .
componet.html
<div class="order-table">
<table mat-table [dataSource]="dataSource" (matSortChange)="sortTable($event)" matSort
class="app-table ">
<ng-container matColumnDef="select">
<th mat-header-cell *matHeaderCellDef>
<mat-checkbox [(ngModel)]="masterCheckboxSelected"
(ngModelChange)="masterCheckBoxSelection()"
[checked]="selection.hasValue() && isAllSelected()" color="primary">
</mat-checkbox>
</th>
<td mat-cell *matCellDef="let row; let i = index;">
<div class="checkbox-class">
<mat-checkbox (ngModelChange)="rowSelection(row, i)" [ngModel]="row.selected"
color="primary">
</mat-checkbox>
</div>
</td>
</ng-container>
<ng-container matColumnDef="po_number">
<th mat-header-cell *matHeaderCellDef mat-sort-header="po_number">PO#
<div class="sort-indicator" [ngClass]="{ desc: sortDirection }">
{{ sortIndicator('po_number') }}
</div>
</th>
<td mat-cell *matCellDef="let element">{{element.po_number}} </td>
</ng-container>
<ng-container matColumnDef="message">
<th mat-header-cell *matHeaderCellDef mat-sort-header="message"> Message
<div class="sort-indicator" [ngClass]="{ desc: sortDirection }">
{{ sortIndicator('message') }}
</div>
</th>
<td mat-cell *matCellDef="let element"> {{element.message}} </td>
</ng-container>
<ng-container matColumnDef="vendor">
<th mat-header-cell *matHeaderCellDef mat-sort-header="vendor">Vendor
<div class="sort-indicator" [ngClass]="{ desc: sortDirection }">
{{ sortIndicator('vendor') }}
</div>
</th>
<td mat-cell *matCellDef="let element"> {{element.vendor}} </td>
</ng-container>
<ng-container matColumnDef="vendor_number">
<th mat-header-cell *matHeaderCellDef mat-sort-header="vendor_number">Vendor#
<div class="sort-indicator" [ngClass]="{ desc: sortDirection }">
{{ sortIndicator('vendor_number') }}
</div>
</th>
<td mat-cell *matCellDef="let element"> {{element.vendor_number}} </td>
</ng-container>
<ng-container matColumnDef="shopNumber">
<th mat-header-cell *matHeaderCellDef mat-sort-header="shopNumber">Shop#
<div class="sort-indicator" [ngClass]="{ desc: sortDirection }">
{{ sortIndicator('shopNumber') }}
</div>
</th>
<td mat-cell *matCellDef="let element"> {{element.shopNumber}} </td>
</ng-container>
<ng-container matColumnDef="po_date">
<th mat-header-cell *matHeaderCellDef mat-sort-header="po_date">PO Date
<div class="sort-indicator" [ngClass]="{ desc: sortDirection }">
{{ sortIndicator('po_date') }}
</div>
</th>
<td mat-cell *matCellDef="let element"> {{element.po_date}} </td>
</ng-container>
<ng-container matColumnDef="edit">
<th mat-header-cell *matHeaderCellDef>Edit</th>
<td mat-cell *matCellDef="let element"><a (click)="onEditClick(element)"
style="color:#4980B3">Edit</a></td>
</ng-container>
<ng-container matColumnDef="delete">
<th mat-header-cell *matHeaderCellDef>Delete</th>
<td mat-cell *matCellDef="let element">
<button mat-raised-button class="btn order-delete" color="danger"
(click)="onDeleteClick(element)" data-bs-toggle="modal"
data-bs-target="#deleteModal">Delete</button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<mat-paginator center="align" (page)="onPaginateChange($event)" [hidePageSize]="true"
[length]="totalRecords" [pageSize]="pageSize" showFirstLastButtons
[pageIndex]="poErrorRequestObj?.pageNo" class="mat-paginator mat-paginator-center"
aria-label="Select page of periodic elements">
</mat-paginator>
</div>
Component.ts
import { SelectionModel } from '@angular/cdk/collections';
import { Component, OnInit, ViewChild } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { MatPaginator, PageEvent } from '@angular/material/paginator';
import { MatSort, Sort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { DatePipe } from '@angular/common'
import { PoErrorsSearchDialogComponent } from '../po-errors-search-dialog/po-errors-search-dialog.component';
import { ActivatedRoute, Router } from '@angular/router';
import { PoErrorsService } from 'src/app/ordermanagement/services/po-errors.service';
import { HttpResponse } from '@angular/common/http';
import { mySaveSearch, poErrorData, poErrorsObject } from 'src/app/ordermanagement/models/po-errors';
import { Location } from '@angular/common';
import { SRSUser, SRSUserService } from 'srs-user-lib';
import { uniqBy } from 'lodash';
@Component({
selector: 'app-po-errors',
templateUrl: './po-errors.component.html',
styleUrls: ['./po-errors.component.scss']
})
export class PoErrorsComponent implements OnInit {
isButtonEnable: boolean = true;
selection = new SelectionModel<poErrorData>(true, []);
purchaseOrders: poErrorData[] = [];
mySaveSearchData: mySaveSearch[] = [];
isDeleteClicked: boolean;
poErrorRequestObj: poErrorsObject = {
message: '',
order: '',
orderBy: '',
pageNo: 0,
pageSize: 10,
po_number: '',
vendor: '',
vendor_number: ''
};
@ViewChild(MatSort) sort: MatSort;
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild('savedSearchPaginator') mySavedSearchPaginator: MatPaginator;
displayedColumns: string[] = ['select', 'po_number', 'message', 'vendor', 'vendor_number',
'shopNumber', 'po_date', 'edit', 'delete'];
mySaveSearchDisplayedColumns: string[] = ['name', 'addDate', 'select', 'delete']
dataSource = new MatTableDataSource(this.purchaseOrders);
currentSortColumn = 'select';
sortDirection = true;
showClearSearchButton: boolean;
totalRecords: number;
mySaveSearchTotalRecords: number;
message: any;
poErrorDeleteData: any[] = [];
isCheckBoxSelected: boolean = false;
mySaveSearchDataSource: any[] = [];
pageSize = 10;
pageNo = 0
mySavedSearchDeleteId: number
public changeTabIndex;
editedSearchName: {};
mySaveSearchList: any[] = [];
counter: number = 0;
currentPage = 0;
currentOrderBy = "po_date";
currentOrder = "desc"
isMySaveSearchEnable: boolean = false;
mySaveSearchId: number;
srsUser: SRSUser = undefined;
userProfileId: number;
masterCheckboxSelected = false;
selectedRows = [];
unSelectedRows = [];
userNavigatePages = {0: 1};
isAllCheckFlag:string='N';
constructor(
private dialog: MatDialog,
private _poService: PoErrorsService,
private srsUserService: SRSUserService,
private activatedRoute: ActivatedRoute,
private router: Router,
private location: Location,
public datepipe: DatePipe
) {
this.selection.changed.subscribe(item => {
this.isButtonEnable = this.selection.selected.length == 0;
})
}
ngOnInit(): void {
this.srsUserService.getUser().subscribe(user => {
this.srsUser = user;
this.userProfileId=this.srsUser.employeeId;
});
this.getPoErrorData();
this.dataSource.paginator = this.paginator;
if(this.location.getState()['statusCode']){
this.message = { statusCode: this.location.getState()['statusCode'],
statusText: this.location.getState()['statusText'] };
this.getPoErrorData();
}
}
ngAfterViewInit() {
this.dataSource.sort = this.sort;
}
// METHOD TO DISPLAY PO ERROR DATA IN TABLE
getPoErrorData() {
// this.selection.clear();
this.purchaseOrders = []
let filterCriteria = null;
if (this.location.getState() && this.location.getState()['filterCriteria']) {
filterCriteria = this.location.getState()['filterCriteria'];
this.currentOrder = filterCriteria['order'];
this.currentOrderBy = filterCriteria['orderBy'];
this.showClearSearchButton = true;
}
this.poErrorRequestObj.po_number = filterCriteria ? filterCriteria['po_number'] : this.poErrorRequestObj?.po_number || '';
this.poErrorRequestObj.vendor = filterCriteria ? filterCriteria['vendor'] : this.poErrorRequestObj?.vendor || '';
this.poErrorRequestObj.vendor_number = filterCriteria ? filterCriteria['vendor_number'] : this.poErrorRequestObj?.vendor_number || '';
this.poErrorRequestObj.message = filterCriteria ? filterCriteria['message'] : this.poErrorRequestObj?.message || '';
this.poErrorRequestObj.pageNo = this.currentPage;
this.poErrorRequestObj.pageSize = 10;
this.poErrorRequestObj.order = this.currentOrder;
this.poErrorRequestObj.orderBy = this.currentOrderBy;
if (this.poErrorRequestObj.vendor ||
this.poErrorRequestObj.vendor_number ||
this.poErrorRequestObj.po_number ||
this.poErrorRequestObj.message
) {
this.showClearSearchButton = true;
}
this.getPoData();
}
/**
* set poErrorRequestObj then,
* just the API call
*/
getPoData() {
this._poService.getPoErrorListData(this.poErrorRequestObj).subscribe(result => {
this.purchaseOrders = result.vendorOrderPOs;
this.totalRecords = result.totalRecords;
this.purchaseOrders?.forEach(element => {
const findRowToMakeSelected = this.selectedRows?.find(data => data.id == element.id);
if (findRowToMakeSelected) {
element['selected'] = true;
} else {
// element['selected'] = false;
if (this.userNavigatePages[this.currentPage] == 1) {
element['selected'] = this.masterCheckboxSelected;
if (this.masterCheckboxSelected) {
this.selectedRows.push(element);
}
}
}
});
this.dataSource = new MatTableDataSource(this.purchaseOrders);
this.selectedRows = uniqBy(this.selectedRows, 'id');
})
}
// METHOD TO DISPLAY MY SAVED SEARCH DATA
getAllMySaveSearchData(pageNo) {
const TYPE = "PURCHASE_ORDER_ERROR_SEARCH";
this._poService.getMySaveSearchData(this.userProfileId, TYPE, pageNo, this.pageSize).subscribe(result => {
this.mySaveSearchList = result.searchprofiles
this.mySaveSearchDataSource = result.searchprofiles;
this.mySaveSearchDataSource.forEach(element => {
element.isEdit = false;
element.displayError = false;
element.saveSearchName = "";
element.isEmpty = false;
})
this.mySaveSearchTotalRecords = result.totalRecords;
})
}
// METHOD TO CALL MY SAVE SEARCH TAB UPON SAVING SEARCH NAME
tabClick(event) {
if (event.index == 1) {
this.getAllMySaveSearchData(0);
}
}
onPaginateChange(event: PageEvent) {
this.currentPage = event.pageIndex;
/**
* userNavgatePages for handling pagination checkbox selection
*/
if (this.userNavigatePages[this.currentPage]) {
this.userNavigatePages[this.currentPage] += 1
} else {
this.userNavigatePages[this.currentPage] = 1;
}
if (this.isMySaveSearchEnable) {
this._poService.onSelectMySaveSearch(this.userProfileId, this.mySaveSearchId, event.pageIndex, this.pageSize).subscribe(result => {
this.changeTabIndex = 0;
this.purchaseOrders = result.vendorOrderPOs
this.totalRecords = result.totalRecords;
this.purchaseOrders?.forEach(element => {
const findRowToMakeSelected = this.selectedRows?.find(data => data.id == element.id);
if (findRowToMakeSelected) {
element['selected'] = true;
} else {
// element['selected'] = false;
if (this.userNavigatePages[this.currentPage] == 1) {
element['selected'] = this.masterCheckboxSelected;
if (this.masterCheckboxSelected) {
this.selectedRows.push(element);
}
}
}
});
this.selectedRows = uniqBy(this.selectedRows, 'id');
this.dataSource = new MatTableDataSource(this.purchaseOrders);
});
}
else {
this.poErrorRequestObj.pageNo = event.pageIndex;
this.getPoData();
}
}
onMySaveSearchPaginateChange(event: PageEvent) {
this.getAllMySaveSearchData(event.pageIndex)
}
// METHOD TO UPDATE THE SAVE SEARCH NAME
onEditSavaSearchClick(event) {
event.saveSearchName = event.name;
event.isEdit = true;
}
// METHOD TO CLEAR SAVE SEARCH NAME NAME AND DISPLAYS EXISTING NAME
clearMySaveSearchName(element) {
element.isEdit = false;
}
// METHOD TO RESTRICT CHARACTERS UPON REACHING MAX LIMIT
onEnterSearchName(element) {
if (element.saveSearchName != "") {
element.isEmpty = false;
}
if (element.saveSearchName.length >= 25) {
element.displayError = true
}
else {
element.displayError = false;
}
}
// ON SAVING MY SAVE SEARCH NAME UPON EDIT
onSavingMySaveSearchName(element) {
element.isEmpty = element.saveSearchName == "";
this.mySaveSearchList.forEach((data, index) => {
if (data.name == element.saveSearchName) {
this.counter++;
this.editedSearchName = element.saveSearchName + this.counter;
} else {
this.editedSearchName = element.saveSearchName;
}
})
let obj = {name: this.editedSearchName,type : ""}
this._poService.onSavingMySaveSearch(this.userProfileId, element.id, obj).subscribe(result => {
if (result == false) {
element.isEdit = false;
this.message = { statusCode: 200, statusText: "Name change saved!" }
this.getAllMySaveSearchData(this.pageNo);
}
})
}
//TO OPEN A SEARCH FLYOUT UPON CLICK
onSearch() {
this.isMySaveSearchEnable = false;
let dialogRef = this.dialog.open(PoErrorsSearchDialogComponent, {
width: '33%',
height: '100%',
})
dialogRef.afterClosed().subscribe((payload) => {
if (payload) {
this.poErrorRequestObj = payload.event;
this.showClearSearchButton = true;
this.purchaseOrders = payload.data.vendorOrderPOs;
this.totalRecords = payload.data.totalRecords;
this.purchaseOrders?.forEach(element => {
const findRowToMakeSelected = this.selectedRows?.find(data => data.id == element.id);
if (findRowToMakeSelected) {
element['selected'] = true;
} else {
// element['selected'] = false;
if (this.userNavigatePages[this.currentPage] == 1) {
element['selected'] = this.masterCheckboxSelected;
if (this.masterCheckboxSelected) {
this.selectedRows.push(element);
}
}
}
});
this.selectedRows = uniqBy(this.selectedRows, 'id');
this.dataSource = new MatTableDataSource(this.purchaseOrders);
this.dataSource.paginator = this.paginator;
}
})
}
onEditClick(event) {
this.router.navigate(['po-details'],
{
relativeTo: this.activatedRoute,
state: { event: event, totalRecords: this.totalRecords, filterParams: this.poErrorRequestObj }
});
}
// ON DELETE CLICK FROM PO ERROR TABLE
onDeleteClick(element) {
this.poErrorDeleteData = []
this.isDeleteClicked = true;
this.poErrorDeleteData.push(element.id);
}
// ON DELETE RECORD IN PO ERROR TABLE
onDeleteRecords() {
this.selectedRows.forEach(x => this.poErrorDeleteData.push(x.id));
this._poService.deletePoErrors(this.poErrorDeleteData).subscribe(response => {
this.poErrorDeleteData = [];
this.currentPage = 0;
this.getPoErrorData();
this.selectedRows= [];
this.message = { statusCode: 200, statusText: "Purchase order(s) successfully deleted" }
},
(error) => {
this.message = { statusCode: 400, statusText: "Failed to delete Purchase Order(s)" }
}
)
}
// ON DELETE MY SAVE SEARCH UPON CLICK
onDeleteMySaveSearchClick(element) {
this.mySavedSearchDeleteId = element.id;
}
// TO DELETE MY SAVE SEARCH DATA
onDeleteSaveSearch() {
console.log("hello")
this._poService.deleteMySaveSearchData(this.userProfileId, this.mySavedSearchDeleteId).subscribe(result => {
this.getAllMySaveSearchData(0);
this.mySavedSearchPaginator.firstPage();
this.message = { statusCode: 200, statusText: "Search successfully deleted from saved searches" }
},
(error) => {
this.message = { statusCode: 400, statusText: "Failed to Delete my Saved search" }
}
)
}
// TO DISPLAY SELECTED RECORD IN PO ERROR TABLE
onSelectMySaveSearchClick(element) {
this.mySaveSearchId = element.id
this._poService.onSelectMySaveSearch(this.userProfileId, this.mySaveSearchId, this.pageNo, this.pageSize).subscribe(result => {
this.changeTabIndex = 0;
this.isMySaveSearchEnable = true;
this.purchaseOrders = result.vendorOrderPOs;
this.totalRecords = result.totalRecords;
this.purchaseOrders?.forEach(element => {
const findRowToMakeSelected = this.selectedRows?.find(data => data.id == element.id);
if (findRowToMakeSelected) {
element['selected'] = true;
} else {
// element['selected'] = false;
if (this.userNavigatePages[this.currentPage] == 1) {
element['selected'] = this.masterCheckboxSelected;
if (this.masterCheckboxSelected) {
this.selectedRows.push(element);
}
}
}
});
this.selectedRows = uniqBy(this.selectedRows, 'id');
this.dataSource = new MatTableDataSource(this.purchaseOrders);
this.dataSource.paginator = this.paginator;
})
}
onClearSearch() {
this.showClearSearchButton = false;
if (this.location.getState()['filterCriteria']) {
this.location.getState()['filterCriteria'] = null;
}
this.poErrorRequestObj.message = '';
this.poErrorRequestObj.po_number = '';
this.poErrorRequestObj.vendor = '';
this.poErrorRequestObj.vendor_number = '';
this.currentPage = 0;
this.getPoData();
}
onSelectClick(element) {
}
sortIndicator(source: string): string {
if (source === this.currentSortColumn) {
return 'T';
} else {
return 'T';
}
}
sortTable(sort: Sort) {
this.currentOrderBy = sort.active;
this.currentOrder = sort.direction;
this.poErrorRequestObj.orderBy = this.currentOrderBy;
this.poErrorRequestObj.order = this.currentOrder;
this.getPoData();
}
// isAllSelected() {
// const numSelected = this.selection.selected.length;
// const numRows = this.dataSource.data.length;
// return numSelected === numRows;
// }
// masterToggle() {
// this.isAllSelected() ?
// this.selection.clear() :
// this.dataSource.data.forEach(row => this.selection.select(row));
// }
// selectAll() {
// if (this.selection.hasValue() && this.isAllSelected()) {
// this.dataSource.data.forEach(row => this.selection.select(row));
// } else {
// this.selection.clear();
// }
// }
unableDisableButton() {
if (this.selection.selected.length > 0 || this.selectedRows.length > 0) {
this.isButtonEnable = false;
} else {
this.isButtonEnable = true;
}
}
onSelectSingleCheckBox(row, event) {
if (event.checked) {
this.poErrorDeleteData.push(row.id)
} else {
this.poErrorDeleteData = this.poErrorDeleteData.filter(e => e !== row.id);
}
}
createNew() {
setTimeout(() => {
this.router.navigate(['/supplies/request-supplies'],
{
relativeTo: this.activatedRoute,
state: { tabIndex: 1}
});
}, 1000);
}
exportPOErrorRecords() {
this.isAllCheckFlag = this.masterCheckboxSelected ? 'Y' : 'N';
this._poService.exportPoErrors(this.masterCheckboxSelected ? this.unSelectedRows : this.selectedRows, this.isAllCheckFlag)
.subscribe(
(response: HttpResponse<Blob>) => {
let filename = "poErrors.csv";
let binaryData = [];
binaryData.push(response);
let downloadLink = document.createElement('a');
downloadLink.href = window.URL.createObjectURL(new Blob(binaryData, { type: 'text/csv' }));
downloadLink.setAttribute('download', filename);
document.body.appendChild(downloadLink);
downloadLink.click();
}
)
}
masterCheckBoxSelection() {
this.purchaseOrders?.forEach(element => {
element['selected'] = this.masterCheckboxSelected;
if (this.masterCheckboxSelected) {
this.selectedRows.push(element);
} else {
this.selectedRows = [];
this.unSelectedRows = [];
}
});
this.dataSource = new MatTableDataSource(this.purchaseOrders);
this.selectedRows = uniqBy(this.selectedRows, 'id');
this.unableDisableButton();
}
rowSelection(row, index) {
row['selected'] = !row.selected;
if (row.selected) {
const isPresentAlreadyInSelectedRows = this.selectedRows?.find(data => data.id == row.id);
if (!isPresentAlreadyInSelectedRows) {
this.selectedRows.push(this.dataSource.filteredData[index]);
}
this.unSelectedRows = this.unSelectedRows.filter(data => data?.id !== row?.id);
} else {
this.selectedRows = this.selectedRows.filter(data => data.id !== row.id);
this.unSelectedRows.push(row);
}
this.selectedRows = uniqBy(this.selectedRows, 'id');
this.unableDisableButton();
}
}
If anyone can help me how to solve this issue.
Expected result : even if i have checked mastercheckbox on any page whether it 1st ,2nd ,5th or last second page all checkbox sholud get selected by default and if i manually deselect any checkbox then it should be deselect . Currently it is working when i have select master checkbox on 1st page.