Thursday, July 4, 2019

Lightning DataTable With Row Actions in Lightning Web Component(lwc)

This post explains how to handle row actions in the lightning data table in lightning web components(lwc)



Example:
HTML Code
<template>
     <lightning-card title="Datatable with Row Actions" icon-name="standard:contact" > <br/>
        <div style="width: auto;">
            <template if:true={data}>

                <lightning-datatable data={data}
                                     columns={columns}
                                     key-field="id"
                                     hide-checkbox-column="true"
                                     onrowaction={handleRowActions}></lightning-datatable>
            </template>

        </div>

        <!-- Spinner -->
        <div if:true={showLoadingSpinner}>
            <lightning-spinner alternative-text="Loading" size="large"></lightning-spinner>
        </div>

        <!-- Detail view modal -->
        <template if:true={bShowModal}>
            <section role="dialog" tabindex="-1"
                    aria-labelledby="modal-heading-01"
                    aria-modal="true"
                    aria-describedby="modal-content-id-1"
                    class="slds-modal slds-fade-in-open">
            <div class="slds-modal__container">
                <!-- modal header -->
                <header class="slds-modal__header">
                    <button class="slds-button slds-button_icon slds-modal__close slds-button_icon-inverse" title="Close" onclick={closeModal}>
                        <lightning-icon icon-name="utility:close" alternative-text="close" variant="inverse" size="small" ></lightning-icon>
                    </button>
                    
                    <h2 id="modal-heading-01" class="slds-text-heading_medium slds-hyphenate" if:false={isEditForm}>Record Detail</h2>
                    <h2 id="modal-heading-02" class="slds-text-heading_medium slds-hyphenate" if:true={isEditForm}>Update Record Values</h2>
                </header>
                <!-- modal body -->
                <div class="slds-modal__content slds-p-around_medium" id="modal-content-id-1" if:false={isEditForm}>
                    <dl class="slds-list_horizontal slds-wrap">
                        <dt class="slds-item_label slds-truncate" title="First Name">First Name:</dt>
                        <dd class="slds-item_detail slds-truncate">{record.FirstName}</dd>
                        <dt class="slds-item_label slds-truncate" title="LastName">Last Name:</dt>
                        <dd class="slds-item_detail slds-truncate">{record.LastName}</dd>
                        <dt class="slds-item_label slds-truncate" title="Phone">Phone :</dt>
                        <dd class="slds-item_detail slds-truncate"><lightning-formatted-phone value={record.Phone} ></lightning-formatted-phone></dd>
                        <dt class="slds-item_label slds-truncate" title="Email">Email :</dt>
                        <dd class="slds-item_detail slds-truncate"><lightning-formatted-email value={record.Email} ></lightning-formatted-email></dd>
                    </dl>
                </div>
                
                <!-- showing record edit form -->
                <div if:true={isEditForm} class="slds-theme_default">
                    <lightning-record-edit-form layout-type="Full" record-id={currentRecordId} object-api-name="Contact" onsubmit={handleSubmit} onsuccess={handleSuccess}>
                        <lightning-messages></lightning-messages>
                        <lightning-output-field field-name="AccountId"></lightning-output-field>
                        <lightning-input-field field-name="FirstName"></lightning-input-field>
                        <lightning-input-field field-name="LastName"></lightning-input-field>
                        <lightning-input-field field-name="Email"></lightning-input-field>
                        <lightning-input-field field-name="Phone"></lightning-input-field><br/>
                        
                        <div style="text-align:center;">
                            <lightning-button class="slds-m-top_small"
                                              variant="brand"
                                              type="submit"
                                              name="update"
                                              label="Update Record"></lightning-button>
                        </div>
                    </lightning-record-edit-form><br/>
                    <div></div>
                </div>

                <!-- modal footer start-->
                <footer class="slds-modal__footer" if:false={isEditForm}>
                    <lightning-button variant="brand"
                                      label="Close"
                                      title="Close"
                                      onclick={closeModal}></lightning-button>
                </footer>
            </div>
            </section>
            <div class="slds-backdrop slds-backdrop_open"></div>
           
        </template>
    </lightning-card>   
</template>
Javascript controller code
import {LightningElement, track, wire} from 'lwc';

// importing apex class methods
import getContacts from '@salesforce/apex/LWCExampleController.getContacts';
import delSelectedCons from '@salesforce/apex/LWCExampleController.deleteContacts';

// importing to show toast notifictions
import {ShowToastEvent} from 'lightning/platformShowToastEvent';

// importing to refresh the apex if any record changes the datas
import {refreshApex} from '@salesforce/apex';

// row actions
const actions = [
    { label: 'Record Details', name: 'record_details'}, 
    { label: 'Edit', name: 'edit'}, 
    { label: 'Delete', name: 'delete'}
];

