I want to hold, the changing of MatTab
until a confirmation is given. I have used MatDialog
for confirmation. The issue is, before clicking "Yes", the the tab is already changed.
For example, From income tab, I click adjustment tab. And before switching to that tab, I need to show the popup first. But I am getting the popup after moving to adjustment tab.
component template:
<mat-tab-group (click)="tabClick($event)">
<mat-tab *ngFor="let tab of tabs; let index = index" [label]="tab">
<app-spread></app-spread
</mat-tab>
</mat-tab-group>
component ts (onClick's method):
tabClick(clickEvent: any) {
if (clickEvent.target.innerText != 'First') {
this.confirm();
}
}
public async confirm() {
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
maxHeight: '200px',
maxWidth: '767px',
width: '360px',
disableClose: true,
data: {
title: 'Confirmation Message',
content:
'There are valid statements that are not Final. Set the statements as Final?'
}
});
const res = dialogRef.afterClosed().subscribe(result => {
if (result === 1) {
//TODO need to change the tab
} else {
//TODO no need to change the tab
}
});
}
Sometime ago I simulate a "mat-tab" in this SO
I Imagine that you can use this with only change the function
<mat-tab-group #tabgroup style="margin-bottom:5px;"
animationDuration="0" mat-align-tabs="start"
(selectedIndexChange)="change(tabgroup,$event)">
...
</mat-tab-group>
And the function change:
change(tab:any,index:number)
{
if (tab.selectedIndex!=this.indexOld){
const dialogRef = this.dialog.open(....)
const res = dialogRef.afterClosed().subscribe(result => {
if (result === 1) {
this.index=index;
} else {
tab.selectedIndex=this.indexOld;
}
});
}
else
{
this.index=index;
}
}
See the stackblitz -in the stackblitz I simple use the confirm dialog-
Update problem if we use a mat-dialog.
There's another approach that it's overwrite the behaviour of the mat-tab-group
We need change the _handleClick
function of the mat-tab-group, (see this function in github) and the function _handleKeydown
of the mat-header (see this function in github
It's a bit complex, but the only is get the mat-group using ViewChild
(I use {static:true}
because my tabgroup is visible always.
@ViewChild('tabgroup', { static: true }) tabgroup: MatTabGroup;
Then, in ngOnInit (if it's not static:true, we use ngAfterViewInit), simply redefine the function. for this first "cast" to any this.tabgroup
First we makes a function alertDialog
alertDialog(index:number,tab:MatTab,tabHeader:any,)
{
const dialogRef = this.dialog.open(DialogOverviewExampleDialog, {
data: {},
});
const res = dialogRef.afterClosed().subscribe((result) => {
if (result) {
tabHeader.focusIndex = index;
if (!tab.disabled) {
this.tabgroup.selectedIndex = index;
}
}
});
}
Then, in ngOnInit we write
ngOnInit(){
(this.tabgroup as any)._handleClick = (
tab: MatTab,
tabHeader: any,
index: number
) => {
if (this.tabgroup.selectedIndex != index)
this.alertDialog(index, tab, tabHeader);
};
}
To override the _handleKeydown
we are enclosed all in setTimeout to give time to Angular to paint the mat-tab-header
ngOnInit() {
....
setTimeout(() => {
const tabHeader = (this.tabgroup as any)._tabHeader;
tabHeader._handleKeydown = (event: KeyboardEvent) => {
if (hasModifierKey(event)) {
return;
}
switch (event.keyCode) {
case ENTER:
case SPACE:
if (tabHeader.focusIndex !== tabHeader.selectedIndex) {
const item = tabHeader._items.get(tabHeader.focusIndex);
this.alertDialog(tabHeader.focusIndex, item, tabHeader);
}
break;
default:
tabHeader._keyManager.onKeydown(event);
}
};
});
You can see in a new stackblit