Show Lookup Combobox And Lightning Datatable in Quick Action Panel

May 09, 2023


 

This blog help you to how can set Lookup Combobox and Lightning Datable in QuickAction Panel. If you want to this you are at right place. To achieve this I have created two component in which one of them child component(named-comboxAndTableQuickAction) and other is parent component(named-parentComboWithTable). And also create apex class (named-comboboxAndTableQuickActionController) for showing data combobox and lightning datatable.

 

comboboxAndTableQuickActionController.cls

public with sharing class comoboboxAndTableQuickActionController {

    @AuraEnabled

    public static List<ResultWrapper> fetchRecords(SearchWrapper inputWrapper) {

        try {

            if(inputWrapper != null)

            {

                String fieldsToQuery = 'SELECT Id, ';

                if(string.isNotBlank(inputWrapper.fieldApiName)){

                    fieldsToQuery = fieldsToQuery + inputWrapper.fieldApiName;

                }

                String query = fieldsToQuery + ' FROM '+ inputWrapper.objectApiName;

                String filterCriteria = inputWrapper.fieldApiName + ' LIKE ' + '\'' + String.escapeSingleQuotes(inputWrapper.searchString.trim()) + '%\' LIMIT 10';

                if(String.isNotBlank(inputWrapper.selectedRecordId)) {

                    query += ' WHERE Id = \''+ inputWrapper.selectedRecordId + '\'';

                }

                else {

                    query += ' WHERE '+ filterCriteria;

                }

                List<ResultWrapper> returnWrapperList = new List<ResultWrapper>();

                for(SObject s : Database.query(query))

                {

                    ResultWrapper wrap = new ResultWrapper();

                    wrap.mainField = (String)s.get(inputWrapper.fieldApiName);

                    wrap.id = (String)s.get('id');

                    returnWrapperList.add(wrap);

                }

                return returnWrapperList;

            }

            return null;

        }

        catch (Exception err)

        {

            throw new AuraHandledException(err.getMessage());

        }

    }

 

    public class ResultWrapper{

        @AuraEnabled public String mainField{get;set;}

        @AuraEnabled public String subField{get;set;}

        @AuraEnabled public String id{get;set;}

    }

 

    public class SearchWrapper {

        @AuraEnabled public String objectApiName{get;set;}

        @AuraEnabled public String fieldApiName{get;set;}

        @AuraEnabled public String searchString{get;set;}

        @AuraEnabled public String selectedRecordId{get;set;}

    }

 

    @AuraEnabled

    public static void receiveOppId(String oppId)

    {

        System.debug('oppId::'+ oppId);

    }

 

    @AuraEnabled

    public static List<Trans__c> getTransRecords(String oppId)

    {

        List<Opportunity> opps = [Select Id, InvoiceNumber__c from Opportunity where Id = :oppId];

        String batchNumber = null;

        System.debug('opps:'+ opps);

        if(opps.isEmpty())

            return null;

        batchNumber = opps[0].InvoiceNumber__c;

        System.debug('BatchNo:'+ batchNumber);

        List<Trans__c> lstTrans = [Select Name, Batch__c, Agency__r.Name, Individual__r.Name,State__r.Name from Trans__c Where Batch__c =: batchNumber];

 

        System.Debug(' List: ' + lstTrans);

        return lstTrans;

    }

}

 

comboxAndTableQuickAction (Child Component)

comboxAndTableQuickAction.html

