'Dynamically Add tabPanel to tabView in PrimeNg
I wanted to have a 'Add Tab' button, on clicking that button i want to add a new Tab(tabPanel) to existing list of tabView. Till now i am able to achieve the addition of new tab on clicking a 'Add Tab' button but i am not sure how to add the dynamic html content to the tab.
appComponent.html
<button pButton (click)="addTab()" label="selected header"></button>
<p-tabView (onChange)="onChange($event)" [activeIndex]="selectedIndex">
<p-tabPanel header="first" [selected]="true">
Hello1
</p-tabPanel>
<p-tabPanel header="second" cache="false">
hello2
</p-tabPanel>
</p-tabView>
app.component.ts
import {Component, ViewChild, ViewContainerRef} from '@angular/core';
import {TabView, TabPanel} from 'primeng/primeng';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(private viewContainerRef: ViewContainerRef) {
}
@ViewChild(TabView) tabView: TabView;
addTab() {
const tab: TabPanel = new TabPanel(this.viewContainerRef);
tab.header = 'Tab3';
tab.closable = true;
this.tabView.tabs.push(tab);
}
}
Solution 1:[1]
This is what worked for me. I took inspiration from Mr. Victor Baydun's answer.
import { Component, HostBinding, QueryList, ViewChild, ViewContainerRef } from "@angular/core";
import { TabPanel, TabView } from "primeng/tabview";
@Component({
...
})
export class MyTabClass {
@ViewChild("tabsContainer", { static: true, read: ViewContainerRef }) tabsContainer!: ViewContainerRef;
ngAfterViewInit() {
const tabView = this.tabsContainer.createComponent<TabView>(TabView);
const tabPanel1 = new TabPanel(tabView.instance, this.tabsContainer, tabView.changeDetectorRef);
const tabPanel2 = new TabPanel(tabView.instance, this.tabsContainer, tabView.changeDetectorRef);
const queryList = new QueryList<TabPanel>(false);
tabPanel1.selected = true;
queryList.reset([tabPanel1, tabPanel2]);
tabView.instance.tabPanels = queryList;
tabView.instance.tabs.push(tabPanel1, tabPanel2);
tabView.instance.initTabs();
}
}
<ng-container #tabsContainer></ng-container>
Solution 2:[2]
import {Component, ViewChild, ViewContainerRef, ComponentFactoryResolver} from '@angular/core';
import {TabView, TabPanel} from 'primeng/primeng';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(private componentFactoryResolver: ComponentFactoryResolver,
private viewContainerRef: ViewContainerRef) {
}
@ViewChild(TabView) tabView: TabView;
addTab() {
let nTabs = this.tabView.tabs.length;
const tab: TabPanel = new TabPanel(this.viewContainerRef);
tab.header = 'Tab' + (nTabs+1);
tab.closable = true;
const component: any = <some component>;
const factory = this.componentFactoryResolver.resolveComponentFactory(component);
this.viewContainerRef.createComponent(factory);
this.tabView.tabs.push(tab);
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Pavel_K |
Solution 2 |