Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to select NgbTabset tab as active on load?

The "Select an active tab by id" example at https://ng-bootstrap.github.io/#/components/tabs shows how to use a DOM button to programmatically select an Angular Bootstrap tab to be active. But how do you set a tab to be active from within the TypeScript code - for example by referencing some persistent state of what tab was most recently open on this view using a service that stored the state?

The activeId documentation on that page explains how to hard-code a tab to be active, but I need to set the tab choice programmatically. I can set the tab using [activeId] = getActiveId() (where getActiveId() accesses a service in which I can store the tab value), but that gets into all sorts of issues with when the activeId is set, which is presumably why the documentation says "Use the "select" method to switch a tab programmatically".

Following this direction I tried using select on the ngb-tabset and using the html onload event to solve this in the DOM, but was unclear where to place onload and I couldn't get this to work.

I tried using ngOnInit in the TypeScript to set the DOM state but couldn't figure out how to refer to the ngb-tabset.

What is a good way to coordinate between the TypeScript and the DOM to select NgbTabset tab as active on load?

like image 210
Mickey Segal Avatar asked Jul 10 '17 15:07

Mickey Segal


2 Answers

I figured out how to get this to work, but I am undecided as to whether it is a kludgy workaround or an elegant solution.

I ended up going against the advice at https://ng-bootstrap.github.io/#/components/tabs/api, which said "Use the "select" method to switch a tab programmatically". I did use activeId, with the core code being:

<ngb-tabset [activeId]="activeIdString">

[activeId] binds to a variable activeIdString, not a method as I described in the original post (using a getActiveId() method instead of a variable results in the "Expression has changed after it was checked" error message, which although it is a development mode only error, as described at https://github.com/angular/angular/issues/6005, is still a problem.)

The variable activeIdString is set when the component initializes:

  ngOnInit(): void {
    this.activeIdString = this.tabNameString[this.personService.getNextTab()];
  }

Since this code is on the component with the tabs, I record mostRecentTab on this component and convert it to nextTab on the navigation component before reaching the component with tabs, getting rid of any need to pay attention to exactly when ngOnInit executes in relation to when I record mostRecentTab.

A discussion "Cannot programmatically select tab" at https://github.com/ng-bootstrap/ng-bootstrap/issues/1016 also suggests using activeId, so I feel some confidence in disregarding the advice on https://ng-bootstrap.github.io/#/components/tabs/api to "Use the "select" method to switch a tab programmatically".

like image 71
Mickey Segal Avatar answered Nov 06 '22 06:11

Mickey Segal


Somehow those answers didnt work, so I found another solution. An easier one. I hope it helps someone. Just follow these steps:

1. Give your tabset a 'tabset' identifier:

<ngb-tabset #tabset="ngbTabset"> many tabs... </ngb-tabset>

2. Give every <tab> in your <tabset> an unique id

<ngb-tab id="tab1"> Tab 1 </ngb-tab>
<ngb-tab id="tab2"> Tab 2 </ngb-tab>
<ngb-tab id="tab3"> Tab 3 </ngb-tab>

3. Declare a @ViewChild for your tabset

@ViewChild('tabset')
tabset: any;

4. Set active tab inside ngAfterViewInit (not ngOnInit, that's too early!)

this.tabset.select('tab3');

Works perfectly for me. Sorry for strange formatting, Stack Overflow doesnt work properly sometimes.

like image 36
IonicMan Avatar answered Nov 06 '22 06:11

IonicMan