PrimeNG - How to dynamically add and remove a p-tabPanel in p-tabView component

11,189

I figured out a way. I am using ngFor to control the # of tabPanel.

My component.ts code will manipulate myModel.leads. Thus, the number of tabPanel will change accordingly.

<!--Lead-->
<p-tabView  >  
  <p-tabPanel [selected]="i==0" *ngFor="let lead of procedureDetail.leads; let i = index" header="lead {{i+1}}"  >
           <div id="{{lead.id}}" class="my_dynamica_lead_tabPanel"> <!-- I can add content to this div with tabView.onChange() api -->
          {{lead.id}} - {{i}}
           </div>
           <div class="row">
              <div class="col-md-3">
                 Date:
              </div>
           <div class="col-md-9">
              <p-calendar [style]="{'width':'180px'}" [monthNavigator]="true" [yearNavigator]="true" yearRange="1900:2020" name="lead.{{i}}.date" [(ngModel)]="lead.date" [showIcon]="true" ></p-calendar> 
          </div>
       </div>

   </p-tabPanel>
</p-tabView> 

Note - If you forget to include [selected] attribute while using *ngFor in p-tabPanel. You will get following error

TabPanel.html:2 ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'none'. Current value: 'block'.
Share:
11,189
Kutas Tomy
Author by

Kutas Tomy

Updated on July 05, 2022

Comments

  • Kutas Tomy
    Kutas Tomy almost 2 years

    I'm on a project where I need to use a p-tabView. A new p-tabPanel is to be created when clicking on a button in the p-tabView.

    How can I dynamically add new panels to a p-tabView?

    • Milan Malani
      Milan Malani over 7 years
      Please provide that what you have tried so far
    • Kutas Tomy
      Kutas Tomy over 7 years
      I tried to modify the DOM adding something like: <p-tabPanel header='Tab45'><div class='ui-tabview-panel ui-widget-content' style='display: block;'></div></p-tabPanel> to the tabWiev. The DOM is modified but something wrong and the panel is not visible.
    • Kutas Tomy
      Kutas Tomy over 7 years
      I also tried to find a method of the component wich is adding panels to the component, but no succcess. The component has no method wich is adding new panels. I used this solution to call component methods: stackoverflow.com/questions/31013461/…
  • Mutmansky
    Mutmansky over 7 years
    This certainly works to create a dynamic set of tabs, but the content is not dynamic. So it's not very useful to have a bunch of tabs all with the same content.
  • Kutas Tomy
    Kutas Tomy about 7 years
    On tab selection/change I reloaded from a map [key == tabHeader] the selected panel content. In this way changing the tabs, the content is also changed.
  • Mutmansky
    Mutmansky about 7 years
    Understood, but how did you populate that map? I assume you still knew what content you needed to load ahead of time so you could populate that map appropriately. In my situation, the contents of the tabs are determined at run time. That is, there's a database table that tells me what tabs I need to have in the application. So after my application starts up, I read that list of tabs in from the database and I create them using ComponentResolver. Sounds like your situation is different.
  • Kutas Tomy
    Kutas Tomy about 7 years
    My situation is pretty the same. I also have my application connected to a database. Basically, the map is populated when the app starts up. I'm calling some REST services to get data loaded. I didn't use any Component Resolver. I have a simple GUI, only a data table which has some filters.
  • Mutmansky
    Mutmansky about 7 years
    Maybe there's something missing from your answer then. You put in the <CONTENT> as if it's a place holder, so I'm assuming that content is just statically defined in the template. I could see how the data within that <CONTENT> could be different based on what's in your map, but the <CONTENT> itself is the same. Correct? If not, how is the content loaded into the DOM based on what's in your map?
  • user2010955
    user2010955 about 6 years
    I'm doing the same way, there's one thing: I'm experiencing memory leaks when I remove elements form the arraybinded to the ngFor (e.g the procedureDetail.leads), the Nodes are not removing from the DOM...