Get Selected HTML or Lightning component in Aura Iterator

How to detect event from Lightning Component and HTML5 components in Aura Iterator

Get selected item in aura iterator component

Coming from Visualforce background, most of us are well aware about repeater component. Same way, Lightning also offers iterator component.

Detecting Selected Lightning Component in Iterator

Usage is very simple, It is used to iterate over collection and render some HTML / Lightning component dynamically as shown below

<aura:component>
  <aura:iteration items="1,2,3,4,5" var="item">
    <meter value="{!item}"/>
  </aura:iteration>
</aura:component>

In above example, each element in collection can be referred using variable “item”. Most of time we find ourselves in situation where we need to get value or component selected in iterator. As we don’t know upfront, how many items would be there, so identifying selected item at run time seems little bit tricky but believe me it easy.

Let’s dive into water and consider below code snippet of Lightning


<aura:iteration items="{!v.lstItem}" var="item">

<ui:inputText change="{!c.textChange}" class="slds-input slds-m-top--large" label="" value="{!item.companyName}"/>

</aura:iteration>

In above code, we have used standard Lightning component ui:inputText and onchange event, we want to find value entered in that text box.

Below is sample code snippet from client side controller

textChange: function(cmp, event,helper) {  
            var target = event.getSource();  
            var txtVal = target.get("v.value") ;
            console.log('Selected Value is '+txtVal);  
    }

We have used event.getSource() method to detect component responsible to generate event. once component is found, we can use target.get(“v.value”). Aura components does not support HTML 5 data attributes and therefore we can not have any other information saved as attribute on components. If we need to store some other information, then need to come up with work around like using class, title or alt attributes.

Detecting Selected HTML Component in Iterator

If we need to store more than one value on element, Aura components could not be solution and we can move to HTML5 components. Lets consider that we have used HTML components in aura iterator tag


<aura:iteration items="{!v.lstItem}" var="item" indexVar="index">
<input data-selected-Index="{!index}" onchange="{!c.textChange}" type="text" value="{! item.companyName}" class="slds-input slds-m-top--large" />
</aura:iteration>

In above example, we have saved value along with index of component in data attribute supported by HTML 5. Index of component in aura:iteration can be referred using indexVar attribute. Related code snippet for client side controller will look like


textChange: function(cmp, event,helper) {
  var target = event.target;
var dataEle = target.getAttribute("data-selected-Index");
console.log("v.selectedItem", "Component at index "+dataEle+" has value "+target.value);
}

Below is complete source code showing how to detect at run time that selected component is Lightning Component or HTML5 component

IteratorDemo.cmp

<aura:component > 
    <aura:attribute name="lstItem" type="Object[]" />
    <aura:attribute name="selectedItem" type="String" default="Changed Text would be displayed here"/> 
     <aura:handler name="init" value="{!this}" action="{!c.initJSONData}"/> 
<div class="slds-grid slds-wrap"> 
<div class="slds-col slds-size--1-of-2"> 
<div class="slds-box slds-box--small slds-theme--shade slds-text-align--center"> 
<h3 class="slds-text-heading--large">Iterator on Lightning Component</h3> 	
                <aura:iteration items="{!v.lstItem}" var="item"> 
                        <ui:inputText change="{!c.textChange}" class="slds-input slds-m-top--large" label="" value="{!item.companyName}"/> 
                </aura:iteration>  
            </div> 
        </div> 
<div class="slds-col slds-size--1-of-2"> 
<div class="slds-box slds-box--small slds-theme--shade slds-text-align--center"> 
<h3 class="slds-text-heading--large">Iterator on HTML Component</h3>  
                <aura:iteration items="{!v.lstItem}" var="item" indexVar="index"> 
                        <input data-selected-Index="{!index}" onchange="{!c.textChange}" type="text" value="{! item.companyName}" class="slds-input slds-m-top--large" />  
                </aura:iteration> 
            </div> 
        </div> 
<div class="slds-col slds-align--absolute-center slds-size--2-of-2"> 
<div class="slds-size--1-of-2 slds-m-top--large slds-text-heading--large">
            	{!v.selectedItem} 
            </div> 
        </div> 
    </div>
</aura:component>

IteratorDemoController.js

({ 
    initJSONData : function(component, event, helper) {
		helper.initJSONData(component, event, helper);
	},
    textChange: function(cmp, event,helper) { 
        helper.textChange(cmp, event,helper); 
    }
})

IteratorDemoHelper.js

({ 
    initJSONData : function(component, event, helper){
        component.set("v.lstItem",helper.getSampleJSON());
        
    },
    getSampleJSON : function(){
        return  [ { "companyName" : "Salesforce" } ,
                 { "companyName" : "IBM" },
                 { "companyName" : "Oracle" } ,
                 { "companyName" : "Twitter" }]  ; 
    },
    textChange: function(cmp, event,helper) {  
        if(event.getSource){
            var target = event.getSource();  
            var txtVal = target.get("v.value") ;
            cmp.set("v.selectedItem",txtVal);   
        }else{
            var target = event.target;  
            var dataEle = target.getAttribute("data-selected-Index"); 
            cmp.set("v.selectedItem", "Component at index "+dataEle+" has value "+target.value); 
        }
         
    }
})

Related posts

2 thoughts on “Get Selected HTML or Lightning component in Aura Iterator”

  1. Hi Jitendra

    I need your assistance in a lightning component. I am trying to re-render my custom component on the clicking on standard component’s button. here I have used rerender method for that scenario but it is rendering recursive and I am unable to stop this. Please assist me for the same.

  2. Hi,
    Thank you for sharing this.I am trying to something similar but instead of ui:inputText, I want to use a button to delete a particular record from iiteration. Can you please guide me to how to get button value as an id of record and then handle it is controller? I tired this component.find(“delRec”).get(“v.value”); It worked for few days and then stopped working now. and the error says cmp.find .value is not valid function.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.