0

I am creating a a list using aura:iteration:

<aura:iteration var="pf" items="{!v.family}" indexVar="ind">
  <li class="slds-dropdown__item">
      <a href="javascript:void(0);" role="menuitemradio" onclick="{!c.prodShow}">
          <p class="slds-truncate">
              <c:svg ariaHidden="true" class="slds-icon slds-icon--selected slds-icon--x-small slds-icon-text-default slds-m-right--x-small" xlinkHref="/resource/SLDS102/assets/icons/utility-sprite/svg/symbols.svg#check"/>
              {!pf}</p>
      </a>
  </li>
</aura:iteration>

Now, when someone clicks on each of these <li> I want to get the value of {!pf} on click on that <li>. Currently, I am not being able to do so since I do not have any ID specific for each <li>.

Could anyone please tell me how to do this? I need this value to populate another dependent picklist on-click of this one.

  • Have look at this answer, it address your problem – Praveen Jun 17 '16 at 6:41
  • I am sorry I couldn't find my solution in this answer. Could you please elaborate Praveen? I don't see a way to set ids from each ' <li>' and accessing them in the helper. – Ayan Sengupta Jun 17 '16 at 7:13
  • i have updated my answer which includes two possible way to access the clicked record – Praveen Jun 17 '16 at 7:52
1

you could do this in two ways:

1.you could do set the data-index instead of id to hold the index in the component and access the clicked value using the id's value in the controller:(based on CharlesT comment)

<aura:iteration var="pf" items="{!v.family}" indexVar="ind">
  <li class="slds-dropdown__item">
      <a data-index="{!ind}" href="javascript:void(0);" role="menuitemradio" onclick="{!c.prodShow}">
          <p class="slds-truncate">
              <c:svg ariaHidden="true" class="slds-icon slds-icon--selected slds-icon--x-small slds-icon-text-default slds-m-right--x-small" xlinkHref="/resource/SLDS102/assets/icons/utility-sprite/svg/symbols.svg#check"/>
              {!pf}</p>
      </a>
  </li>
</aura:iteration>

In the controller.js

({
 prodShow: function(cmp, ev) {
        var index = event.target.dataset.index;
        console.log(cmp.get("v.family")[index]);
    }
})

2.you need to break the component into two : Event Driven Way

For instance,

1.ListCmp - (fetches the data) -> Parent Component

2.ListItemCmp - (displays each record) -> Child component

And use the Event driven way to pass the clicked record from the ListItemCmp to the ListCmp.

ListCmp.cmp

<aura:component>
    <aura:attribute name="family" type="Object[]"/>
    <aura:handler name="sendRecordToParent" event="c:selectedRecordEvt" action="{!c.gotRecordFromChild}" />

        <aura:iteration var="pf" items="{!v.family}" indexVar="ind">
            <c:ListItemCmp item="{!pf}" /> 
        </aura:iteration>
</aura:component>

ListCmpController.js

({
 editRecord : function(cmp, ev) {
        var selectedValue = event.getParam("record");
        console.log(selectedValue);
    }
})

This is an Component level event you should create, which carries the data to the parent.

selectedRecordEvt.evt

<aura:event type="COMPONENT">
    <aura:attribute name="record" type="String"/>
</aura:event>

ListItemCmp.cmp

<aura:compoent>
<aura:attribute name="item" type="String"/>
<aura:registerEvent name="sendRecordToParent" type="c:selectedRecordEvt"/>

      <li class="slds-dropdown__item">
          <a href="javascript:void(0);" role="menuitemradio" onclick="{!c.sendToParent}">
              <p class="slds-truncate">
                  <c:svg ariaHidden="true" class="slds-icon slds-icon--selected slds-icon--x-small slds-icon-text-default slds-m-right--x-small" xlinkHref="/resource/SLDS102/assets/icons/utility-sprite/svg/symbols.svg#check"/>
                  {!v.item}</p>
          </a>
      </li>
</aura:component>

ListItemCmpController.js

({
    sendToParent : function(component, event, helper) {
        var event = component.getEvent("sendRecordToParent");
        event.setParams({
            'record':component.get("v.item")
        });
        event.fire();
})

Also, the OP's solution :

var prodFam = event.currentTarget.childNodes[0].innerText; 

would also work if the element exist in the same namespace in the component.

  • Thank you so much for your extremely elaborated explanation. I am new to lightning. Hence, it was great to understand two different possible solutions. However, what I did is simply this. var prodFam = event.currentTarget.childNodes[0].innerText; I could get hold of the text inside the <li> perfectly. Could you tell me if this method has any drawbacks in your opinion? – Ayan Sengupta Jun 17 '16 at 8:14
  • 2
    Your code wont work in Org with locker service enabled – Praveen Jun 17 '16 at 8:18
  • 1
    More info about Locker Service and be found here – Praveen Jun 17 '16 at 8:23
  • 1
    Getting innerText will work fine under Locker as long as the element was created by a component in your namespace. In regards to the first way, it would be a lousy practice to store a small integer value in the HTML id attribute because that attribute must be unique across the whole page. Instead you can store it in a data- attribute such as data-index="4". You can then get these attributes out using element.dataset.index. – Charles T Jun 17 '16 at 13:57
  • I totally agree with you @CharlesT . I have updated the answer. – Praveen Jun 17 '16 at 14:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.