[SalesForce] Toggle buttonIcon inside

All,

I am new to lightning, hoping someone could provide me some pointers here:

Here's the requirement: Iterate over Basic Account Information object and display name, balance and status. Click on the buttonIcon to get additional information about the account and display it underneath the basic information.

Technical details: There are two separate APIs I call to get Basic Account Information and detailed account information:

Problem: When I click on the buttonIcon I want the plus sign to disappear and minus sign to appear. (See in the below code, iconName attribute).

Code: viewAccountsList.cmp

     <aura:iteration items="{!v.accountsList}" var="account" indexVar="i">
 <div class="slds-p-around--large">
     <div class="slds-page-header" style="cursor: pointer;">
      <section class="slds-clearfix">
        <div class="slds-float--left">
            <lightning:buttonIcon class="slds-show" value="{!account.id}" iconName="utility:add" size="x-small" alternativeText="Indicates add" onclick="{!c.toggleAccountSection}"/>
            <lightning:buttonIcon class="slds-hide" value="{!account.id}" iconName="utility:dash" size="x-small" alternativeText="Indicates dash" onclick="{!c.toggleAccountSection}"/>
        </div>
        <div class="slds-m-left--large">{!account.name}, {!account.accountManageStatus}, {!account.balance}</div>

      </section>
    </div>
  </div>
</aura:iteration>   

https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/js_cb_show_hide_markup.htm

The Salesforce developer site (above link) talks about assigning attribute to a tag to do the toggle action. cannot hold a variable value it has to be literal string. Since I want the id of the account to make the API call to get detailed account information. How can I make the toggle work in the ?

I am getting the accountId by calling event.getSource.get("v.value") in the controller.js

Best Answer

You could solve this a few ways. Probably the most commonly accepted is to make a custom component to wrap each instance of the iteration you're looping through, then give that component its own "toggle" method. Like this:

The list becomes:

<aura:iteration items="{!v.accountsList}" var="account" indexVar="i">
    <c:accountListItem acct="{!account}" />
</aura:iteration>

accountListItem.cmp looks like:

<aura:attribute type="boolean" name="showDetail" default="false" />
<aura:attribute type="object" name="acct" />
<aura:attribute type="object" name="detailData" />
<div class="slds-p-around--large">
     <div class="slds-page-header" style="cursor: pointer;">
      <section class="slds-clearfix">
        <div class="slds-float--left">
          <aura:if isTrue="{!v.displayDetail == false}">
            <lightning:buttonIcon iconName="utility:add" size="x-small" alternativeText="Indicates add" onclick="{!c.showAccountSection}"/>
          </aura:if>
          <aura:if isTrue="{!v.displayDetail == true}">
            <lightning:buttonIcon iconName="utility:dash" size="x-small" alternativeText="Indicates dash" onclick="{!c.hideAccountSection}"/>
          </aura:if>
        </div>
        <div class="slds-m-left--large">{!v.acct.name}, {!v.acct.accountManageStatus}, {!v.acct.balance}
        </div>

          </section>
        </div>
    </div>

you JS accountListItemController would have something like the following:

showAccountSection : function(component, event, helper){
    component.set('v.showDetail',true);
    helper.toggleAccountSection(component);
},
hideAccountSection : function(component, event, helper){
    component.set('v.showDetail',false);
}

And your helper that does the fetching of the account detail data would no longer need to use the Id from the button, but instead get it straight from the component property, like this:

toggleAccountSection : function(component){
    if(component.get('v.detailData') == null){
    // make your callout to get the detail info, and use
    // component.set('v.detailData',res.getReturnValue());
    // or something similar.
)
Related Topic