We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy.
Unfortunately, activation email could not send to your email. Please try again.

Dynamic tabs with content

Thread ID:

Created:

Updated:

Platform:

Replies:

128048 Dec 28,2016 12:37 PM Jun 28,2017 08:17 AM Angular 22
loading
Tags: ejTab
Me
Asked On December 28, 2016 12:37 PM

Hello,

I need to add tabs and tab content dynamically into tabPanel. How can I achieve that?

                            <ej-tab id="tabsample">
                                <ul>
                                    <li><a rel='nofollow' href="#home" >Home</a></li>
                                </ul>
                                <div id="home" style="background-color: deeppink">
                                    <h1>Welcome! This is Home tab..</h1>     
                                </div> 
                            </ej-tab>

I can add tab dynamically like this:             
                              var tabObj = $("#tabsample").data("ejTab");
                              tabObj.addItem("#dynamicTab", "dynamic content", 2, "myClass", 2);

But how can I add content (dynamically)?
                               <div id="dynamicTab">
                                    <h1>Welcome Dynamic tab! </h1>     
                                </div> 

Also, I need that heightAdjustMode would be ''fill' for each tab.


P.S. Content can't be hardcoded into HTML. I need to be able to add it dynamically.




Gopi Govindasamy [Syncfusion]
Replied On January 2, 2017 07:50 AM

Hi Me 

We have checked your scenario for “new tab and content added dynamically in angular 2”, We can add the tab dynamically by using addItem() public method.  
 
Add code snippet here 

 

  
Regards, 
Gopi G   


Me
Replied On January 2, 2017 03:59 PM

Hey, thanks! However it works only for simple html, but not for angular / syncfusion components. How could I add something like this:

var content= "<div id='dynamicTab'> <myCustomList></myCustomList> </div>";

Also, is there a way to remove that HTML after tab is closed? Moreover can I specify particular tab to have / not have close button?


P.S. A bit disappointment that Syncfusion haven't implemented such an important functionality for TabPanel :/ 

Gopi Govindasamy [Syncfusion]
Replied On January 3, 2017 04:24 AM

Hi Me,    
  
We have checked your scenario. You can dynamically add ej component and the provided content to new tab items. We have prepared a sample for your requirement and attached the sample link below.    
  
  
In the tab control, we have provided showCloseButton property to show the close button icon. If you click the icon, the particular tab will be closed and the tab will be removed from HTML attributes also removed automatically. By default, all tabs show close icon. If you need to show the close icon in a particular tab item only, you have to customize this. We have customized the tab in the above sample.    
  
We have implemented most of the feature. Please share the expected feature in tab control, so that we can consider it and implement it.    
  
Regards,    
Gopi G.   


Me
Replied On February 1, 2017 06:58 AM

Hello again.

Your solution kinda works, but it's not fully what I need. It only works with HTML and Syncfusion component. I would like to write a wrapper for ejGrid and add that component (dynamically, which will also be lazy loaded). However, as far as I saw I'm not able to do that, unless I use hard-coded divs.

I tried to use this method:

Tabpanel:

Hard coding containers for dynamic load:

Creating Tab:

Lazy loading component and inserting into container:


Have in mind I'm using SystemJS for that. That works, but only until I try to close a tab. When I close tab my created hard-coded divs are also removed and I'm not able to reuse them.
1. Is there a way to prevent content div removal after tab close button is clicked? (Tab itself still has to hide) 
2. After tab is cloused with id tabContent3, I'm not anymore able to create tab with same ID, why is that? :o

 tabObj.addItem('tabContent3', 'tabContent9', 6, null, 'tabContent3'); Create tab like this, close it and then try to create it again.

I get this error:


P.S. Tried to use $("#myMainTabPanel").data("ejTab").hideItem(1); - not working. I get no error, but nothing happens. Tried to change index too.

Prince Oliver [Syncfusion]
Replied On February 2, 2017 11:52 AM

Hi Me, 

Thanks for your update. 

Query 1: Is there a way to prevent content div removal after tab close button is clicked? (Tab itself still has to hide)   

