Angular Material Tab : Prevent tab change of mat-tab-group if the form in current tab is dirty

前端 未结 1 965
天涯浪人
天涯浪人 2020-12-07 04:07

I was trying to prevent tab change of mat-tab, if the form in currently active tab is dirty.

But I couldn\'t find a way to intercept the tab change even

相关标签:
1条回答
  • 2020-12-07 04:37

    This solution is just a hack and has its flaws. It is mentioned below.

    Steps :

    In the template :

    1. Disable all tabs of the mat-tab-group <mat-tab label="Tab 0" disabled>
    2. Provide a click event handler on mat-tab-group. Also set the selectedIndex property using a variable from the component class.

      <mat-tab-group (click)="tabClick($event)" [selectedIndex]="selectedTabIndex">

    In the Component class :

    1. Declare the variable selectedTabIndex
      selectedTabIndex = 0;

    2. Create a method to get the tab Index , provided the tab label.

      getTabIndex(tabName: string): number {
      
      switch (tabName) {
        case 'Tab 0': return 0;
        case 'Tab 1': return 1;
        case 'Tab 2': return 2;
        default: return -1; // return -1 if clicked text is not a tab label text
       }
      
      }
      

      We can get the tab-label text from a property of the click event

      clickEventName.toElement.innerText

    3. Create the method for handling the click event on mat-tab-group.

      tabClick(clickEvent: any) {
      
      // Get the index of clicked tab using the above function
      const clickedTabIndex = this.getTabIndex(clickEvent.toElement.innerText);
      
      // if click was not on a tab label, do nothing
      if (clickedTabIndex === -1) {
        return;
      }
      
      // if current tab is same as clicked tab, no need to change. 
      //Otherwise check whether editing is going on and decide
      
      if (!(this.selectedTabIndex === clickedTabIndex)) {
      
        if ( /*logic for form dirty check*/ ) {
      
          // if form is dirty, show a warning modal and don't change tab.
        }
        else {
      
          // if form is not dirty, change the tab
          this.selectedTabIndex = clickedTabIndex;
        }
      }
      

      }

    In my case each tab content was in separate components. So I used @ViewChild to access them and check whether any of the form is dirty or not.

    Flaws :

    1. Since this method uses the text of clicked element for switching tabs, there is a chance that one of your tab may contain some element with text content same as the heading of other tabs.

      So it may trigger a tab change. You can look for other properties in click event to prevent this scenario if possible. I used following code in tabClick() method's beginning

      if (!((clickEvent.toElement.className).toString().includes('mat-tab-label'))) {
       return;
       }
      
    2. You may need to override the css of disabled state of mat-tab to make it look natural

    Template :

    <mat-tab-group  (click)="tabClick($event)" [selectedIndex]="selectedTabIndex">
    
      <mat-tab label="Tab 0" disabled>
    
        // Tab 0 Content
    
      </mat-tab>
    
      <mat-tab label="Tab 1"  disabled>
    
        // Tab 1 Content
    
      </mat-tab>
    
      <mat-tab label="Tab 2"  disabled>
    
        // Tab 2 Content
    
      </mat-tab>
    
    </mat-tab-group>
    
    0 讨论(0)
提交回复
热议问题