Search code examples
angularangular2-components

Angular 2 changing tabs dynamically


I have created a tabs component which is working fine. I'd like to support changing tabs programatically, however I'm not sure how to go about it.

Here's the code that I have so far...

Tab Component

@Component({
    selector: 'tabs',
    template: `
        <ul>
            <li *ngFor="let tab of tabsMenu" (click)="tabClick(tab)" [class.active]="tab.index === activeTabIndex">
                {{ tab.title }}
            </li>
        </ul>
        <div>
            <ng-content select="tab-content"></ng-content>
        </div>
    `
})

export class TabsComponent implements AfterViewInit {
    @Input() tabsMenu: MenuItem[];
    @Input() activeTabIndex: number = 0;

    @ContentChildren(TabContentComponent) tabsContent: QueryList<TabContentComponent>;
    private tabsContentComponents: TabContentComponent[] = [];

    ngAfterViewInit() {
        this.tabsContentComponents = this.tabsContent.toArray();
        this.setActiveTab(this.activeTabIndex);
    }

    tabClick(tab: MenuItem) {
        this.activeTabIndex = tab.index;
        this.setActiveTab(tab.index);
    }

    private setActiveTab(index: number) {
        this.tabsContentComponents.filter((temp) => {
            temp.activeTabIndex = this.activeTabIndex;
        });
    }
}

Tab Content Component

@Component({
    selector: 'tab-content',
    template: `
        <div [hidden]="tabIndex !== activeTabIndex">
            <ng-content></ng-content>
        </div>
    `
})

export class TabContentComponent {
    @Input() tabIndex: number;
    activeTabIndex: number = 0;
}

Example of the code being used

@Component({
    selector: 'example',
    template: `
        <tabs [tabsMenu]="tabs">
            <tab-content>
                Tab 1
            </tab-content>
            <tab-content>
                Tab 2
            </tab-content>
            <tab-content>
                Tab 3
            </tab-content>
         </tabs>
    `
})

export class TabContentComponent {
    tabs: MenuItem[] = [
        new MenuItem(0, 'Tab 1'),
        new MenuItem(1, 'Tab 2'),
        new MenuItem(2, 'Tab 3')
    ];
}

What I'm trying to do now is have a button inside a tab-content component that redirects to another tab. I'm not entirely sure how I'm to change the activeTabIndex inside the TabComponent to be able to access a different tab.


Solution

  • One good idea in general would be taking a look at the material2 from that amazing angular-team! :)

    https://github.com/angular/material2/tree/master/src/lib/tabs

    But for especially your problem, your could try something like this:

    <tabs #tabsRef [tabsMenu]="tabs">
       <tab-content>
           Tab 1
       </tab-content>
       <tab-content>
           Tab 2
           <button (click)="tabsRef.setActiveTab(2);">tab 3!</button>
       </tab-content>
       <tab-content>
           Tab 3
       </tab-content>
    </tabs>
    

    And make that function setActiveTab public.