Search code examples
angularangular-router

Angular 8 with Material tabs - select last active tab on reload


Using the following example:

Example

How can I activate the last selected tab when a page is reloaded? Is there a design pattern of doing it?

Thanks


Solution

  • This is a simple, naive hard-coded version:

    <mat-tab-group [selectedIndex]="1">
      <mat-tab label="system" routerLink="syspref"> Default Preferences </mat-tab>
      <mat-tab label="user" routerLink="userpref"> User Preferences </mat-tab>
    </mat-tab-group>
    

    To make it more generic you would need to have some programmatic way of knowing how many tabs you have. For example, if you were building your tabs from an array.

    <mat-tab-group [selectedIndex]="tabs.length - 1">
      <mat-tab *ngFor="let tab of tabs" [label]="tab.label" [routerLink]="tab.link">{{tab.name}}</mat-tab>
    </mat-tab-group>
    

    Where tabs is an array of objects with appropriate property names.

    Edit:

    You want to persist the active tab across page reloads.

    The general pattern that I follow for this is:

    1. On tab change, add index to query params
    2. On page load, find index in query params
    3. If valid, set active tab index

    component

    constructor(private route: ActivatedRoute,
      private router: Router) {}
    
    selectedTabIndex: number;
    
    ngOnInit(): void {
      this.selectedTabIndex = parseInt(this.route.snapshot.queryParamMap.get('tab'), 10);
      // TODO: check upper bound. Material will set the last tab as selected
      // if selectedTabIndex >= number of tabs
      if (isNaN(this.selectedTabIndex) || this.selectedTabIndex < 0) {
        this.selectedTabIndex = 0;
      }
    }
    
    onTabChange(selectedTabIndex: number): void {
      this.router.navigate([], { relativeTo: this.route, queryParams: {
        tab: selectedTabIndex
      }});
      this.selectedTabIndex = selectedTabIndex;
    }
    

    html

    <mat-tab-group [selectedIndex]="selectedTabIndex" 
      (selectedIndexChange)="onTabChange($event)">
      <mat-tab label="system" routerLink="syspref"> Default Preferences </mat-tab>
      <mat-tab label="user" routerLink="userpref"> User Preferences </mat-tab>
    </mat-tab-group>