3

I have a set of tabs that I create dynamically, dependent on my input data. And what I want to do is to be able to figure out which tab is currently selected. In the example code below, I have a tab control and beneath all this, I have a button that when clicked will delete the selected tab. I've tried to keep this relatively simple and it might seem contrived, but I hope it does to illustrate what I mean.

Here's my code:

<div class="col-md-12">
  <ngb-tabset *ngIf="selectedInfo" type="groups" >
    <ngb-tab *ngFor="let tab of selectedInfo.groups" title={{tab.name}} >
        // some stuff in the tabs
    </ngb-tab>
  </ngb-tabset>
</div>

<div>
  <button class="btn btn-primary float-left" (click)="deleteTab()" > Delete Tab </button>
</div>


export class MyTabs implements OnInit {

  selectedIfno: MyInfoClass;

  ngOnInit(): void {

    // init data

  }

  deleteTab() {


  }

}

So let's say I want to delete the currently selected tab. How do I know what tab is currently selected?

WebDevBooster
  • 14,674
  • 9
  • 66
  • 70
user2477533
  • 201
  • 1
  • 2
  • 10

2 Answers2

15

I would suggest listening to the tabChange change event - this would allow you to "intercept" all the cases where the active page changes and store info about the currently selected tab. Here is the sketch of the idea:

<ngb-tabset [activeId]="activeTab" (tabChange)="activeTab = $event.nextId"> ... </ngb-tabset>

And a working plunker: http://plnkr.co/edit/4vRDHgWMhcvafXhQkxEO?p=preview

While typing the answer I've realized that keeping track of the active tab yourself might be a bit of pain and we could add this functionality to the tabset itself. Feel free to open a feature request at https://github.com/ng-bootstrap/ng-bootstrap/issues

pkozlowski.opensource
  • 117,202
  • 60
  • 326
  • 286
7

You can get the active tab id (activeId) for NgbTabset using Angular @ViewChild() to retrieve an instance of the the NgbTabset from the HTML. You'd then have access to the activeId in the class methods. Considering you are us *ngIf you may need to create a setter for @ViewChild() described in this question. I've updated the example to use the setter.

HTML:

<div class="col-md-12">
  <ngb-tabset #t="ngbTabset" *ngIf="selectedInfo" type="groups">
    <ngb-tab *ngFor="let tab of selectedInfo.groups" title={{tab.name}} >
        // some stuff in the tabs
    </ngb-tab>
  </ngb-tabset>
</div>

TS:

import { Component, ViewChild, ViewContainerRef } from '@angular/core';
import { NgbTabset } from '@ng-bootstrap/ng-bootstrap';

export class MyTabs implements OnInit {
  private tabSet: ViewContainerRef;

  @ViewChild(NgbTabset) set content(content: ViewContainerRef) {
    this.tabSet = content;
  };

  ngAfterViewInit() {
    console.log(this.tabSet.activeId);
  }

  deleteTab() {
    // currently selected tab id
    console.log(this.tabSet.activeId);
  }
}

Here is a plunker demonstrating the functionality.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Alexander Staroselsky
  • 37,209
  • 15
  • 79
  • 91
  • i'm unable to do the following: this.tabSet = content in the @ViewChild part.... not sure why at the minute, but i can see how all this should be working. – user2477533 Jul 25 '17 at 19:37
  • You are getting an error? The `*ngIf` may be preventing `@ViewChild()` from finding the element on load. – Alexander Staroselsky Jul 25 '17 at 19:39
  • Yes, i get an error at compile time: `Type 'ViewContainerRef' is not assignable to type 'NgbTabset'. Property 'tabs' is missing in type 'ViewContainerRef'.` Thanks very much for your help! – user2477533 Jul 25 '17 at 19:43
  • ` @ViewChild(NgbTabset) set content(content: ViewContainerRef) { this.tabSet = content; };` It is taken precisely the same as above. – user2477533 Jul 25 '17 at 19:46
  • Sorry, change to private tabSet: ViewContainerRef. Or have both be the NgbTabset. Typing error. – Alexander Staroselsky Jul 25 '17 at 19:49