2

I display a menu in a lightning component. For that I get dynamically the element of the menu, and I display them with an aura:iteration, like this :

<ul class="messages-list" aura:id="main">
   <aura:iteration items="{!v.lThemes}" var="theme">
      <li class="message-item" onclick="{!c.getSelectedTheme}" data-id="{!theme.DeveloperName}" aura:id="{!theme.DeveloperName}">
            <a href="#" >
              <i class="{!'icon ' + theme.Icone__c}"></i>
              <span class="subject">{!theme.Theme__c}</span>
            </a>
       </li>
   </aura:iteration>
</ul>

In the <li> tag, I need to insert a class 'current' so I can apply some style to the selected element, when clicked. I try to do it with the JS method :

getSelectedTheme : function(component, event, helper){

    var selectedItem = event.currentTarget;
    var id = selectedItem.dataset.id;
    console.log('id : ' + id);

    var alreadySelectedElement = document.getElementsByClassName("current");
    for (var i = 0; i < alreadySelectedElement.length; i ++) {
        var val = alreadySelectedElement[i].getAttribute('data-id');
        alreadySelectedElement = component.find(val);
        console.log('val : ' + val);
        if(val != id){
            $A.util.removeClass(alreadySelectedElement, "current");
        }
    }

    var selectedElement = component.find(id);
    $A.util.addClass(selectedElement, "current");

}

But it does not work. If I use it with a non dynamic list (without aura:iteration) it works... But I need to make this list dynamic.

EDIT-------

I tried to change the component like this :

<aura:iteration items="{!v.lThemes}" var="theme" indexVar="indx">
    <li class="message-item" onclick="{!c.getSelectedTheme}" data-id="{!indx}" aura:id="testli" data-theme="{!theme.Theme__c}">
        <a href="#" >
            <i class="{!'icon ' + theme.Icone__c}"></i>
            <span class="subject">{!theme.Theme__c}</span>
        </a>
    </li>
</aura:iteration>

with the method of the controller :

var selectedItem = event.currentTarget;
    var id = selectedItem.dataset.id;

    var Elements = component.find('testli');
    console.log('Elements.length : ' + Elements.length);
    for (var i = 0; i < Elements.length; i++) {
        var val = Elements[i].getElement().getAttribute('data-id');

        if(val != id &&  $A.util.hasClass(Elements[i], "current")){
            $A.util.removeClass(Elements[i], "current");
        } else {
            $A.util.addClass(Elements[i], "current");
        }
    }

But it doesn't work as expected, the first time I click on an element, all the elements are selected (the class is applied to all) and after that if I click another element, it i correctly selected, but then if I click another element, the previous is deselected, but all the others are selected...

4
  1. Firstly You can't dynamically set aura:id based on aura:attribute for any component.Workaround( you can dynamically create the component using $A.createComponent and you can set aura:id dynamically).

  2. For this scenerio you can also create a child component for 'li' tag to change a class based on the element you click . By this you can avoid aura:id issue.

  3. You can also create using a single component itself by getting aura:Id as list and do the stuff there you have done some mistake in your code. I have included a sample code

    EXAMPLE:

Component:

<aura:component>
    <ul class="messages-list" aura:id="main">
        <aura:iteration items="['1','2']" var="theme" indexVar="indx">
            <li aura:id="testli" class="message-item" onclick="{!c.getSelectedTheme}" data-id="{!indx}" >
                {!indx}
            </li>
        </aura:iteration>
    </ul>
</aura:component >

Controller:

({
    getSelectedTheme : function(component, event, helper){

        var selectedItem = event.currentTarget;
        var id = selectedItem.dataset.id;

        var Elements = component.find('testli');

        for (var i = 0; i < Elements.length; i++) {
            var val = Elements[i].getElement().getAttribute('data-id');

            if(val != id){
                $A.util.removeClass(Elements[i], "current");
            } else {
                $A.util.addClass(Elements[i], "current");
            }
        }


    }
})
  • I tried you code but there is some problem : when I click an element, the class is applied to all elements – dou Feb 14 '18 at 12:49
  • It is correctly rendering to me can you update your question what you have tried now – vignesh Feb 14 '18 at 12:54
  • I just did it :) – dou Feb 14 '18 at 13:00
  • Is {!theme.DeveloperName} is unique – vignesh Feb 14 '18 at 13:08
  • no, it isn't. I tried to delete it, but I have the same behavior – dou Feb 14 '18 at 13:10

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.