1

EDIT: Scroll to the bottom of this post for the working code.

I'm very much a beginner at using SalesForce so please forgive me if this question has a trivial solution :(

I have a DataTable filled with movie poster information (title, inventory count). I'm just trying to make an app that adds/deletes and if I have time, edits the entries.

Right now I'm trying to get deleting working. I've tried dissecting the example at https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/aura_compref_lightning_datatable.htm but I'm having trouble.

Javascript controller code:

deleteTableRow : function(component, row) {
    var action = component.get("c.deletePoster");
    action.setParams({
        "toDelete": row 
    });

    $A.enqueueAction(action);
    component.refreshDataTable();
}

Here is how I refresh my DataTable (code from the JS controller):

refreshDataTable : function(component, event, helper) {
    var refreshAction = component.get("c.getPosters");
    refreshAction.setCallback(this, function(data) {
       component.set("v.Poster", data.getReturnValue()); 
    });

    $A.enqueueAction(refreshAction);
},

Apex code for deleting and refreshing/populating the table:

@AuraEnabled
public static List<Poster__c> getPosters(){    
    return [Select ID__c, Count__c, Name From Poster__c];    
}

@AuraEnabled
public static void deletePoster(Poster__c toDelete){
    delete toDelete;
}

Markup (the relevant delete code is in the 2nd lightning card):

<aura:component controller="PostroApexController" implements="flexipage:availableForRecordHome" access="global">

    <aura:attribute name="Poster" type="Poster__c"/>
    <aura:attribute name="Posters" type="List"/>
    <aura:attribute name="Columns" type="List"/>
    <aura:attribute name="newPosterTitle" type="String"/>
    <aura:attribute name="newPosterCount" type="Decimal"/>

    <aura:method name="refreshDataTable" action="{!c.refreshDataTable}" 
                 description="refreshes datatable when data changes"/>

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

    <div class="width200">

        <lightning:card title="Postro SalesForce Demo" iconName="standard:account" footer="Some footer">

            <p>
                Postro is an inventory management system for movie theatres, specifically relating to movie poster stock.
            </p>


            <lightning:datatable data="{! v.Poster }" columns="{! v.Columns }" keyField="ID" hideCheckboxColumn="true"
                                 onrowselection="{! c.getSelectedID}"/>        
            <hr/>        
            <lightning:input type="text" label="Poster Title" name="posterTitle" value="{!v.newPosterTitle}"/>
            <lightning:input type="number" label="Poster Count" name="posterCount" value="{!v.newPosterCount}"/>
            <lightning:button type="submit" label="Add" name="btnAdd" onclick="{! c.addNewPoster}"/>

        </lightning:card>   

        <lightning:card title="Postro Tools" footer="Some footer">

            <lightning:button type="button" label="Delete" name="btnDelete" onclick="{! c.deleteTableRow}"/>

        </lightning:card>

    </div>




</aura:component>

Here are the fields on my Poster object: enter image description here

If I click "delete", nothing happens. How can I get this to work?


EDIT: Working code

Add new attribute to store selected rows:

<aura:attribute name="selectedRows" type="List"/>

Set DataTable's onrowselection to a JS component function to store the selected rows in the above attribute. My function is {! c.storeSelectedRows}.

Here is that function:

storeSelectedRows : function(component, event, helper){ 
    var selectedRows = event.getParam("selectedRows");
    component.set("v.selectedRows", selectedRows);
},

Finally the JS for deleting rows, set as the function for a "Delete" button. This function feels pretty hacky and could probably be made more efficient, but this works for my purposes for now:

deleteTableRows : function(component, event, helper) {

    var selectedPosters = component.get("v.selectedRows");
    var IDs = [];
    for (var i = 0; i < selectedPosters.length; i++){
        IDs[i] = selectedPosters[i].ID__c;
    }

    var action = component.get("c.deletePosterListByID");
    action.setParams({
        "idList": IDs
    });

    $A.enqueueAction(action);
    component.refreshDataTable();
}

The function to refresh is higher in this post. Thank you to everyone who helped me get here!

4
  • How are you refreshing the data table after delete? Can you post the contents of refreshDataTable?
    – Jayant Das
    Commented Apr 7, 2018 at 2:16
  • @JayantDas Hey, just edited my OP with both the JS and Apex code for that.
    – Dan
    Commented Apr 7, 2018 at 2:35
  • While invoking deleteRow, it seems you are not passing the selected row, which should be then passed on to the aura controller. When you invoke the deleteRow, you will need to make sure that you have the reference of the row that was selected to be deleted.
    – Jayant Das
    Commented Apr 7, 2018 at 3:17
  • Your design isn't very lightning-ish. You ideally should be using an action column if you want to have the deleteTableRow work the way you've written it. Try reading the documentation again, and read this answer for a full working example.
    – sfdcfox
    Commented Apr 7, 2018 at 3:36

1 Answer 1

4

In addition to what @sfdcfox mentioned, below is how you can modify your code to work. Though the below approach will enable your code to work, but follow a more efficient approach where you don't need to make a server trip after deleting the row, instead update the dataTable values, right in the deleteTableRow function as explained in the documentation.

Declare a variable which will capture the selected row, which you will need to use in deleteTableRow JS function.

    <aura:attribute name="selectedRow" type="Object"/>

Set the value of this attribute in the getSelectedID JS function as:

component.set("v.selectedRow", selectedRows[i]); // or however you are retrieving the selectedRow

Additionally, modify your deleteRow JS function as below to align as a JS controller function for the component and use the selectedRow attribute as above:

deleteTableRow : function(component, event, helper) {
    var action = component.get("c.deletePoster");
    var row = component.get("v.selectedRow"); 
    //rest of your code
6
  • Oddly enough I can't figure out how to actually get the selected row from the data table. Do you know where I could start?
    – Dan
    Commented Apr 7, 2018 at 6:04
  • @KingDan There is an example of how to get the selected rows from the event in the getSelectedName method in the documentation.
    – Keith C
    Commented Apr 7, 2018 at 10:13
  • Follow as suggested by @KeithC. Also recommend to remove hidecheckbox from your dataTable to allow selecting using checkboxes, that will help you to understand the flow. In my example above, its assumed there is always one row selected, and that’s how you can start as basics and then extend it further as you go in the learning process.
    – Jayant Das
    Commented Apr 7, 2018 at 12:59
  • @KeithC + Jayant Das Thanks for your help guys - my code implementation of the docs code isn't triggering and I think it's because the full row of the datatable isn't being selected. On click it selects just once cell at a time. I know in C# there is a FullRowSelect property that has to be changed to get full row select, is there something similar for the lightning datatable?
    – Dan
    Commented Apr 7, 2018 at 17:55
  • 1
    @KingDan I assume that the selection will only work when hideCheckboxColumn=false i.e. the checkbox column is showing.
    – Keith C
    Commented Apr 7, 2018 at 17:59

You must log in to answer this question.

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