1

I am trying to pass an iteration variable into my client side controller (I know there are a number of posts on this but haven't found any that work).

I've found some resources online that set iteration variables as a div id... for example:

    <aura:iteration items="{!v.newCases}" var="case">  
      <button type="button" onclick="{!c.showCaseDeleteModal}" id={!case.Id}>Delete</button> 
     </aura:iteration>

found at https://developer.salesforce.com/forums/?id=906F0000000kAn0IAE

However, this hasn't worked. Here is my code(iteration var is in quotes... both did not worked):

aura:

          <aura:iteration items="{!v.car_list}" var="car" indexVar="i">
              <div id="{!car.id}" class="expand-btn" onclick="{!c.expand}">
                <lightning:icon iconName="utility:threedots" size="x-small"  alternativeText="expand" />
              </div>
          </aura:iteration>

js:

expand: function(component, event, helper){
    var id = event.target.id;
    console.log('car_id', id);
    var div = document.getElementById('foo');
    if (div.style.display !== 'none') {
        div.style.display = 'none';
    }
    else {
        div.style.display = 'block';
    }
}
})

The only thing logged is 'car_id'.

1
  • What are you trying to do here and where is the foo element?
    – Saroj Bera
    Commented Jul 12, 2017 at 23:22

2 Answers 2

2

I figured out the issue. The above logic would work fine , however, using lightning:icon caused event.target to point to all of the stuff under the hood of this aura feature.

So in order to get around this I had to traverse up the dom to find the id that I wanted to access. Here is my updated code:

aura:

    <aura:iteration items="{!v.car_list}" var="car" indexVar="i">
            <li data-car-id="{!car.id}" class="car-element slds-item">
                  <div class="expand-btn" onclick="{!c.expand}">
                      <lightning:icon iconName="utility:threedots" size="x-small"  alternativeText="expand" />
                  </div>
            </li>
      </aura:iteration>

expand.js:

expand: function(component, event, helper){
    var car_element = event.target
    while (car_element.dataset.carId === undefined && car_element.parentNode !== undefined){
        car_element = car_element.parentNode;
    }
    var car_id = car_element.dataset.carId;
    var comment_panel_element = car_element.getElementsByClassName('comment-panel')[0];

    if (comment_panel_element.style.display !== 'none') {
        comment_panel_element.style.display = 'none';
    }
    else {
        comment_panel_element.style.display = 'block';
    }
}
3
  • 1
    Actually, if you move data-car-id to the div element instead, and use event.currentTarget.dataset.carId, you won't need the getElementsByClassName call nor need to traverse the DOM in any way. Be careful with the data-* attributes though, as they are formatted a certain way when you read them as javascript / object properties. For instance, they are case sensitive, and camel case if you use hyphens, etc. Commented Jul 13, 2017 at 0:19
  • Yeah I moved it to li because I plan to use car.id for other div elements in that li element.
    – Stuart
    Commented Jul 13, 2017 at 17:09
  • I think it’s better to use in your component aura:id with name and value tag and then on your controller component.find(“your Id”).get(“v.value”).. but I found it easier to break it into an inner component where I can easily capture all values from object passed
    – sfdx bomb
    Commented Aug 11, 2018 at 12:32
0

You're best off making the button it's own component and pass in any data as attributes. Then each instance of the component knows which data to use in it's js controller.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .