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