// datatable columns with row actions
const columns = [
    { label: 'FirstName', fieldName: 'FirstName' }, 
    { label: 'LastName', fieldName: 'LastName' },
    { label: 'Phone', fieldName: 'Phone', type: 'phone'}, 
    { label: 'Email', fieldName: 'Email', type: 'email' }, 
    {
        type: 'action',
        typeAttributes: {
            rowActions: actions,
            menuAlignment: 'right'
        }
    }
];

export default class DeleteRowsInDatatableLWC extends LightningElement { 
    // reactive variable
    @track data;
    @track columns = columns;
    @track record = [];
    @track bShowModal = false;
    @track currentRecordId;
    @track isEditForm = false;
    @track showLoadingSpinner = false;

    // non-reactive variables
    selectedRecords = [];
    refreshTable;
    error;

    // retrieving the data using wire service
    @wire(getContacts)
    contacts(result) {
        this.refreshTable = result;
        if (result.data) {
            this.data = result.data;
            this.error = undefined;

        } else if (result.error) {
            this.error = result.error;
            this.data = undefined;
        }
    }

    handleRowActions(event) {
        let actionName = event.detail.action.name;

        window.console.log('actionName ====> ' + actionName);

        let row = event.detail.row;

        window.console.log('row ====> ' + row);
        // eslint-disable-next-line default-case
        switch (actionName) {
            case 'record_details':
                this.viewCurrentRecord(row);
                break;
            case 'edit':
                this.editCurrentRecord(row);
                break;
            case 'delete':
                this.deleteCons(row);
                break;
        }
    }

    // view the current record details
    viewCurrentRecord(currentRow) {
        this.bShowModal = true;
        this.isEditForm = false;
        this.record = currentRow;
    }

    // closing modal box
    closeModal() {
        this.bShowModal = false;
    }


    editCurrentRecord(currentRow) {
        // open modal box
        this.bShowModal = true;
        this.isEditForm = true;

        // assign record id to the record edit form
        this.currentRecordId = currentRow.Id;
    }

    // handleing record edit form submit
    handleSubmit(event) {
        // prevending default type sumbit of record edit form
        event.preventDefault();

        // querying the record edit form and submiting fields to form
        this.template.querySelector('lightning-record-edit-form').submit(event.detail.fields);

        // closing modal
        this.bShowModal = false;

        // showing success message
        this.dispatchEvent(new ShowToastEvent({
            title: 'Success!!',
            message: event.detail.fields.FirstName + ' '+ event.detail.fields.LastName +' Contact updated Successfully!!.',
            variant: 'success'
        }),);

    }

    // refreshing the datatable after record edit form success
    handleSuccess() {
        return refreshApex(this.refreshTable);
    }

    deleteCons(currentRow) {
        let currentRecord = [];
        currentRecord.push(currentRow.Id);
        this.showLoadingSpinner = true;

        // calling apex class method to delete the selected contact
        delSelectedCons({lstConIds: currentRecord})
        .then(result => {
            window.console.log('result ====> ' + result);
            this.showLoadingSpinner = false;

            // showing success message
            this.dispatchEvent(new ShowToastEvent({
                title: 'Success!!',
                message: currentRow.FirstName + ' '+ currentRow.LastName +' Contact deleted.',
                variant: 'success'
            }),);

            // refreshing table data using refresh apex
             return refreshApex(this.refreshTable);

        })
        .catch(error => {
            window.console.log('Error ====> '+error);
            this.dispatchEvent(new ShowToastEvent({
                title: 'Error!!', 
                message: error.message, 
                variant: 'error'
            }),);
        });
    }

}

Configuration XML File
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="DeleteRowsInDatatableLWC">
    <apiVersion>46.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
    </targets>
</LightningComponentBundle>
Apex Class
public inherited sharing class LWCExampleController {
    
    @AuraEnabled(Cacheable = true)
    public static List<Contact> getContacts(){
        return [SELECT Id, FirstName,LastName, Phone, Email FROM Contact ORDER BY Name limit 10];
    }
    
    @AuraEnabled
    public static void deleteContacts(list<Id> lstConIds){
        try {
            list<Contact> lstConsToDelete = new list<Contact>();
            System.debug('lstConIds ====> '+lstConIds);
            for(Id idCon : lstConIds) {
                lstConsToDelete.add(new Contact(Id = idCon));
            }
            if(!lstConsToDelete.isEmpty()) {
                delete lstConsToDelete;
            }
        }
        catch(Exception ex) {
            throw new AuraHandledException(ex.getMessage());
        }
    }
}
Result:

Resources:
lightning-datatable
record-edit-form

1 comment:

  1. It appears that the screenshot implies that these contacts belong to the account being viewed. I expected the getContacts() method then to return a list but accept a string -> the account.id to use in the query. That does not appear here...am I missing something?

    ReplyDelete