1
votes

I have a mat-tab group with different tabs. I want to detect click on the active tab header.

Eg. I have 2 tabs- a company tab and a users tab and inside each tab there are 2 views - a list view view and a detailed view. Initially I want to load the list and on clicking on an item, want to go to the corresponding item's detailed view. But If I click on the tab header again I want to goto the list view again.

There are events like (selectedTabChange) which detects if tab is changed but since I am inside the same tab, it is not getting emitted. Any help.?

<mat-tab-group class="theme-specific-tabs account-page-tabs" [(selectedIndex)]="selectedTab"  (selectedIndexChange)="accountTabOnIndexChange($event)">
4

4 Answers

2
votes

This is a hack, but it should work. Note that the setTimeout() call is necessary because it seems like the tab change happens before the click event gets to our callback, so we need to delay saving the selected tab index until the click event has completed propagation. That is also why we can't simply check for the active tab index from MatTab.

<mat-tab-group (selectedIndexChange)="selectedIndexChange($event)" (click)="tabClick($event)">
  <mat-tab label="Tab 1">Content 1</mat-tab>
  <mat-tab label="Tab 2">Content 2</mat-tab>
</mat-tab-group>


selectedTabIndex: number = 0;
selectedIndexChange(index: number) {
  setTimeout(() => this.selectedTabIndex = index);
}

tabClick(event: MouseEvent) {
  let el = event.srcElement;
  const attr = el.attributes.getNamedItem('class');
  if (attr.value.indexOf('mat-tab-label-content') >= 0) {
    el = el.parentElement;
  }
  const tabIndex = el.id.substring(el.id.length - 1);
  if (parseInt(tabIndex) === this.selectedTabIndex) {
    // active tab clicked
    console.log(tabIndex);
  }
}

Here it is on stackblitz.

1
votes

onTabGroupClicked(event) {
    if (this.prevTabIndex === this.activeTabIndex) {
      // current active tab clicked!
    } else {
      // another tab clicked!
    }

    this.prevTabIndex = this.activeTabIndex;
    
  }
<mat-tab-group [(selectedIndex)]="activeTabIndex" (click)="onTabGroupClicked()">
0
votes

Update answer of G. Tranter for Angular 8 and my case (sometimes click get into inner element):

<mat-tab-group (selectedIndexChange)="onTabChange($event)" (click)="tabClick($event)">
  <mat-tab label="Tab 1">Content 1</mat-tab>
  <mat-tab label="Tab 2">Content 2</mat-tab>
</mat-tab-group>

onTabChange(event: MatTabChangeEvent) {
    setTimeout(() => {
        this.selectedTabIndex = event.index;
    });
}

tabClick(event: MouseEvent) {
    let el = event.target as Element;
    let index: number;

    if (el.classList.contains("mat-tab-label")) {
        index = +el.id.substring(el.id.length - 1);
    }
    const ppEl = el.parentElement.parentElement
    if (ppEl.classList.contains("mat-tab-label")) {
        index = +ppEl.id.substring(ppEl.id.length - 1);
    }
    if (index === this.selectedTabIndex) {
        console.log("click on selected");
    }

}
0
votes

Although late at the party - nevertheless an approach based on the documentation (isActive). You could simply add the tab you are interested in an id, e.g.

<mat-tab #secondTab>

and than evaluate the status, e.g. {{secondTab.isActive}}. Here is a working full sample. Watch the second tab - it changes the icon and the title!