3

I'm trying to use lighting:tabset in a custom component where my component will receive a list of labels for the tabs, plus a list of components for their contents. But, I can't make it work.

I've broken the whole thing out into a standalone app to try to diagnose the situation.

My first thought was to try to use positional association like this...

Component:

<aura:application extends="force:slds">

    <aura:attribute name="labels" type="String" />

    <aura:attribute name="components" type="Aura.Component[]" />
    <aura:attribute name="tabContentsAndLabels" type="Object[]" access="private" />

    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>

    <lightning:tabset>
        <aura:iteration items="{!v.components}" indexVar="i" var="thisComponent">
            <lightning:tab>
                {!thisComponent}
                <aura:set attribute="label">
                    {!labels[i]}
                </aura:set>
            </lightning:tab>
        </aura:iteration>
    </lightning:tabset>

</aura:application>

Controller:

({
    doInit : function(component, event, helper) {
        var tabContentsAndLabels = [];

        $A.createComponents([
            ["ui:message",{
                "title" : "Tab 1 Content",
                "severity" : "info",
            }],
            ["ui:message",{
                "title" : "Tab 2 Content",
                "severity" : "info",
            }],
            ],
            function(components, status, errorMessage){
                if (status === "SUCCESS") {
                    var labels = [];
                    components.forEach(function(newComponent, i) {
                        var thisLabel = 'Tab ' + i + ' label';
                        labels.push(thisLabel);
                        tabContentsAndLabels.push({
                            content: newComponent,
                            label: thisLabel
                        });
                    });
                    component.set('v.tabContentsAndLabels', tabContentsAndLabels);
                    component.set('v.components', components);
                }
            }
        );      

    }
})

But this doesn't even compile because the indexVar of an iteration doesn't work as an integer in an expression (see Lightning: aura:iteration - how to refer indexVar variable inside loop to access elements in List?).

So, I tried putting the label together with the component in an object. Then, I can iterate over the object and use the .component and .label keys to match things up.

This renders the tab labels correctly, but not the body inside the tabs. To make sure I'm not being totally stupid, I then tried the tabs where I just iterate over the list of components, and use the indexVar for the label itself:

<aura:attribute name="labels" type="String" />
<aura:attribute name="components" type="Aura.Component[]" />
<aura:attribute name="tabContentsAndLabels" type="Object[]" access="private" />

<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>

Objects:
<lightning:tabset>
    <aura:iteration items="{!v.tabContentsAndLabels}" indexVar="i" var="thisTabContentAndLabel">
        <lightning:tab>
            {!thisTabContentAndLabel.content}
            <aura:set attribute="label">
                {!thisTabContentAndLabel.label}
            </aura:set>
        </lightning:tab>
    </aura:iteration>
</lightning:tabset>
Just the components:
<lightning:tabset>
    <aura:iteration items="{!v.components}" indexVar="i" var="thisComponent">
        <lightning:tab>
            {!thisComponent}
            <aura:set attribute="label">
                {!i}
            </aura:set>
        </lightning:tab>
    </aura:iteration>
</lightning:tabset>

This lot renders to:

enter image description here

So, the object-based version produces the wrong rendered result, but simple iteration over the Aura.Component array works for the tab bodies. Does this mean there isn't a way to achieve what I'm looking for? Custom tab bodies and custom tab labels together?

The one other thing I did try was wrapping the tab into its own custom to component, to see if that would hint to types correctly to Lightning, but that didn't work i.e.

<aura:component access="global">

    <aura:attribute name="content" type="Aura.Component" />
    <aura:attribute name="label" type="String" />

    <lightning:tab>
        {!v.content}
        <aura:set attribute="label">
            {!v.label}
        </aura:set>
    </lightning:tab>


</aura:component>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.