<template>

    <div class="slds-form-element slds-m-bottom_xx-large">

        <div class="slds-form-element__control">

            <div class="slds-combobox_container" if:false={isValueSelected}>

                <div class="slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click slds-is-open">

                    <div class="slds-combobox__form-element slds-input-has-icon slds-input-has-icon_right" role="none">

                        <lightning-input onchange={handleChange} type="search" autocomplete="off" label="Choose Opportunity"

                            required={required} field-level-help={helpText} placeholder={placeholder}

                            onblur={handleInputBlur}></lightning-input>

                    </div>

                </div>

            </div>

            <template if:true={isValueSelected}>

                <label class="slds-form-element__label" for="combobox-id-5" id="combobox-label-id-35">{label}</label>

                <template if:true={required}>

                    <span style="color:red">*</span>

                </template>

                <div tabindex="0" class="slds-combobox_container slds-has-selection">

                    <div class="slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click">

                        <div class="slds-combobox__form-element slds-input-has-icon slds-input-has-icon_left-right"

                            role="none">

                            <span

                                class="slds-icon_container slds-icon-standard-opportunity slds-combobox__input-entity-icon"

                                title="Opportunity">

                                <lightning-icon icon-name={selectedIconName} alternative-text={selectedIconName}

                                    size="x-small"></lightning-icon>

                            </span>

                            <button type="button"

                                class="slds-input_faux slds-combobox__input slds-combobox__input-value"

                                aria-labelledby="combobox-label-id-34 combobox-id-5-selected-value"

                                id="combobox-id-5-selected-value" aria-controls="listbox-id-5" aria-expanded="true"

                                aria-haspopup="listbox">

                                <span class="slds-truncate" id="combobox-value-id-19">{selectedRecordName}</span>

                            </button>

                            <button class="slds-button slds-button_icon slds-input__icon slds-input__icon_right"

                                title="Remove selected option" onclick={handleCommit}>

                                <lightning-icon icon-name="utility:close" alternative-text="Remove selected option"

                                    size="x-small"></lightning-icon>

                            </button>

                        </div>

                    </div>

                </div>

            </template>

 

            <template if:true={showRecentRecords}>

                <div id="listbox-id-4" tabindex="0" onblur={handleBlur} onmousedown={handleDivClick}

                    class="slds-dropdown slds-dropdown_length-with-icon-7 slds-dropdown_fluid" role="listbox">

                    <ul class="slds-listbox slds-listbox_vertical" role="presentation">

                        <template for:each={recordsList} for:item="rec">

                            <li role="presentation" key={rec.id} class="slds-listbox__item">

                                <div onclick={handleSelect} data-id={rec.id} data-mainfield={rec.mainField}

                                     class="slds-media slds-listbox__option slds-listbox__option_entity slds-listbox__option_has-meta"

                                    role="option">

                                    <span class="slds-media__figure slds-listbox__option-icon">

                                        <lightning-icon icon-name={selectedIconName} alternative-text={selectedIconName}

                                            size="small"></lightning-icon>

                                    </span>

                                    <span class="slds-media__body">

                                        <span class="slds-listbox__option-text slds-listbox__option-text_entity">

                                            <span>

                                                <mark>{rec.mainField}</mark>

                                            </span>

                                        </span>

                                    </span>

                                </div>

                            </li>

                        </template>

                    </ul>

                </div>

            </template>

        </div>

    </div>

</template>

 

comboxAndTableQuickAction.js

import { LightningElement, api} from 'lwc';

import fetchRecords from '@salesforce/apex/comoboboxAndTableQuickActionController.fetchRecords';

 

const DELAY = 500;

 

export default class ComboboxAndTableQuickAction extends LightningElement {

 

    @api recordId;

    @api helpText = "Help text";

    @api label = "Choose Opportunity";

    @api required;

    @api selectedIconName = "standard:opportunity";

    @api objectLabel = "Choose Opportunity";

    recordsList = [];

    selectedRecordName;

 

    @api objectApiName = "Opportunity";

    @api fieldApiName = "Name";

    @api searchString = "";

    @api selectedRecordId = "";

 

    preventClosingOfSerachPanel = false;

 

    get methodInput() {

        return {

            objectApiName: this.objectApiName,

            fieldApiName: this.fieldApiName,

            searchString: this.searchString,

            selectedRecordId: this.selectedRecordId,

        };

    }

    get showRecentRecords() {

        if (!this.recordsList) {

            return false;

        }

        return this.recordsList.length > 0;

    }

 

    connectedCallback() {

        if (this.selectedRecordId) {

            this.fetchSobjectRecords(true);

        }

    }

 

    fetchSobjectRecords(loadEvent) {

       

        fetchRecords({

            inputWrapper: this.methodInput

        }).then(result => {

            if (loadEvent && result) {

                this.selectedRecordName = result[0].mainField;

            } else if (result) {

                this.recordsList = JSON.parse(JSON.stringify(result));

            } else {

                this.recordsList = [];

            }

        }).catch(error => {

            console.log(error);

        })

    }

 

    get isValueSelected() {

        return this.selectedRecordId;

    }

 

    handleChange(event) {

        this.searchString = event.target.value;

        this.fetchSobjectRecords(false);

    }

 

    handleBlur() {

        this.recordsList = [];

        this.preventClosingOfSerachPanel = false;

    }

 

    handleDivClick() {

        this.preventClosingOfSerachPanel = true;

    }

 

    handleCommit() {

        this.selectedRecordId = "";

        this.selectedRecordName = "";

    }

 

    handleSelect(event) {

        let selectedRecord = {

            mainField: event.currentTarget.dataset.mainfield,

            subField: event.currentTarget.dataset.subfield,

            id: event.currentTarget.dataset.id

        };

        this.selectedRecordId = selectedRecord.id;

        this.selectedRecordName = selectedRecord.mainField;

        this.recordsList = [];

    }

 

    handleInputBlur(event) {

        window.clearTimeout(this.delayTimeout);

        this.delayTimeout = setTimeout(() => {

            if (!this.preventClosingOfSerachPanel) {

                this.recordsList = [];

            }

            this.preventClosingOfSerachPanel = false;

        }, DELAY);

    }

 

    @api

    getTransId()

    {

        console.log('getTransId');

        const selectedEvent = new CustomEvent('valueselected', {

            detail: this.selectedRecordId

        });

        //dispatching the custom event

        this.dispatchEvent(selectedEvent);

    }  

}

 

