How do we identify which lightning input is updated in an iteration?

I’m trying to construct a page that allows users to edit records, and it should be in SLDS, so I’m trying to use lightning:input to minimize the amount of code I need to write. Ultimately, a method will be called to update the records on the server. Ideally, I’d like to be able to identify which row was updated without saving/comparing the state of all the input elements.

Using normal HTML inputs, this is trivial. Under Locker Service, it appears that I can’t traverse back up into my code to figure out which element to use, nor can I set custom data elements to identify which row is being updated. Here’s a simple example that demonstrates what I’m trying to achieve:

<aura:application extends="force:slds">
    <aura:attribute name="message1" type="String" />
    <aura:attribute name="message2" type="String" />
    <aura:attribute name="values1" type="List" default="['','']" />
    <aura:attribute name="values2" type="List" default="['','']" />

    <aura:iteration items="{!v.values1}" var="value" indexVar="index">
        <div data-index="{!index}" onchange="{!c.update1}">
            <label class="slds-form-element__label" for="{!'item'+index}">HTML Input</label>
            <input class="slds-input" id="{!'item'+index}" value="{!value}" />
        </div>
    </aura:iteration>
    <hr />
    {!v.message1}
    <hr />
    <aura:iteration items="{!v.values2}" var="value" indexVar="index">
        <div data-index="{!index}" onchange="{!c.update2}">
            <lightning:input type="text" value="{!value}" label="Lightning Input" />
        </div>
    </aura:iteration>
    <hr />
    {!v.message2}
    <hr />
</aura:application>

({
    update1: function(component, event, helper) {
        component.set(
            "v.message1", 
            `HTML line ${1+parseInt(event.target.parentNode.dataset.index)} was updated to ${event.target.value}`
        );
    },
    update2: function(component, event, helper) {
        component.set(
            "v.message2", 
            `Lightning line ${1+parseInt(event.target.parentNode.dataset.index)} was updated to ${event.target.value}`
        );
    }
})

In update1, we can easily identify the value that was changed and the row which was updated. Is there a way comparable way to get the index of the row in update2 that’s compatible with Locker Service, or otherwise identify which item in the list is being updated?


Edit: Ideally, if possible, we should be able to read an attribute, or otherwise be able to determine, specifically which row was updated without using an attribute that has a different purpose. For example, using name will cause type="radio" to work incorrectly.

Answer

I do not think class attribute should be used to store index. Instead we can use name in Lightning:input to do so.

<aura:iteration items="{!v.values2}" var="value" indexVar="index">
        <lightning:input type="text" name="{!index}" value="{!value}" label="Lightning Input" onchange="{!c.update3}"/>
    </aura:iteration>

In js

update3 : function(component,event){
        var index = event.getSource().get('v.name');
        var value = event.getSource().get('v.value');
    }

Attribution
Source : Link , Question Author : sfdcfox , Answer Author : Manjot Singh

Leave a Comment