Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent tab selection on ngx-bootstrap

Tags:

I have two tabs with ngx-bootstrap like bellow, and I want to programatically stop tab functionality rom working:

<tabset>
    <tab heading="First">Tab 1 content</tab>
    <tab heading="Second">Tab 2 content</tab>
</tabset>

<label>Edit in progress: </label>
<input type="checkbox" [(ngModel)]="isTabSwitchEnabled">

Basically, if I have a dirty form in, say, Tab 1, I want to popup a "Discard changes?" dialog before allowing the user to "navigate" to Tab 2. I see nothing on the ngx-bootstrap tabs API that I could use.

I have an example Stackblitz where I tried working with [disabled] on tabs, and it works partways, but not fully, because I cannot set the tab programatically active (or I don't know how):

export class MyComponent  {
  disableSwitching: boolean;
  @ViewChild('tabset') tabset: TabsetComponent;
  @ViewChild('first') first: TabDirective;
  @ViewChild('second') second: TabDirective;

  confirmTabSwitch($event) {
    if (this.disableSwitching) {
      const confirm = window.confirm('Discard changes and switch tab?');
      if (confirm) {
        this.disableSwitching = false;
        this.second.active = true;
      }
    }
  }

}

The this.second.active = true doesn't switch to the new tab, only marks it active. The same if I try with this.tabset.tabs[index].active = true;.

Is there a way to have this functionality? Enable and disable switching tabs? Ideally bind it to a router too (but I definitely need programatic access).

like image 901
Zlatko Avatar asked Feb 05 '18 15:02

Zlatko


1 Answers

Here's a working stackblitz example - https://stackblitz.com/edit/ngx-bootstrap-tabs-rs832l?file=app/app.component.ts

The thing here is that select event emits before tabset sets active property of all other tabs to false so you need to wrap the code that selects a tab in a setTimeout or something like that. This will set the active tab after all internal operations of the tabset.

Edit: as the OP says, at current ([email protected]) the workaround is to find the matching element on the tabset component and activate:

confirmTabSwitch($event) {
  if (this.disableSwitching) {
    const confirm = window.confirm('Discard changes and switch tab?');
    if (confirm) {
      this.disableSwitching = false;
      const liArr = Array.from(this.tabsetEl.nativeElement.querySelectorAll('ul li'));
      let tabIndex;
      liArr.forEach((li, i) => {
        if(li.contains($event.target)) {
          tabIndex = i;
        }
      });
      setTimeout(() => this.tabset.tabs[tabIndex].active = true);
    }
  }
}
like image 198
IlyaSurmay Avatar answered Sep 19 '22 12:09

IlyaSurmay