3

i want to conditionally prevent user from navigating to other tab in mat-tab-group. I found one monkey patching here How to conditionally prevent user from navigating to other tab in mat-tab-group. But i want to implement this using mat-tab-group API. Can I implement this using focusChange event or event.preventDefault or any other way.

Here is the example https://stackblitz.com/edit/angular-mat-tab-focuschange-tphyvw

c1992
  • 189
  • 4
  • 12
  • https://stackoverflow.com/questions/56607394/angular-material-tab-prevent-tab-change-of-mat-tab-group-if-the-form-in-curren – jophab May 22 '20 at 15:08

2 Answers2

2

it is easily achievable by using @Output() selectedIndexChange: EventEmitter<number> to catch tab change attempts and using @Input() selectedIndex: number | null to set active tab (and set to current tab index if you don't want new index to get selected)

<mat-tab-group #mtg (selectedIndexChange)="selectedIndexChange($event)">
  <mat-tab *ngFor="let tab of tabs; let index = index" [label]="tab">
    Contents for {{tab}} tab
  </mat-tab>
</mat-tab-group>
  @ViewChild("mtg") tg: MatTabGroup;
  tabs = ['First', 'Second', 'Third', "Fourth"];
  current = 0;

  selectedIndexChange(evt: any) {
    if (evt % 2) {
      this.tg.selectedIndex = this.current;
      console.log("You cannot select even numbered tabs, sorry ^_^");
    } else {
      this.current = evt;
    }
  }

here is a working demo

ysf
  • 4,634
  • 3
  • 27
  • 29
  • this solution won't work as it'll recall the selectedIndexChange function again because of this.tg.selectedIndex = this.current – c1992 Jun 26 '19 at 15:12
  • it is correct that it will cause a new emission on `selectedIndexChange`. however, for the example above it works because there is no side effect of calling `selectedIndexChange(evt: any)` twice in my example. it may cause side effects depending on your use case but it is easily preventable by adding `if(evt === this.current) return;` on top of `selectedIndexChange(evt: any)` method. see it in action [here](https://stackblitz.com/edit/angular-mat-tab-focuschange-fzhdck) – ysf Jun 26 '19 at 15:23
  • In my case, if(evt === this.current) return; will also not work – c1992 Jun 26 '19 at 17:30
  • why not? what is your use case? please, give some more details regarding your use case and why it doesn't work. – ysf Jun 26 '19 at 17:33
1

If you want to conditionally prevent the user from moving to a specific tab, you could just disabled the tab based on this condition. Letting the user click the tab and then somehow trying to prevent it, doesn't seem like a good solution to me.

Let's say you wanted to disable the tab with the index 1:

<mat-tab-group (focusChange)="show()" [selectedIndex]="selected.value"
               (selectedIndexChange)="selected.setValue($event)">
  <mat-tab *ngFor="let tab of tabs; let index = index" [label]="tab" [disabled]="index === 1">
    Contents for {{tab}} tab
  </mat-tab>
</mat-tab-group>

Ideally you would define an interface for your tabs, add a property (for example disabled) and based on that property set the disabled state of the tab. This lets you easily enable/disable a tab.

Fabian Küng
  • 5,925
  • 28
  • 40
  • I know how to disable tab. but, In my requirement, when user click the tab, then it should check the condition. – c1992 Jun 26 '19 at 15:11