2

In my lightning component, I have a table with column that has a menu in it. The menu items are for edit and delete. I'm trying to find a way to get the row that was clicked on and so far everything thing I've found/tried hasn't worked. This is in a Summer 16 sandbox w/Locker Service enabled.

These approaches no longer work:

Here is the top level component:

<aura:component implements="flexipage:availableForAllPageTypes,force:appHostable,force:hasRecordId">
<c:AffiliationsList curRecordId="{!v.recordId}" />
<c:AffiliationDetails />

Here is the component that has the datagrid:

<aura:component implements="flexipage:availableForAllPageTypes,force:appHostable" controller="AffiliationController">
<ltng:require styles="/resource/SLDS103/assets/styles/salesforce-lightning-design-system-ltng.min.css"/>

<aura:attribute name="curRecordId" type="String"/>
<aura:attribute name="afList" type="AffiliationWrapper[]"/>
<aura:attribute name="numAf" type="Integer" default="0"/>

<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<aura:registerEvent name="appEvent" type="c:affiliationToEdit"/>

<div class="slds">
    <div class="slds-card">
        <div class="slds-card__header slds-grid">
            <div class="slds-media slds-media--center slds-has-flexi-truncate">
                <div class="slds-media__figure">
                    <c:svg class="slds-icon slds-icon-standard-contact slds-icon--small" xlinkHref="/resource/SLDS103/assets/icons/standard-sprite/svg/symbols.svg#contact"/>
                </div>
                <div class="slds-media__body">
                    <h2 class="slds-text-heading--small slds-truncate">Affiliations ({!v.numAf})</h2>
                </div>
            </div>
        </div>
        <div class="slds-card__body">
            <table class="slds-table slds-table--bordered slds-table--striped slds-max-medium-table--stacked-horizontal">
                <thead>
                    <tr class="slds-text-heading--label">
                        <th class="slds-is-sortable" scope="col">
                            <div class="slds-truncate">Relationship
                                <button class="slds-button slds-button--icon-bare">
                                    <c:svg class="slds-button__icon slds-button__icon--small" xlinkHref="/resource/SLDS103/assets/icons/utility-sprite/svg/symbols.svg#arrowdown"/>
                                    <span class="slds-assistive-text">Relationship</span>
                                </button>
                            </div>
                        </th>
                        <th class="slds-is-sortable" scope="col">
                            <div class="slds-truncate">Status
                                <button class="slds-button slds-button--icon-bare">
                                    <c:svg class="slds-button__icon slds-button__icon--small" xlinkHref="/resource/SLDS103/assets/icons/utility-sprite/svg/symbols.svg#arrowdown"/>
                                    <span class="slds-assistive-text">Status</span>
                                </button>
                            </div>
                        </th>
                        <th class="slds-is-sortable" scope="col">
                            <div class="slds-truncate">Project
                                <button class="slds-button slds-button--icon-bare">
                                    <c:svg class="slds-button__icon slds-button__icon--small" xlinkHref="/resource/SLDS103/assets/icons/utility-sprite/svg/symbols.svg#arrowdown"/>
                                    <span class="slds-assistive-text">Project</span>
                                </button>
                            </div>
                        </th>
                        <th class="slds-is-sortable" scope="col">
                            <div class="slds-truncate">Sub-Project
                                <button class="slds-button slds-button--icon-bare">
                                    <c:svg class="slds-button__icon slds-button__icon--small" xlinkHref="/resource/SLDS103/assets/icons/utility-sprite/svg/symbols.svg#arrowdown"/>
                                    <span class="slds-assistive-text">Sub-Project</span>
                                </button>
                            </div>
                        </th>
                        <th class="slds-is-sortable" scope="col">
                            <div class="slds-truncate">Task
                                <button class="slds-button slds-button--icon-bare">
                                    <c:svg class="slds-button__icon slds-button__icon--small" xlinkHref="/resource/SLDS103/assets/icons/utility-sprite/svg/symbols.svg#arrowdown"/>
                                    <span class="slds-assistive-text">Task</span>
                                </button>
                            </div>
                        </th>
                        <th class="slds-is-sortable" scope="col">
                            <div class="slds-truncate">Notes
                                <button class="slds-button slds-button--icon-bare">
                                    <c:svg class="slds-button__icon slds-button__icon--small" xlinkHref="/resource/SLDS103/assets/icons/utility-sprite/svg/symbols.svg#arrowdown"/>
                                    <span class="slds-assistive-text">Notes</span>
                                </button>
                            </div>
                        </th>
                        <th class="slds-cell-shrink"></th>
                    </tr>
                </thead>
                <tbody>
                    <aura:iteration items="{!v.afList}" var="af" indexVar="idx">
                        <tr class="slds-hint-parent slds-has-flexi-truncate" id="{!idx}">
                            <td class="slds-truncate slds-cell-wrap" data-label="Relationship">{!af.relationship}</td>
                            <td class="slds-truncate" data-label="Status">{!af.status}</td>
                            <td class="slds-truncate slds-cell-wrap" data-label="Project">
                                <a >{!af.project}</a>
                            </td>
                            <td class="slds-truncate slds-cell-wrap" data-label="Sub-Project">{!af.subProject}</td>
                            <td class="slds-truncate slds-cell-wrap" data-label="Task">{!af.task}</td>
                            <td class="slds-truncate slds-cell-wrap" data-label="Notes">{!af.note}</td>
                            <td class="slds-cell-shrink" data-label="Actions">
                                <ui:button aura:id="edit" label="Edit" press="{!c.editAffiliation}"/>
                                <!-- <ui:menu>
                                    <ui:menuTriggerLink aura:id="trigger" title="more"/>
                                    <ui:menuList class="actionMenu" aura:id="actionMenu">
                                        <ui:actionMenuItem aura:id="edit" label="Edit" click="{!c.editAffiliation}"/>
                                        <ui:actionMenuItem aura:id="delete" label="Delete" click="{!c.deleteAffiliation}"/>
                                    </ui:menuList>
                                </ui:menu> -->
                            </td>
                        </tr>
                    </aura:iteration>
                </tbody>
            </table>
        </div>
    </div>
