function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Daniel Watson 21Daniel Watson 21 

Lightning Datatable Bind or Update selectedRows (after init)

Hello Dev friends,

I have a Lightning:Datatable that is on a component in an aura:if set. The idea is that you can select a few things on the datatable, hit a "Save" button, and the items you selected will be displayed in the else section fo the aura:if set. Then you could hit a "Edit" button and the component will bring you back to the datatable with the items you that you already selected, pragmatically selected.

Component:

<aura:component controller="ReconciliationController" implements="flexipage:availableForRecordHome,force:hasRecordId" access="global">
	<!-- Attributes for the Component -->
    <aura:attribute name="recordId" type="Id" />
    <aura:attribute name="thisRecon" type="Reconciliation__c" />
    <aura:attribute name="editVList" type="Boolean" default="true" />
    
    <!-- Attributes for the Benefits Edit DataTable -->
    <aura:attribute name="tableCols" type="List" />
    <aura:attribute name="selectedRows" type="List" /> <!-- The rows to be displayed. -->
    <aura:attribute name="rowsSelected" type="List" /> <!-- The rows to be saved and displayed latter. -->
    
    <!-- Attributes for the Benefits Status List -->
    <aura:attribute name="benefits" type="Sobject[]" />
    
    <!-- Initializer -->
    <aura:handler name="init" action="{!c.doInit}" value="{!this}"/>
    
    <!-- Component -->
    <lightning:card title="Benefit Vendors" class="container" >
        <aura:if isTrue="{!v.editVList}">
            <lightning:datatable data="{!v.benefits}"
                                 columns="{!v.tableCols}"
                                 keyField="Id"
                                 selectedRows="{!v.selectedRows}"
                                 onrowselection="{!c.UpdateSelectedRows}" 
                             />
            <aura:set attribute="else">
                <aura:iteration items="{!v.benefits}" var="detail">
                        <div class="slds-grid" id="{! globalId + '-recordview-' + detail.Id }" style="padding-left: 20px; padding-top:5px; background-color: #ffe2e2">
                            <div class="slds-col slds-size_4-of-5">
                                <p>{!detail.vendorName}</p>
                            </div>
                            <div class="slds-col slds-size_1-of-5">
                                <lightning:input type="checkbox-button" checked="false" name="{!detail.Id}" onchange="{!c.CheckboxChangedEvent}" />
                            </div>
                        </div>
                </aura:iteration>
            </aura:set>
        </aura:if>
        <div style="padding-left: 20px; padding-top: 15px;">
            <lightning:button variant="brand" label="Save" onclick="{!c.EditVendorsListEvent}" />
        </div>
    </lightning:card>
</aura:component>

Currently flipping back and forth between the two datatable and iteration components clears out selectedRows. And if I try and set selectedRows, the datatable crashes and fials to load until I logout of my sandbox and then back in agian.

Controller:

