Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Material Tab Group - prevent tab change

I use the Angular Material Tabs and need a hook to check if the user can change the tab (form is un/saved). I couldn't find any API functionality to prevent the tab change. Any ideas? Thanks

like image 848
Lord Midi Avatar asked Mar 07 '19 09:03

Lord Midi


Video Answer


2 Answers

I used the solution from AlessHo, however it didn't work for me that way. I had to change the function assigned to _handleClick, returning a boolean didn't do the trick.

Here's my solution:

Add @ViewChild(MatTabGroup) tabs: MatTabGroup; to the class.

Note the type parameter in place of the #tabGroup reference. It worked with it as well, but our tests didn't. tabs was undefined in the tests, but it worked with the type selector.

Next, I implemented AfterViewInit, because in the OnInit, the tab group was not reliably initialized:

ngAfterViewInit(): void {

    // Just to be sure
    if (!this.tabs) {
        throw Error('ViewChild(MatTabGroup) tabs; is not defined.');
    }

    // Returning just a boolean did nothing, but this works:

    // 1. Save the click handler for later
    const handleTabClick = this.tabs._handleClick;

    // 2. Replace the click handler with our custom function
    this.tabs._handleClick = (tab, header, index) => {

        // 3. Implement your conditional logic in canDeactivateTab()
        // (return the boolean here)
        if (this.canDeactivateTab()) {

            // 4. If the tab *should* be changed, call the 'old' click handler
            handleTabClick.apply(this.tabs, [tab, header, index]);
        }
    };
}
like image 95
Emaro Avatar answered Oct 13 '22 14:10

Emaro


I was facing the same issue. In my case I would not allow the user to move to another tab until he fills all mandatory details.

Finally I found something here different from (selectedTabChange)="tabChanged($event)" which is the one that has been used:

  1. Add @ViewChild('tabGroup') tabs: MatTabGroup; in your class;
  2. add #tabGroup to <mat-tab-group #tabGroup> .. </mat-tab-group> in your HTML code.
  3. Add import {MatTabGroup, MatTab, MatTabHeader } from '@angular/material'; to your class;
  4. Add this.tabs._handleClick = this.myTabChange.bind(this); in ngOnInit function;
  5. Add below function which allows tab change or not, and is able to get the tab index number:
myTabChange(tab: MatTab, tabHeader: MatTabHeader, idx: number) {    
    var result = false;    
    // here I added all checks/conditions ; if everything is Ok result is changed to true
    // ==> this way the tab change is allowed.
    return result;    
}

Cheers !

like image 1
AlessHo Avatar answered Oct 13 '22 15:10

AlessHo