</div>

Here is the controller:

({
    doInit : function(component, event, helper) {
        helper.loadAffiliations(component, event);
    },
    editAffiliation : function(component, event, helper) {
        helper.editRecord(component, event);
    }
})

Here is the helper:

({
    loadAffiliations : function(cmp, ev) {
        var action = cmp.get("c.getAffiliations");
        action.setParams({
            "currentId": cmp.get("v.curRecordId")
        });
        action.setCallback(this, function(response) {
            var state = response.getState();
            if(state === "SUCCESS") {
                var affiliations = response.getReturnValue();
                cmp.set('v.numAf', affiliations.length);
                cmp.set('v.afList', affiliations);
            }
            else if (state === "ERROR") {
                console.log('errors', response.getError());
            }
        });
        $A.enqueueAction(action);
    },
    editRecord : function(cmp, ev) {
        var row = cmp.getEvent("editAffiliation");
        console.log('row', row);
    }
})

console.log('row', row); logs out as null.

Originally my approach was just to pull the indexVar and then I'd be set but that's when I started finding out that none of the old ways worked anymore.

In my function, I'm thinking I should be able to get the value via getSource() on the event, but so far I haven't been able to figure out what, if any, key holds that value. It seems there should be a way to get to the dataset. Is there anyway to get the value for data-index from the event? It appears that the Locker Service has blocked everything. Or is there another approach that would work better? Any suggestions?

7
  • Try deleting rows using Event mechanism,check out my answer
    – Praveen
    Commented May 16, 2016 at 14:43
  • @Praveen That doesn't appear to work... logs out as null editRecord : function(cmp, ev) { var row = cmp.getEvent("editAffiliation"); console.log('row', row); }
    – Evan S.
    Commented May 16, 2016 at 15:13
  • Please post enough code by editing your question,so that i can help you out.
    – Praveen
    Commented May 16, 2016 at 15:18
  • There really isn't anything to post other than my controller method editAffiliation which just calls the helper editRecord method which is what I pasted above. editAffiliation : function(component, event, helper) { helper.editRecord(component, event); } I was just starting on this part of the functionality and ran into the issue of not being able to identify which row to edit.
    – Evan S.
    Commented May 16, 2016 at 15:28
  • No need to include the apex controller,just post your component,it's controller.js and helper.js and also Lightning Event (.evt) file alone.
    – Praveen
    Commented May 16, 2016 at 15:33

2 Answers 2

0

I believe the Event driven mechanism is probably the right way to handle this,instead of relying on the dataset attributes on the DOM.Inorder to do so,you have to split the component into two parts:

