Zlatko
Zlatko

Reputation: 19569

How to prevent tab selection on ngx-bootstrap

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).

Upvotes: 5

Views: 8178

Answers (2)

IlyaSurmay
IlyaSurmay

Reputation: 2333

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);
    }
  }
}

Upvotes: 5

Vivek Doshi
Vivek Doshi

Reputation: 58573

Issue here is :

@ViewChild('first') first: TabDirective;

Not pointing to the TabDirective but just native ElementRef , so this.second.active = true; will not make TabDirective active.

You can achevie that simply using this.tabset.tabs[index].active = true;

WORKING DEMO

Upvotes: 0

Related Questions