comboxAndTableQuickAction.js-meta.xml

<?xml version="1.0" encoding="UTF-8"?>

<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">

    <apiVersion>56.0</apiVersion>

    <isExposed>false</isExposed>

</LightningComponentBundle>

 

parentComboWithTable(Parent Component)

parentComboWithTable.html

<template>

    <lightning-quick-action-panel header="Search for Opportunity">

        <template lwc:if={transList}>

            <lightning-datatable key-field="Id" data={transList} columns={columns} hide-checkbox-column="true" >

            </lightning-datatable>

        </template>

        <template lwc:else>

            <c-combobox-and-table-in-quick-action label="Opportunity" selected-icon-name="standard:opportunity" object-label="Opportunity"

            object-api-name="Opportunity" field-api-name="Name"

             record-id={recordId}  onvalueselected={handleValueSelectedOnAccount}>

            </c-combobox-and-table-in-quick-action>

        </template>

       

        <div slot="footer">

            <lightning-button variant="neutral" label="Cancel" onclick={handleClose}></lightning-button>

            <template lwc:if={transList}>

                <lightning-button variant="brand" label="Save" class="slds-m-left_x-small" onclick={handleSave}></lightning-button>

            </template>

            <template lwc:else>

                <lightning-button variant="brand" label="Ahead" class="slds-m-left_x-small" onclick={handleNext}></lightning-button>

            </template>

           

        </div>

        </lightning-quick-action-panel>

</template>

 

parentComboWithTable.js

import { LightningElement, track, api } from 'lwc';

import { CloseActionScreenEvent } from 'lightning/actions';

import getTransRecords from '@salesforce/apex/comoboboxAndTableQuickActionController.getTransRecords'

import receiveOppId from '@salesforce/apex/comoboboxAndTableQuickActionController.receiveOppId'

import NAME from '@salesforce/schema/Trans__c.Name';

import BATCH from '@salesforce/schema/Trans__c.Batch__c';

 

export default class ParentComboWithTable extends LightningElement {

 

    @api recordId;

 

    @track

    transList

 

    oppId;

    errors;

 

    @track

    columns = [

        {

            label: 'Name',

            fieldName: NAME.fieldApiName,

            editable: false,

            type: 'text'

        },

        {

            label: 'Invoice',

            fieldName: BATCH.fieldApiName,

            editable: false

        },

        {

            label: 'Account',

            fieldName: 'Account',

            type: 'lookup'

        },

        {

            label: 'Individual',

            fieldName: 'Individual',

            editable: false

        },

        {

            label: 'State',

            fieldName: 'State',

            editable: false

        },

    ];

 

    handleSave(){

        console.log('Transmit !!')

        receiveOppId({oppId:this.oppId})

        .then(results => {

            console.log('Promise::', results);

            const toastEvent = new ShowToastEvent({

                title:'Success!',

                message:'Process Started!!',

                variant:'success'

            })

            this.dispatchEvent(toastEvent);

        })

        .catch(error => {

            this.errors = reduceErrors(error);

            console.log('Eror', this.errors);

        });

        this.dispatchEvent(new CloseActionScreenEvent());

       

    }

 

    handleNext(){

        console.log('handleNext start');

        this.template.querySelector('c-combobox-and-table-in-quick-action').getTransId();

        console.log('handleNext end');

    }

 

    handleClose() {

        this.dispatchEvent(new CloseActionScreenEvent());

    }

 

    @api

    handleValueSelectedOnAccount(event) {

        this.oppId = event.detail;

        console.log('oppId-->>'+ this.oppId);

 

        getTransRecords({oppId:this.oppId})

        .then(result  => {  

            console.log('result->' + result);

            console.log('JSON.stringify(result)->' + JSON.stringify(result));

            let parsedData = JSON.parse(JSON.stringify(result))

            parsedData.forEach(ele => {

                if(ele.Agency__c != undefined )

                    ele.Account = ele.Agency__r.Name;

                if(ele.Individual__c != undefined )

                    ele.Individual = ele.Individual__r.Name;

                if(ele.State__c != undefined )

                    ele.State = ele.State__r.Name;

            });

            this.transList = parsedData;

        })

        .catch(error => {

            this.errors = reduceErrors(error);

            console.log('Eror', this.errors);

        });

    }

}

 

parentComboWithTable.js-meta.xml

<?xml version="1.0" encoding="UTF-8"?>

<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">

    <apiVersion>56.0</apiVersion>

    <isExposed>true</isExposed>

    <targets>

        <target>lightning__RecordAction</target>

    </targets>

    <targetConfigs>

      <targetConfig targets="lightning__RecordAction">

        <actionType>ScreenAction</actionType>

      </targetConfig>

    </targetConfigs>

</LightningComponentBundle>

 

I hope this blog helped you!