aura:id doesn’t support expressions, and now?

If you create dynamic User Interfaces in Lightning, you will certainly have the problem to detect the right element or button being clicked.

For example, say your user will have a dynamic list of elements that you can’t predict, rendered in the UI. Each element when triggered should execute a specific functionality or action.

How do you handle that type of dynamism, to find out what button was clicked?

It seems legit to use aura:id to do this, right?
Well, unfortunately it’s still not possible to have a dynamic assignment on aura:id. From the docs (link):

aura:id doesn’t support expressions. You can only assign literal string values to aura:id.

The trick is to assign a custom identifier to each element, different from the aura:id, so that you can use it to find out what action to execute when your event occurs.

Since the identifier should also be easy to retrieve during the event handling, it should be an attribute of the html element or the lightning component. For example, if you want to use buttons you can:
1) use standard HTML buttons, using data attributes for the identifiers
2) use lightning:button, passing your identifier in the name

In case of HTML buttons, look at the data-index attribute usage in this example:

<aura:iteration items="{!v.items}" var="index" indexVar="indexVar">
    <button onclick="{!c.buttonClick}" data-index="{!indexVar}" class="slds-button slds-button_neutral">
        {!'HTML Button ' + index}
    </button>
</aura:iteration>

The client-side controller can retrieve the data-index like this:

buttonClick : function(component, event, helper) {
    var clicked = event.target.getAttribute("data-index");
    console.log("HTML Button: clicked element ", clicked);
}

Similarly with lightning:button you can use the name attribute:

<aura:iteration items="{!v.items}" var="index">
    <lightning:button label="{!'Lightning Button ' + index}" name="{!index}" onclick="{!c.lightningButtonClick}"/>
</aura:iteration>

And retrieve the name in the client-side controller like this:

lightningButtonClick : function(component, event, helper) {
	var clicked = event.getSource().get("v.name");
	console.log("Lightning Button: clicked element ", clicked);
} 

NotBad

Christian Tinghino

Senior Developer, 2x Salesforce certified

Leave a Reply

Your email address will not be published. Required fields are marked *