({
    /** Client-side Controller **/
    doInit : function(component, event, helper) {
        helper.getThisReconciliation(component, helper);
        var cols = [
            {label: 'Vendor', fieldName: 'vendorName', type: 'text'},
            {label: 'Type', fieldName: 'recordName', type: 'text'},
            {label: 'Created', fieldName: 'created', type: 'Date'}
        ];
        component.set("v.tableCols", cols);
    },
    
    UpdateSelectedRows : function(component, event, helper) {
        var selectedRows = event.getParam('selectedRows');        
        var setRows = [];
        for (var i = 0; i < selectedRows.length; i++){
            setRows.push(selectedRows[i].Id);
        }
        console.log(setRows);
        component.set("v.rowsSelected", setRows); // <-- Crashed datatable if "v.selectedRows"
    },
    
    EditVendorsListEvent : function(component, event, helper) {
        var editVList = component.get("v.editVList");
        if (editVList == true) { // SAVE
            helper.updateReconciliationState(component);
            event.getSource().set('v.label','Edit');
            component.set("v.editVList", false);
        } else { // EDIT
            helper.editReconciliationState(component);
            event.getSource().set('v.label','Save');
			component.set("v.editVList", true);
			$A.get('e.force:refreshView').fire();            
        }
    }
})
Helpers:
({
    // DATA GETTERS AND SETTERS...
    
    updateReconciliationState : function(component) {
        var action = component.get("c.updateReconciliation");
        var reconciliation = component.get("v.thisRecon");
        var benefits = component.get("v.benefits");
        var rowsSelected = component.get('v.rowsSelected');
        var selectedRows = component.get('v.selectedRows');
        
        console.log("Reconciliation:");
        console.log(reconciliation);
        console.log("Benefits:");
        console.log(benefits);
        console.log("RowsSelected:");
        console.log(rowsSelected);
        console.log("SelectedRows:");
        console.log(selectedRows);
    },
    
    editReconciliationState : function(component) {
        var rowsSelected = component.get('v.rowsSelected');
        var selectedRows = component.get('v.selectedRows');
        
        console.log("RowsSelected:");
        console.log(rowsSelected);
        console.log("SelectedRows:");
        console.log(selectedRows);
        
        
        
        // component.set('v.selectedRows', rowsSelected); <-- causes datatable to crash...
    },
    
})

The purpose for v.rowsSelected and v.SelectedRows was me testing if my issue was coming from if you could not set SelectedRows directyl or not. Otherwise I will get rid of one.
 
Best Answer chosen by Daniel Watson 21
sfdcMonkey.comsfdcMonkey.com
Hi Daniel,
    if <aura:if> tag isTrue attribute set to false then it will be destroyed all elements inside True condition, in your case use Div  with 'slds-hide' class to show or hide div instead of using <aura:if> tag here is updated lightning component: 
<aura:component controller="ReconciliationController" implements="flexipage:availableForRecordHome,force:hasRecordId" access="global">
	<!-- Attributes for the Component -->
    <aura:attribute name="recordId" type="Id" />
    <aura:attribute name="thisRecon" type="Reconciliation__c" />
    <aura:attribute name="editVList" type="Boolean" default="true" />
    
    <!-- Attributes for the Benefits Edit DataTable -->
    <aura:attribute name="tableCols" type="List" />
    <aura:attribute name="selectedRows" type="List" /> <!-- The rows to be displayed. -->
    <aura:attribute name="rowsSelected" type="List" /> <!-- The rows to be saved and displayed latter. -->
    
    <!-- Attributes for the Benefits Status List -->
    <aura:attribute name="benefits" type="Sobject[]" />
    
    <!-- Initializer -->
    <aura:handler name="init" action="{!c.doInit}" value="{!this}"/>
    
    <!-- Component -->
    <lightning:card title="Benefit Vendors" class="container" >
   <div class="{!v.editVList ? 'slds-show' : 'slds-hide'}">
            <lightning:datatable data="{!v.benefits}"
                                 columns="{!v.tableCols}"
                                 keyField="Id"
                                 selectedRows="{!v.selectedRows}"
                                 onrowselection="{!c.UpdateSelectedRows}" 
                             />
           
        </div>
		
		
		 <div class="{!v.editVList ? 'slds-hide' : 'slds-show'}">
                <aura:iteration items="{!v.benefits}" var="detail">
                        <div class="slds-grid" id="{! globalId + '-recordview-' + detail.Id }" style="padding-left: 20px; padding-top:5px; background-color: #ffe2e2">
                            <div class="slds-col slds-size_4-of-5">
                                <p>{!detail.vendorName}</p>
                            </div>
                            <div class="slds-col slds-size_1-of-5">
                                <lightning:input type="checkbox-button" checked="false" name="{!detail.Id}" onchange="{!c.CheckboxChangedEvent}" />
                            </div>
                        </div>
                </aura:iteration>
         </div>
        <div style="padding-left: 20px; padding-top: 15px;">
            <lightning:button variant="brand" label="Save" onclick="{!c.EditVendorsListEvent}" />
        </div>
    </lightning:card>
