6

Assume the following pseudo-markup:

<component>
    <attribute recordList/>
    <button label="Add" onclick="{!c.addRec}"/>
    <accordion>
        <iterate over recordList using an indexVar>
            <accordionSection aura:id="{!'section_' + index}"/>
        </iterate>
    </accordion>
</component>

When the button is clicked the client-controller adds a new record to the recordList:

addRec : function(component, event, helper) {
    var ls = component.get('v.recordList');
    ls.push({'sobjectType':'Account'});
    component.set('v.recordList', ls);
}

Now I want the newly-added accordionSection to be auto-expanded. I know the corresponding class name is slds-is-open however I am not sure how to set it.

I guess one problem is, somehow the aura:ids of accordionSections don't get propagated to the resulting HTML. So if I do component.get('section_0') I get back undefined even if there are existing records in the list.

Of course I cannot set the CSS class for accordionSections directly in the markup either because the class gets applied to the outer element.

Any ideas would be appreciated.

6

You can't set an aura:id dynamically; it is used as a literal string, not an expression. Set the lightning:accordionSection name, then set the activeSectionName on the lightning:accordion element.

<lightning:accordion activeSectionName="{!v.activeSectionName}">
  <aura:iteration items="{!v.items}" var="item">
    <lightning:accordionSection name="{!item.Id}"> ... </lightning:accordionSection>
  </aura:iteration>
</lightning:accordion>

There is no need to specifically set slds-is-open anywhere.

However, you do need to wait for a render cycle, so you'll want to use setTimeout to specify the new section to set.

Here's a self-contained example for you.


<aura:application extends="force:slds">
    <aura:attribute name="items" type="List" default="[]" />
    <aura:attribute name="openSection" type="String" />

    <lightning:buttonIcon iconName="utility:add" onclick="{!c.add}" alternativeText="Add" />

    <lightning:accordion activeSectionName="{!v.openSection}">
        <aura:iteration items="{!v.items}" var="item">
            <lightning:accordionSection name="{!item.guid}" label="{!item.label}">
                {!item.content}
            </lightning:accordionSection>
        </aura:iteration>
    </lightning:accordion>
</aura:application>

({
    add: function(component, event, helper) {
        var items = component.get("v.items");
        items.push({ guid: 'guid'+items.length, label: "Item "+(1+items.length), content: "Sample Content" });
        component.set("v.items", items);
        setTimeout($A.getCallback(
            () => component.set("v.openSection", items[items.length-1].guid)
        ));
    }
})
  • Thanks -that worked. While at it, do you know why dynamic accordions (i.e. inside an iteration component) do not default-open the first section? I tried setting the names of accordions to "accName" and the activeSectionName="accName" expecting the framework to auto-open the first section but that didn't work. Is it because the sections are created dynamically, so that when the parent accordion is initialized it doesn't know about its children yet? – Mossi Feb 6 '18 at 6:00
  • @Mossi It's a timing issue with the rendering, as far as I can tell. I'm tempted to see if I can get in touch with someone that can look in to this. Ideally, it should work either way, without the setTimeout. – sfdcfox Feb 6 '18 at 6:04
  • Agreed. Either that, or if modifying components causes a re-render of affected elements the framework should also re-render any dependent nodes. This kind of obvious/trivial stuff should be abstracted away. – Mossi Feb 6 '18 at 6:31
  • In this regard - if you can help me out here - before i venture into building my own slds accordion. How would i achieve to expand/collapse all the sections on a button click. Setting activeSectionName would open only a single section and also how to close all ? @sfdcfox – owsata Feb 21 at 9:38
  • @owsata Set the activeSectionName to a list of sections to have open and you can expand all sections at once. Check the docs, but if you still have a question about this, feel free to ask a new question, include what you've tried so far, and we'll help you out. There's not quite enough space in comments to provide a full answer here. – sfdcfox Feb 21 at 10:57

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.