1

I need to add collapsible/expandable rows based on an icon click. My code is effecting all the rows. But I need it for the specific rows where the user clicks on icons to expand or collapse. Below is the code:

Component:

<aura:component access="global">
    <aura:attribute name="dcrHistoryObject" type="Object" description="This is used to contain DataChangeRequestWrapper" access="public"/>
    <aura:attribute name="recordID" type="String" description="Record Identifier for dcrHistoryObject" access="public"/>
    <aura:attribute name="dcrStatus" type="String" description="DCR status" access="public" default ="Open"/>
    <aura:attribute name="toggleName" type="String" description="Toggle Name" access="public" default ="utility:chevrondown"/>
    <aura:attribute name="noOfChildRows" type="Integer" description="Number of Child Rows" access="public"/>
    <table class="slds-table slds-table_bordered" role="treegrid" aria-owns="tree0-node0 tree0-node1 tree0-node2 tree0-node3" 
        aria-readonly="true">
        <thead>
            <tr class="slds-text-title_caps">
                <th class="" scope="col">
                  <div class="slds-grid slds-grid_vertical-align-center">
                      <div class="slds-truncate slds-m-left_medium" title="{!!$Label.c.DCR_HistoryField}">{!$Label.c.DCR_HistoryField}</div>
                  </div>
                </th>
                <th scope="col">
                  <div class="slds-truncate" title="{!$Label.c.DCR_HistoryOldValue}">{!$Label.c.DCR_HistoryOldValue}</div>
                </th>
                <th scope="col">
                  <div class="slds-truncate" title="{!$Label.c.DCR_HistoryNewValue}">{!$Label.c.DCR_HistoryNewValue}</div>
                </th>
                <th scope="col">
                  <div class="slds-truncate" title="{!$Label.c.DCR_HistoryModifiedBy}">{!$Label.c.DCR_HistoryModifiedBy}</div>
                </th>
                <th scope="col">
                  <div class="slds-truncate" title="{!$Label.c.DCR_HistoryModifiedDate}">{!$Label.c.DCR_HistoryModifiedDate}</div>
                </th>                            
            </tr>
        </thead>

        <tbody>
            <aura:iteration items="{!v.dcrHistoryObject}" var="recordHistory" indexVar="recIndex">
                <aura:iteration items="{!recordHistory.fieldHistoryList}" var="historySobject" indexVar="historyIndex" end = "{!v.noOfChildRows}">  
                <tr>
                    <aura:if isTrue="{!historyIndex== 0}">
                        <th data-label="Account Name" scope="row" rowspan="{!recordHistory.fieldHistoryList.length}" 
                            style="vertical-align: top;" class ="slds-wrap slds-size_1-of-6">
                            <span style="display:flex;">
                                <lightning:buttonIcon iconName="{!v.toggleName}" variant="bare" size="x-small" alternativeText="Toggle" class="slds-m-right_x-small slds-shrink-none slds-table_tree__toggle" onclick = "{!c.toggleIcon}"/>
                                <div class="slds-truncate" title="{!recordHistory.keyFieldLabel}">
                                    {!recordHistory.keyFieldLabel}
                                </div>
                `            </span>
                        </th>
                    </aura:if>

                    <td role="gridcell" class="slds-wrap slds-size_1-of-6">
                        <aura:if isTrue="{!or(equals(historySobject.fieldType, 'DATE'), equals(historySobject.fieldType, 'DATETIME'))}">
                            <div class="slds-grid">
                              <div>
                                <lightning:input type="radio" name="{!add(add(recIndex,'-'), v.recordID)}" 
                                 value="{!historySobject.oldValue}"  onchange="{!c.selectHistoryValue}" 
                                 disabled="{!v.dcrStatus =='Closed'}"
                                 /> 
                              </div>
                              <div class="dcr-radio-label">
                                <aura:if isTrue="{!equals(historySobject.fieldType, 'DATETIME')}">
                                    <lightning:formattedDateTime value="{!historySobject.oldValue}"
                                    year="numeric" month="numeric" day="numeric"  hour="2-digit" minute="2-digit"/> 
                                    <aura:set attribute="else">
                                        <lightning:formattedDateTime value="{!historySobject.oldValue}"/>                           
                                    </aura:set>                                         
                                </aura:if>                  
                              </div>    
                            </div>   

                            <aura:set attribute="else">
                                <lightning:input type="radio" label="{!historySobject.oldLabel}" name="{!add(add(recIndex,'-'), v.recordID)}" value="{!historySobject.oldValue}"  onchange="{!c.selectHistoryValue}" 
                                disabled="{!or( equals(v.dcrStatus,'Closed')
                                                , and(
                                                    equals(historySobject.oldValue, NULL)
                                                    , equals(historySobject.fieldType, 'BOOLEAN')
                                                )
                                            )}"/> 
                            </aura:set>                         
                        </aura:if>                  
                    </td>
                    <td role="gridcell" class="slds-wrap slds-size_1-of-6">
                        <aura:if isTrue="{!or(equals(historySobject.fieldType, 'DATE'), equals(historySobject.fieldType, 'DATETIME'))}">
                            <div class="slds-grid">
                              <div>
                                <lightning:input type="radio" name="{!add(add(recIndex,'-'), v.recordID)}" 
                                 value="{!historySobject.newValue}"  onchange="{!c.selectHistoryValue}" 
                                 disabled="{!v.dcrStatus =='Closed'}" checked="true"
                                 /> 
                              </div>
                              <div class="dcr-radio-label">
                                <aura:if isTrue="{!equals(historySobject.fieldType, 'DATETIME')}">
                                    <lightning:formattedDateTime value="{!historySobject.newValue}"
                                    year="numeric" month="numeric" day="numeric"  hour="2-digit" minute="2-digit"/> 
                                    <aura:set attribute="else">
                                        <lightning:formattedDateTime value="{!historySobject.newValue}"/>                           
                                    </aura:set>                                         
                                </aura:if>                  
                              </div>    
                            </div>   

                            <aura:set attribute="else">
                                <lightning:input type="radio" label="{!historySobject.newLabel}" name="{!add(add(recIndex,'-'), v.recordID)}" value="{!historySobject.newValue}" onchange="{!c.selectHistoryValue}" checked="true" disabled="{!v.dcrStatus =='Closed'}"/> 
                            </aura:set>                         
                        </aura:if>                  
                    </td>

                    <td role="gridcell" class="slds-wrap slds-size_1-of-6">
                        <div class="slds-truncate">{!historySobject.createdBy} </div>
                    </td>
                    <td role="gridcell" class="slds-wrap slds-size_2-of-6">
                        {!historySobject.formattedCreatedDate}
                    </td>
                </tr>
                </aura:iteration> 
            </aura:iteration>
        </tbody>
    </table>
</aura:component>

Controller js:

({
    selectHistoryValue : function(component, event, helper) { 
        var source = event.getSource();
        // selected value of a row
        var selectedValue = source.get('v.value');
        // Get name property of a row
        var name = source.get('v.name');
        // Get row index
        var rowIndex = name.split("-")[0];

        var recordHistory = component.get('v.dcrHistoryObject');
        // set selectedValue for a specific row
        if(recordHistory !=null && recordHistory.length>0 && rowIndex < recordHistory.length){
            recordHistory[rowIndex].value = selectedValue;  
        }
        component.set('v.dcrHistoryObject', recordHistory);
    },

    toggleIcon : function(component, event, helper) { 
        var toggleName =  component.get('v.toggleName');
        if(toggleName == "utility:chevrondown"){
            component.set('v.toggleName',"utility:chevronright");
            component.set('v.noOfChildRows',"1");
        }
        else{
            component.set('v.toggleName',"utility:chevrondown");
            component.set('v.noOfChildRows','v.historyIndex');
        }
    },
     makeRowCompact: function(component, event, helper) {
        component.set("v.compact", true);
    },

    makeRowDetailed: function(component, event, helper) {
        component.set("v.compact", false);
    },
})
2

You need one Boolean value per row. Typically, the easy way to do this it to include it directly in the data, or as a related array. Here's a very simple copy-paste example for you.


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

    <aura:handler name="init" value="{!this}" action="{!c.init}" />

    <lightning:layout multipleRows="true">
        <aura:iteration items="{!v.items}" var="item" indexVar="itemIndex">
            <lightning:layoutItem size="12">

                <h1>
                    <lightning:buttonIcon value="{!itemIndex}" onclick="{!c.toggle}" iconName="{!item.expanded?'utility:chevrondown':'utility:chevronright'}" />
                    {!item.title}
                </h1>
                <aura:if isTrue="{!item.expanded}">
                    <div>
                        Extra content would be shown here.
                    </div>
                </aura:if>
            </lightning:layoutItem>
        </aura:iteration>
    </lightning:layout>
</aura:application>

({
    init: function(component, event, helper) {
        component.set("v.items", [
            { expanded: false, title: "Row 1" },
            { expanded: false, title: "Row 2" },
            { expanded: false, title: "Row 3" }
        ]);
    },
    toggle: function(component, event, helper) {
        var items = component.get("v.items"), index = event.getSource().get("v.value");
        items[index].expanded = !items[index].expanded;
        component.set("v.items", items);
    }
})

Notice here how I set the Boolean value for the row I want to toggle. Doing this allows any number of rows to be collapsed/expanded as I desire.

  • This approach perfectly worked for my requirement. Thank you so much for the help. – Subbarao Muppaneni Feb 7 '18 at 17:11

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.