function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Patrick McClellanPatrick McClellan 

Dynamic assignment on aura:id

I'm creating a Lightning component that uses aura:iterate to dynamically build a form, with a field for each item in a list object. The markup works great, but I don't know how to go back and get the values from the fields later -- to validate the fields and then to save the values.

I would normally use aura:id to component.find() the field, and then get("v.value"). BUT aura:id is undefined because it can't be dynamically assigned with a merge field. Here's how I was trying to assign aura:id in the iteration markup, but that aura:id assignment doesn't work.
<aura:component >
    <aura:attribute name="topic" type="Topic__c"/>
        <div class="slds-tile slds-hint-parent">
            <div class="slds-form-element slds-is-required">
                <div class="slds-form-element__control">
                    <ui:inputNumber aura:id="{!v.topic.Id}" label="{!v.topic.Name}"
                                    class="slds-input"
                                    labelClass="slds-form-element__label"
                                    value = "{!v.topicResult.score__c}" />   
                </div>
            </div> 
        </div>
</aura:component>
I've double checked that {v.topic.Id} is valid (I can assign it to the label with no problem). I've tried using a simple string in a variable, also with no success. It appears aura:id has to be hard-coded.

So, any ideas on another attribute I can use to identify and call each field?
Is there a way to do a component.find() on a different attribute, like label, that can be set dynamically?

I'm using ui:inputNumber based on my use of it in the Lightning Component Trail on Trailhead (the one with Expenses and the Camping List), but I'm seeing an altenative --  lightning:input (Beta). I'm reading the docs on it, thinking maybe I can use the name attribute, but not sure if I can then component.find() it by name.

Any insight or ideas out there? Thanks.
Patrick McClellanPatrick McClellan
I realized that when doing the component.find() in validation, it's ok if the fields all have the same aura:id because find() will return an array and I can validate there. However, even if they all have the same name, I can't even hardcode an aura:id in an aura:iteration loop. Damn frustrating. Am I missing something?
<aura:component >
    <aura:attribute name="topic" type="Topic__c"/>
    
    <div class="slds-tile slds-hint-parent">        
        
        <div class="slds-form-element slds-is-required">
            <div class="slds-form-element__control">

                <div class= "{!v.topic.Id}">

                    <lightning:input aura:id="field"
                                     type="number" 
                                     label="{!v.topic.Name}"
                                     value = ""
                                     required="true"/>   
                    <br></br>
                </div>
            </div>
        </div> 
    </div>
    
</aura:component>
Notice that I added a div class wrapper that dynamically assigns the unique Id, but I don't know if I can access the info (field input) based on the class name.
 
Jefferson FernandezJefferson Fernandez
Hi Patrick,
Yes you are right that we cannot hard code aura:id. Instead of aura:iteration, an approach that you could consider is to dynamically create a number of components equal to the size of your object list upon rendering of your page, please see Dynamically Creating Components (https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/js_cb_dynamic_cmp_async.htm?search_text=createcomponent). This way, you can set make a loop on JS and assign the aura:id dynamically by appending a string plus the index value based on the size of the object list which you can later retrieve when you validate.