Friday, November 1, 2019

Reusable Picklist in Salesforce using Lightning web components(lwc)

This post explains how to implement reusable picklist in the lightning web component(lwc)


To get the picklist values in lightning web components we can use 'getPicklistValues' or 'getPicklistValuesByRecordType' wire adapters, these wire adapters uses the lightning/uiObjectInfoApi scoped module to get the picklist values based on specific Field or based on Record Type.

HTML Code
<template>
    <lightning-combobox label={picklistlabel} 
                        name={picklistlabel} 
                        onchange={handleValueChange} 
                        options={options} 
                        placeholder="--None--" 
                        value={selectedValue}></lightning-combobox>
    <div if:true={error} style="margin-left:3%">
        <b style="color: red;">{error}</b>
    </div>
</template>
Javascript Controller
import {LightningElement, api, track, wire} from 'lwc';
import {getPicklistValues, getObjectInfo} from 'lightning/uiObjectInfoApi';

export default class Reusepicklistinlwc extends LightningElement {
    @api objAPIName;
    @api fieldAPIName;
    @track options = [];
    // pick list label
    @track picklistlabel;
    @track error;

    recordTypeId;
    objfieldAPIName;

    @wire(getObjectInfo, {objectApiName: '$objAPIName'})
    objectInfo(result) {
        if(result.data) {
            // Field Data
            let fieldData = result.data.fields[this.fieldAPIName];
            if(fieldData) {
                this.picklistlabel = fieldData.label;
            
                this.objfieldAPIName = {};
                this.objfieldAPIName.fieldApiName = fieldData.apiName;
                this.objfieldAPIName.objectApiName = result.data.apiName;
    
                this.recordTypeId = result.data.defaultRecordTypeId;
            }
            else {
                this.error = 'Please enter valid field api name';
            }
        }
        else if(result.error) {
            this.error = JSON.stringify(result.error);
        }
    }
    
    @wire(getPicklistValues, { recordTypeId: '$recordTypeId', fieldApiName: '$objfieldAPIName'})
    picklistValues({error, data}) {
        if (data) {

            let picklistOptions = [{ label: '--None--', value: '--None--'}];

            // Picklist values
            data.values.forEach(key => {
                picklistOptions.push({
                    label: key.label, 
                    value: key.value
                })
            });

            this.options = picklistOptions;

        } else if (error) {
            this.error = JSON.stringify(error);
        }
    }


    handleValueChange(event) {
        this.selectedValue = event.target.value;
    }
}

Configuration File
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="reusepicklistinlwc">
    <apiVersion>46.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
    </targets>
</LightningComponentBundle>

How to use the component

Add this component in your parent component and pass object API name and field API name

Ex:
<template>
    <lightning-card>
        <!-- Account Type picklist -->
        <c-reusepicklistinlwc field-a-p-i-name="Type" obj-a-p-i-name="Account"></c-reusepicklistinlwc>
        <!--Contact Lead source picklist-->
        <c-reusepicklistinlwc field-a-p-i-name="LeadSource" obj-a-p-i-name="Contact"></c-reusepicklistinlwc>
    </lightning-card>
</template>

2 comments:

  1. Can you please help me with JEST unit tests for this?

    ReplyDelete
  2. Thank you for the Code I am getting the data but its not saving into the database from the LWC .

    ReplyDelete