ngx-bootstrap: fix(tabs): order not working with ngIf\dynamic directives

I have been using tab directive.Additionally i used ngIf directive inside tab selector.Everything is right.But tab order not regular.It is not order as I want .Here my code:

<tabset [justified]="true">
  <tab (select)="showCustomer()" *ngIf="isRoleCustomer" >
    <template tabHeading>Customers</template>
    <customers></customers>
  </tab>
  <tab (select)="showProgram()" *ngIf="isRoleProgram">
    <template tabHeading>Programs</template>
    <programs [role]="_isRole"></programs>
  </tab>
  <tab (select)="showMessage()" >
    <template tabHeading>Message Templates</template>
    <message-templates></message-templates>
  </tab>
</tabset>

This is tab order as (message | customers | programs) in this code.But i want to be like (customers| programs| messages) of tab order.So is there any order input property like tabIndex and tabOrder.

About this issue

  • Original URL
  • State: open
  • Created 8 years ago
  • Reactions: 13
  • Comments: 30

Commits related to this issue

Most upvoted comments

Below is a directive which you can use to specify tab order. Instead of relying on id field which might be used for something else, it “patches” the object with __tabOrder property.

@Directive({
    selector: '[tabOrder]'
})
export class TabOrderDirective implements OnChanges {

    @Input() tabOrder = 0;

    constructor(private tab: TabDirective) { }

    ngOnChanges() {
        (this.tab as any).__tabOrder = +this.tabOrder;
        this.tab.tabset.tabs.sort((a: any, b: any) => a.__tabOrder - b.__tabOrder);
    }
}

usage:

<tab heading="Tab 1" tabOrder="1">
<tab heading="Tab 2" tabOrder="2">

As a workaround, just add *ngIf=“true” to any tab elements that don’t have an *ngIf. Issue seems to be lifecycle related.

+1 same issue, I don’t see any ‘index’ functionality that was previously mentioned either.

+1 I tried the *ngIf=“true” word around but it didn’t work.

I have done working workaround using customClass and adding ‘_HIDDEN’ sufix to my customClass <tab customClass="MY_CLASS_NAME{{!show ? '_HIDDEN' : ''}}"> Class MY_CLASS_NAME_HIDDEN has just: display: none !important;

Important: When you need to show/hide 1st tab, you need to control tab [active] property on your tabs, because when you will hide 1st tab that was active, it will look like no tab is active.

has tvoloshyn’s solution been considered for production?

I’ve found one solution for today. It doesn’t look like a good solution but as is.

  • you have declare the tabset component element in your class
import { TabsetComponent } from 'ngx-bootstrap/tabs';
....
@ViewChild('someTabs') someTabs: TabsetComponent;
  • and then you can sort the tabs manually when you need. For example like here (with lodash)
this.someTabs.tabs  = _(this.someTabs.tabs).sortBy(t => +t.elementRef.nativeElement.id).value();

I have a tab component inspired by this. I ended up sorting the tabs by id upon ceration. Something in the lines of:


  addTab(tab: TabComponent) {
    const insertPos = this.tabs.findIndex(aTab => aTab.id > tab.id);
    if (insertPos >= 0) {
      this.tabs.splice(insertPos, 0, tab);
    } else {
      this.tabs.push(tab);
    }
  }

Just had to move the addTab invocation from the constructor to ngOnInit to get the id

I wonder if there’s anything less intrusive to know the relative positions of the tabs… ElementRef ?

The solution provided by @romanszedzielorz is the only one working - adding *ngIf to all tabs works only until a change to *ngIf condition is detected in the middle element - if it is the case, if condition is true, tab is moved to the end instead staying in the place as declared. Index does not work. Please consider it a serious problem as any dynamic tabs declared other than items in a list are not handled correctly.