[SalesForce] How to use the lightning:tabset selectedTabId to change the current tab

I've got a lightning:tabset with a collection of child lightning:tab components. Each child tab defines an id attribute.

The lightning:tabset selectedTabId is bound to a private string attribute in an attempt to control the selected tab.

Changing the attributes default value does successfully change the tab that the component loads with.

Yet changing the corresponding attribute from the controller has no affect on the selected tab. Is there an easier way to change the selected tab from JavaScript?

Best Answer

Right, when you change the two-way binding attribute, it does not reflect the change in selectedTabId. This is probably because digest cycle does not carry the change to the lightning:namespace component attribute "selectedTabId". Hence we have set the "selectedTabId" attribute explicitly for the change to happen.

You could implement something as follows

var selected = component.get("v.key"); //key used for storing tab ids.
component.find("tabs").set("v.selectedTabId",selected);

But, implementing the above at every value change could be tedious to maintain especially if there are other logic supplements.

Instead, we could use the value:change handler to do that during every variable assignment.

Application

<aura:application extends="force:slds" access="global">
    <aura:attribute name="key" type="String" default="two" />
    <aura:handler name="change" value="{!v.key}" action="{!c.selectTab}"/>

    <lightning:tabset aura:id="tabs" selectedTabId="two">
        <lightning:tab label="Item One" id="one">
            Sample Content One
        </lightning:tab>
        <lightning:tab label="Item Two" id="two">
            Sample Content Two
        </lightning:tab>
        <lightning:tab label="Item Three" id="three">
            Sample Content Three
        </lightning:tab>
    </lightning:tabset>

    <br/><br/><br/>

    <lightning:button variant="brand" label="ChangeValue" onclick="{!c.handleClick}" />
</aura:application>

Controller

({
    selectTab : function(component, event, helper) { 
        /* General utility */
        var selected = component.get("v.key");
        component.find("tabs").set("v.selectedTabId",selected);
    },
    handleClick : function(component, event, helper){
        component.set("v.key","three"); // value assignation
    }
})

The value change (v.key) is now monitored by the value change handler. And it would fire the selectTab action from the controller and it would set the selecteTabId attribute.

This way whenever the two-way binding attribute is changed, the selected tab would change. If the aura:attribute used is an object, then you could use conditional checks and sanitizations to suit your requirements.