I am bout to create an dynamic vertical tabbar which gets its content from a query later on. This turns out to be an issue as the aura:iteration seems to be not filled at the point of time the init event is triggered.
Basically I have my VerticalTabs element, which shows the content via {!v.body}
<div class="slds-vertical-tabs">
<ul class="{!'slds-vertical-tabs__nav '+ (v.showHeader?'':'slds-hide')}" role="tablist" aria-orientation="vertical">
{!v.header}
</ul>
{!v.body}
</div>
The tab structure is defined via a VerticalTab component
<div class="{#'slds-vertical-tabs__content slds-'+ (v.index==0?'show':'hide')}" id="{#'slds-vertical-tabs-' + v.index}" role="tabpanel" aria-labelledby="{#'slds-vertical-tabs-' + v.index + '__nav'}" aura:id="verticalTab">
<div class="slds-text-longform">
<aura:if isTrue="{#showTitle}">
<h3 class="slds-text-heading_medium">{#v.title}</h3>
</aura:if>
<p>{!v.body}</p>
</div>
</div>
based on the body, I want to dynamically create the tabbar header. This is to be done dynamically via the controller iterating over the body:
init : function(component, event, helper) {
console.log("init VerticalTabs");
var body = component.get("v.body");
var barComponents = [];
for (var i=0, len = body.length; i<len; i++) {
var title = body[i].get("v.title");
console.log(title);
body[i].set("v.index", i);
barComponents.push(["aura:html", {
"tag": "li",
"HTMLAttributes": {
"title": title,
"class": "slds-vertical-tabs__nav-item " + (i==0?'slds-is-active':''),
"role": "presentation"
}
}]);
barComponents.push(["aura:html", {
"tag": "a",
"body": title,
"HTMLAttributes": {
"class": "slds-vertical-tabs__link",
"role": "tab",
"tabindex": (i==0?"0":"-1"),
"aria-selected": (i==0?"true":"false"),
"aria-controls": "slds-vertical-tabs-" + i,
"id": "slds-vertical-tabs-"+ i +"__nav",
"onclick": component.getReference("c.changeTab")
}
}]);
}
if (len > 1)
component.set("v.showHeader", true);
$A.createComponents(barComponents, function (components, status, errorMessage) {
if (status === "SUCCESS") {
var navbar = [];
for (var i=0, len = components.length; i<len; i+=2) {
components[i].set("v.body", components[i+1]);
navbar.push(components[i]);
}
component.set("v.header", navbar);
}
else {
console.log(errorMessage);
//this.displayToast("Error", "Failed to create list components.");
}
});
next part is loading the vertical tabs via a wrapping component:
<aura:component implements="flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId" access="global" >
<aura:attribute name="test" type="Object[]" />
<c:VerticalTabs>
<aura:iteration items="{!v.test}" var="q">
<c:VerticalTab title="{!q}">
<div>{!q}</div>
</c:VerticalTab>
</aura:iteration>
</c:VerticalTabs>
</aura:component>
But it does look like this data is loaded after the initial init of the body. Due to the nature of aura:iteration it looks like the body does not get updated and I cannot receive the loaded verticalTab. This results in nothing being displayed.
Is there a more proper way of dynamically creating the content? How can I build my dynamic tabs? If I hard-code the VerticalTabs it is working flawless. Otherwise, it does not recognize the change in the v.body :/
nico