1.AffiliationsList - (fetches the data) -> Parent Component

2.AffiliationsListItem - (displays each record,fires selected data for edit) -> Child component

AffiliationsList.cmp

<aura:component implements="flexipage:availableForAllPageTypes,force:appHostable" controller="AffiliationController">
<ltng:require styles="/resource/SLDS103/assets/styles/salesforce-lightning-design-system-ltng.min.css"/>

<aura:attribute name="curRecordId" type="String"/>
<aura:attribute name="afList" type="AffiliationWrapper[]"/>
<aura:attribute name="numAf" type="Integer" default="0"/>

<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<aura:handler name="appEvent" event="c:affiliationToEdit" action="{!c.editAffiliation}" />

<div class="slds">
    <div class="slds-card">
        <div class="slds-card__header slds-grid">
            <div class="slds-media slds-media--center slds-has-flexi-truncate">
                <div class="slds-media__figure">
                    <c:svg class="slds-icon slds-icon-standard-contact slds-icon--small" xlinkHref="/resource/SLDS103/assets/icons/standard-sprite/svg/symbols.svg#contact"/>
                </div>
                <div class="slds-media__body">
                    <h2 class="slds-text-heading--small slds-truncate">Affiliations ({!v.numAf})</h2>
                </div>
            </div>
        </div>
        <div class="slds-card__body">
            <table class="slds-table slds-table--bordered slds-table--striped slds-max-medium-table--stacked-horizontal">
                <thead>
                    <tr class="slds-text-heading--label">
                        <th class="slds-is-sortable" scope="col">
                            <div class="slds-truncate">Relationship
                                <button class="slds-button slds-button--icon-bare">
                                    <c:svg class="slds-button__icon slds-button__icon--small" xlinkHref="/resource/SLDS103/assets/icons/utility-sprite/svg/symbols.svg#arrowdown"/>
                                    <span class="slds-assistive-text">Relationship</span>
                                </button>
                            </div>
                        </th>
                        <th class="slds-is-sortable" scope="col">
                            <div class="slds-truncate">Status
                                <button class="slds-button slds-button--icon-bare">
                                    <c:svg class="slds-button__icon slds-button__icon--small" xlinkHref="/resource/SLDS103/assets/icons/utility-sprite/svg/symbols.svg#arrowdown"/>
                                    <span class="slds-assistive-text">Status</span>
                                </button>
                            </div>
                        </th>
                        <th class="slds-is-sortable" scope="col">
                            <div class="slds-truncate">Project
                                <button class="slds-button slds-button--icon-bare">
                                    <c:svg class="slds-button__icon slds-button__icon--small" xlinkHref="/resource/SLDS103/assets/icons/utility-sprite/svg/symbols.svg#arrowdown"/>
                                    <span class="slds-assistive-text">Project</span>
                                </button>
                            </div>
                        </th>
                        <th class="slds-is-sortable" scope="col">
                            <div class="slds-truncate">Sub-Project
                                <button class="slds-button slds-button--icon-bare">
                                    <c:svg class="slds-button__icon slds-button__icon--small" xlinkHref="/resource/SLDS103/assets/icons/utility-sprite/svg/symbols.svg#arrowdown"/>
                                    <span class="slds-assistive-text">Sub-Project</span>
                                </button>
                            </div>
                        </th>
                        <th class="slds-is-sortable" scope="col">
                            <div class="slds-truncate">Task
                                <button class="slds-button slds-button--icon-bare">
                                    <c:svg class="slds-button__icon slds-button__icon--small" xlinkHref="/resource/SLDS103/assets/icons/utility-sprite/svg/symbols.svg#arrowdown"/>
                                    <span class="slds-assistive-text">Task</span>
                                </button>
                            </div>
                        </th>
                        <th class="slds-is-sortable" scope="col">
                            <div class="slds-truncate">Notes
                                <button class="slds-button slds-button--icon-bare">
                                    <c:svg class="slds-button__icon slds-button__icon--small" xlinkHref="/resource/SLDS103/assets/icons/utility-sprite/svg/symbols.svg#arrowdown"/>
                                    <span class="slds-assistive-text">Notes</span>
                                </button>
                            </div>
                        </th>
                        <th class="slds-cell-shrink"></th>
                    </tr>
                </thead>
                <tbody>
                    <aura:iteration items="{!v.afList}" var="af" indexVar="idx">
                        <c:AffiliationsListItem afRec="{!v.af}"
                    </aura:iteration>
                </tbody>
            </table>
        </div>
    </div>