</aura:component>
Thanks, let us know if it helps you 
sfdcmonkey.com




 

All Answers

Daniel Watson 21Daniel Watson 21
The Error I get when the table crashes...
TypeError: render threw an error in 'lightning:datatable' [e.indexes[t][l[0]] is undefined]
sfdcMonkey.comsfdcMonkey.com
Hi Daniel,
    if <aura:if> tag isTrue attribute set to false then it will be destroyed all elements inside True condition, in your case use Div  with 'slds-hide' class to show or hide div instead of using <aura:if> tag here is updated lightning component: 
<aura:component controller="ReconciliationController" implements="flexipage:availableForRecordHome,force:hasRecordId" access="global">
	<!-- Attributes for the Component -->
    <aura:attribute name="recordId" type="Id" />
    <aura:attribute name="thisRecon" type="Reconciliation__c" />
    <aura:attribute name="editVList" type="Boolean" default="true" />
    
    <!-- Attributes for the Benefits Edit DataTable -->
    <aura:attribute name="tableCols" type="List" />
    <aura:attribute name="selectedRows" type="List" /> <!-- The rows to be displayed. -->
    <aura:attribute name="rowsSelected" type="List" /> <!-- The rows to be saved and displayed latter. -->
    
    <!-- Attributes for the Benefits Status List -->
    <aura:attribute name="benefits" type="Sobject[]" />
    
    <!-- Initializer -->
    <aura:handler name="init" action="{!c.doInit}" value="{!this}"/>
    
    <!-- Component -->
    <lightning:card title="Benefit Vendors" class="container" >
   <div class="{!v.editVList ? 'slds-show' : 'slds-hide'}">
            <lightning:datatable data="{!v.benefits}"
                                 columns="{!v.tableCols}"
                                 keyField="Id"
                                 selectedRows="{!v.selectedRows}"
                                 onrowselection="{!c.UpdateSelectedRows}" 
                             />
           
        </div>
		
		
		 <div class="{!v.editVList ? 'slds-hide' : 'slds-show'}">
                <aura:iteration items="{!v.benefits}" var="detail">
                        <div class="slds-grid" id="{! globalId + '-recordview-' + detail.Id }" style="padding-left: 20px; padding-top:5px; background-color: #ffe2e2">
                            <div class="slds-col slds-size_4-of-5">
                                <p>{!detail.vendorName}</p>
                            </div>
                            <div class="slds-col slds-size_1-of-5">
                                <lightning:input type="checkbox-button" checked="false" name="{!detail.Id}" onchange="{!c.CheckboxChangedEvent}" />
                            </div>
                        </div>
                </aura:iteration>
         </div>
        <div style="padding-left: 20px; padding-top: 15px;">
            <lightning:button variant="brand" label="Save" onclick="{!c.EditVendorsListEvent}" />
        </div>
    </lightning:card>
</aura:component>
Thanks, let us know if it helps you 
sfdcmonkey.com




 
This was selected as the best answer
Daniel Watson 21Daniel Watson 21

You, my friend, are a gentalman and a scholar!

Makes sense now after reading the aura:if docs and what you said.

Much thanks! ~ Watson

Daniel Watson 21Daniel Watson 21
Hello piyush_soni,

I might still be haveing some issues with setting the selected rows. I see that you cannot set them until after the UI is rendered. So I have my component.set("v.selectedRows", setRows) in my "AfterRender", but they are still not being rendered. Any advice?
 
afterRender: function (component, helper) {
        this.superAfterRender();
        
        console.log("AFTER RENDER!");
        var rstate = component.get("v.selectedBenefits");
        console.log(rstate);
        var setRows = [];
        for (var i = 0; i < rstate.length; i++){
            setRows.push(rstate[i].Id);
        }
        console.log(setRows);
        component.set("v.selectedRows", setRows); // <-- Why does this not work...
},

my console.log(setRows); is giving me the proper Ids. And my capitalization and spelling is correct fot the component and data.