In order to remove the content alone instead of entire div, you need to manually override the _tabDeleteClick method. Have a look at the following code snippet. 

ej.Tab.prototype._tabDeleteClick = function (args) { 
            if (this.model.enabled) { 
                var currentTab = $(args.target); 
                if (currentTab.closest("li").hasClass("e-active") && currentTab.hasClass("e-close")){ 
                    $(this.contentPanels[this.model.selectedItemIndex()]).html(""); 
                } 
            } 
        }; 


Query 2: After tab is cloused with id tabContent3, I'm not anymore able to create tab with same ID, why is that?  

We were not able to reproduce the issue at our end. Please provide us additional information along with an issue reproducing sample and replication steps, it would help us to isolate the root cause and provide a solution 

Regards, 
Prince 


Me
Replied On April 6, 2017 10:29 AM

Hello again,

I need to be able to dynamically create tabs and insert my custom written components. Again, tab's must be created dynamically not hardcoded into html. How can I achieve that?

This is code how I would like to insert component into newly, dynamically created tab (vcRef is viewContainerRef which I don't have because tabs must be created dynamically, runtime) :
          // Inputs need to be in the following format to be resolved properly
        let inputProviders = Object.keys(inputData).map((inputName=> {return {provide: inputNameuseValue: inputData[inputName]};});
        let resolvedInputs = ReflectiveInjector.resolve(inputProviders);

        // We create an injector out of the data we want to pass down and this components injector
        let injector = ReflectiveInjector.fromResolvedProviders(resolvedInputsvcRef.parentInjector);

        // We create a factory out of the component we want to create
        let factory = this.resolver.resolveComponentFactory(component);

        // We create the component using the factory and the injector
        let comp = factory.create(injector);

        // We insert the component into the dom container
        vcRef.insert(comp.hostView);

        this.tabComponents[tabId] = comp;



Prince Oliver [Syncfusion]
Replied On April 9, 2017 09:37 AM

Hi Me, 

Thank you for your update. 

We are unable to replicate your scenario with the provided code. Please provide us a simple sample explaining your requirement. It will help us understand your query requirement better and provide solution. 

Regards, 
Prince 


Me
Replied On April 24, 2017 01:57 AM

Here is your asked working sample (which has some bugs, for instance - can't change title when tab reused). Just bear in mind, my provided sample is kinda working, but it's not right. I'm looking for better, easier and cleaner solution. My main goal is to be able dynamically create tabs and then add into them my custom created ng2 components. Not Syncfusion component, but my custom created component (which might have syncfusion component). You should understand what I need by checking sample out.P.S. Node_Modules folder excluded because of the file size, but I added it here: http://www74.zippyshare.com/v/xnoKpJXp/file.html

Me
Replied On April 24, 2017 02:00 AM

Here is your asked working sample (which has some bugs, for instance - can't change title when tab reused). Just bear in mind, my provided sample is kinda working, but it's not right. I'm looking for better, easier and cleaner solution. My main goal is to be able dynamically create tabs and then add into them my custom created ng2 components. Not Syncfusion component, but my custom created component (which might have syncfusion component). You should understand what I need by checking sample out.P.S. Node_Modules folder excluded because of the file size, but I added it here: http://www74.zippyshare.com/v/xnoKpJXp/file.html

Attachment again.

Attachment: angular2seedsmaster_9d83b890.zip

Prince Oliver [Syncfusion]
Replied On April 24, 2017 09:02 AM

Hi Me, 

Thank you for your update. 

We checked the sample you shared. In order to dynamically create tabs with content, you can use the contentPanel from tab object and set the innerHtml content. Refer to the following code snippet. 

tabObj["contentPanels"][tabCount].innerHTML = "<div #" + tabId +"></div>"; 

  
ViewContainerRef will not be accessible for dynamically rendered div element and you cannot assign it dynamically. Hence the error will be thrown. So, you need to predefine the reference div elements if you need to use it as ViewContainerRef to render the ng2 components in them. 


Please note we have excluded the node_modules folder from the sample. 

Regards, 
Prince 


Me
Replied On April 25, 2017 02:53 AM

Echh.. That limitation really puts brackets on :| Looks like my current solutions is the best one, for a now.. Another related question: when I hide and show tab I need it to appear in the back of the tabs row, like a newly created tab. How can I do that? (Again, have a look into my provided sample as it's that one which I would like to upgrade)


Prince Oliver [Syncfusion]
Replied On April 26, 2017 07:57 AM

  
Hi Me,   
  
Thank you for your update.   
  
By default, in our tab control when the tab item is hidden and then shown, it will appear in the same position. To hide the item and show it in the last position, you need to manually remove the <li> element of the hidden tab and place it in the last. Kindly refer to the following code snippet.   

onHide(args) 
    { 
         var tabObj = this.gpTabPanel.widget; 
         var tabLi = tabObj["element"]["find"]("li"); 
        tabObj["hideItem"](1); 
        tabObj["items"][1]["setAttribute"]("style","display:none;"); 
        tabLi[tabObj["items"]["length"]-1]["parentNode"]["append"](tabLi[1]); 
      } 
//In the above method, we are hiding the second tab item and displaying it in last position  

We have attached the modified sample, kindly refer to the following link for the sample:  

Regards, 
Prince 


Me
Replied On June 20, 2017 08:56 AM

Hey,


I tried to implement your solution, but I get weird behavior: After moving old tab to the back of the row, on mouse over a tab it sets 'Exit'  button visibility for the previous tab (check picture):

After I add new tab normally, it fixed 'X' button visibility issues, bu then it shows two active tabs at the same time:



Any solution?





Me
Replied On June 20, 2017 09:18 AM

Moreover, after you close those two new tabs and create new one, some of the old dissapears until you again, create a few more new tabs and then everything seems to work ok.

Checked your provided sample, has same bugs.


Prince Oliver [Syncfusion]
Replied On June 21, 2017 07:11 AM

Hi Me,   
  
Thank you for your update.   
  
In the previous solution, we have provided the steps to move the <li> element to last while hiding. The changes done hasn’t been updated in the internal variables that hold the tab items. So, when the hover handler is called the close icons are displayed for items in their previous position. To overcome this, we need to refresh the variables by calling the internal _itemsRefreshing method and triggering the click for the active item updates the changes in the control thus fixing the multiple active item behavior. You need to refresh the items in both hide and show method. Kindly refer to the following code snippet.   

onHide(args) 
{ 
    var tabObj = this.gpTabPanel.widget; 
    var tabLi = tabObj["element"]["find"]("li"); 
    if(tabObj["items"]["length"]<=1){ 
    alert("Add more Tabs"); 
    }else{ 
    tabObj["hideItem"](1); 
    tabObj["items"][1]["setAttribute"]("style","display:none;"); 
    tabLi[tabObj["items"]["length"]-1]["parentNode"]["append"](tabLi[1]); 
       tabObj["_itemsRefreshing"](); 
       tabObj["items"]["parent"]()["find"](".e-active")["trigger"]("click"); 
    } 
} 
 
onShow(args) 
{ 
    var tabObj = this.gpTabPanel.widget; 
    var tabLi = tabObj["element"]["find"]("li"); 
    if(tabObj["items"]["length"]<=1){ 
    alert("Add more Tabs"); 
    }else{ 
    tabObj["showItem"](1); 
    tabObj["items"][1]["removeAttribute"]("style"); 
       tabObj["_itemsRefreshing"](); 
       tabObj["items"]["parent"]()["find"](".e-active")["trigger"]("click"); 
    } 
} 

Regards, 
Prince 


Me
Replied On June 22, 2017 01:08 PM

Hey,

Your provided code is working, but after that two code-rows is executed, content gets mixed up. Checked tab and content Ids - everything is fine (see image), but visually wrong content is shown. If your provided code is commented out, content shows fine, but there are those bugs with tabs then. Any solution?

If I comment out your provided code (see image below), content won't mix up and is shown fine. You can test it by commenting out provided code in two places: createNewTab and onBeforeTabItemRemvove.


You can reproduce bug by following these steps:

1. Create 4 tabs (GridComponent, GridComponentA, GridComponentB, GridComponentC)
2. Close 2 ar 3 of them (Don't close Home tab, that one is not implemented - it will stay open all the time)

3. Create closed tabs again. (If tab with that component is already opened, it will be automatically focused, otherwise created and moved to the back).


P.S. I attached working sample.


Attachment: ng2tabsample_f5de1c50.rar

Me
Replied On June 22, 2017 01:11 PM

Once again, to clarify problem: after code (which updates tab items internally) is executed, wrong content is shown within tabs. This won't happen if I don't execute your provided code. Tabs has correct content ids, so this is not a case. You should easily see that in my provided sample, as every grid has different headers by letter (A, B,C or none). 


Prince Oliver [Syncfusion]
Replied On June 23, 2017 08:24 AM

Hi Me,   
  
Thank you for sharing your sample.   
  
In the show method, we can use the internal refresh method to update the content panels in accordance with the changes done in the tab headers. Through this way, we can avoid the wrong content for the tabs. Kindly refer to the following code snippet.   

// Showing tab 
  tabObj["showItem"](tabId); 
  tabObj["items"][tabId]["removeAttribute"]("style"); 
//this.myTabPanel.widget.showItem(htId); 
//this.myTabPanel.widget.element.ejTab({hiddenItemIndex: this.hiddenTabs }); 
// Moving tab to the back of tabs row 
tabElements[tabId]["parentNode"]["append"](tabToShow); 
// Refreshing tabs 
tabObj["_itemsRefreshing"]();  
tabObj["items"]["parent"]()["find"](".e-active")["trigger"]("click");  
tabObj["_refresh"](); 

  
We have attached the modified sample for your convenience, kindly refer to the following link for the sample: http://www.syncfusion.com/downloads/support/forum/128048/ze/ng2tabsample_f5de1c50104942926 

Regards, 
Prince 


Me
Replied On June 23, 2017 11:09 AM

Cheers - that works! Looks like we are almost there.. A few more questions:
1. After 'X' is clicked on tab and onBeforeTabRemove() method is executed, how can I focus last tab in a tab row? showItem() seems not to be working...

2. That code you provided me, is there any documentation on that I can look into?




Prince Oliver [Syncfusion]
Replied On June 27, 2017 03:33 AM

Hi Me, 

Thank you for your update. 

Query 1. After 'X' is clicked on tab and onBeforeTabRemove() method is executed, how can I focus last tab in a tab row? showItem() seems not to be working...  

Response: To focus the last tab, we need to use the selectedItemIndex property. Kindly refer to the following code snippet.   

var tabObj = this.myTabPanel.widget.element.ejTab("instance");  
tabObj["setModel"]({ selectedItemIndex : tabObj["items"]["length"] - 1}); //To select the last tab 


Query 2. That code you provided me, is there any documentation on that I can look into? 

Response: We have provided a specific solution for your requirement by altering the default behavior of the tab and overriding the internal methods. Hence it is not documented.   

Regards, 
Prince 


Me
Replied On June 27, 2017 08:27 AM

Hey,

Your provided code is not working. Something else is missing again?


Prince Oliver [Syncfusion]
Replied On June 28, 2017 08:17 AM

Hi Me, 

Thank you for your update. 

We have to use setTimeout method to select the last tab item, because the selected items gets reset in the further execution of script in zone.js file after the onBeforeTabRemove() method. Kindly refer to the following code snippet. 

//selecting the last tab item after hiding 
setTimeout(()=>{    
    tabObj["setModel"]({ selectedItemIndex : tabObj["items"]["length"] - 1}); 
},1); 

  
We have attached the sample, kindly refer to the following link for the sample: http://www.syncfusion.com/downloads/support/forum/128048/ze/ng2tabsample1335150324 

Regards, 
Prince 


CONFIRMATION

This post will be permanently deleted. Are you sure you want to continue?

Sorry, An error occured while processing your request. Please try again later.

You are using an outdated version of Internet Explorer that may not display all features of this and other websites. Upgrade to Internet Explorer 8 or newer for a better experience.

;