</div>
</aura:component/>

AffiliationsListController.js

({
    doInit : function(component, event, helper) {
        helper.loadAffiliations(component, event);
    },
    editAffiliation : function(component, event, helper) {
        helper.editRecord(component,event);
    }
})

AffiliationsListHelper.js

({
    loadAffiliations : function(cmp, ev) {
        var action = cmp.get("c.getAffiliations");
        action.setParams({
            "currentId": cmp.get("v.curRecordId")
        });
        action.setCallback(this, function(response) {
            var state = response.getState();
            if(state === "SUCCESS") {
                var affiliations = response.getReturnValue();
                cmp.set('v.numAf', affiliations.length);
                cmp.set('v.afList', affiliations);
            }
            else if (state === "ERROR") {
                console.log('errors', response.getError());
            }
        });
        $A.enqueueAction(action);
    },
    editRecord : function(cmp, ev) {
        var row = event.getParam("selectedAffliation");
        console.log('row', row);
    }
})

Assuming your component level event looks like this :

affiliationToEdit.evt

<aura:event type="COMPONENT" description="Affiliation To Edit Event">
    <aura:attribute name="selectedAffliation" type="Object"/>
</aura:event>

AffiliationsListItem.cmp

<aura:component>
    <aura:attribute name="afRec" type="Object"/>
    <aura:registerEvent name="appEvent" type="c:affiliationToEdit"/>

    <tr class="slds-hint-parent slds-has-flexi-truncate">
        <td class="slds-truncate slds-cell-wrap" data-label="Relationship">{!v.afRec.relationship}</td>
        <td class="slds-truncate" data-label="Status">{!v.afRec.status}</td>
        <td class="slds-truncate slds-cell-wrap" data-label="Project">
            <a >{!v.afRec.project}</a>
        </td>
        <td class="slds-truncate slds-cell-wrap" data-label="Sub-Project">{!v.afRec.subProject}</td>
        <td class="slds-truncate slds-cell-wrap" data-label="Task">{!v.afRec.task}</td>
        <td class="slds-truncate slds-cell-wrap" data-label="Notes">{!v.afRec.note}</td>
        <td class="slds-cell-shrink" data-label="Actions">
            <ui:button aura:id="edit" label="Edit" press="{!c.editAffiliationRecord}"/>
            <!-- <ui:menu>
            <ui:menuTriggerLink aura:id="trigger" title="more"/>
            <ui:menuList class="actionMenu" aura:id="actionMenu">
            <ui:actionMenuItem aura:id="edit" label="Edit" click="{!c.editAffiliation}"/>
            <ui:actionMenuItem aura:id="delete" label="Delete" click="{!c.deleteAffiliation}"/>
            </ui:menuList>
            </ui:menu> -->
        </td>
    </tr>
</aura:component>

AffiliationsListItemController.js

({  //Fires the event to the parent,to capture the selected affliation record.
    editAffiliationRecord : function(component, event, helper) {
        var event = component.getEvent("appEvent");
        event.setParams({
            'selectedAffliation':component.get("v.afRec")
        });
        event.fire();
    }
})
4
  • Thanks @Praveen Does the nested component support sorting on the table? I was planning to use sortable or Tablesorter so that's why I steered away from this approach.
    – Evan S.
    Commented May 16, 2016 at 17:56
  • I'm not really sure about the sortable in a nested component
    – Praveen
    Commented May 16, 2016 at 17:58
  • 1
    I think your listItem component can fire a 'sort' event with parameter "asc" or "desc". The list component can handle that event and sort the afList array. This will rerender all the items in the list and display in sorted order. Commented May 16, 2016 at 21:32
  • @prashanthkr that might work... thanks for the idea!
    – Evan S.
    Commented May 17, 2016 at 20:16
0

With the latest patch, we can now get to the element with event.srcElement so that solves my issue. I'm setting the id equal to the index and that's exactly what I was after!

<a href="javascript:void(0);" id="{!idx}" onclick="{!c.editAffiliation}">Edit</a>

editAffiliation : function(component, event, helper) {
    helper.editRecord(component, event);
}

editRecord : function(cmp, ev) {
    var afList = cmp.get('v.afList');
    var affiliation = afList[ev.srcElement.id];
    this.openModal(affiliation);
}
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .