Lightning Picklist Field Component in LWC
This article will show a way to fetch the values of a picklist field using few approaches.
- UI-API – Using the run time api to fetch the picklist values without writing APEX.
- getPicklistValues – use this wire adapter to get the picklist values for a specified field. (Will require using
@salesforce/schema
module to describe the fieldName)
- getPicklistValuesByRecordType – allow more dynamic context.
- getPicklistValues – use this wire adapter to get the picklist values for a specified field. (Will require using
- APEX – Using Global describe methods to access object metadata.
Final Result output
Lets get started
HTML – display the values
<template> <div class="slds-var-p-around_medium"> <label for="picklist">{picklistField.label}</label> <select id="picklist" class="slds-select" onchange={onChangeFieldValue}> <template for:each={picklistField.items} for:item="option"> <option key={option.name} value={option.name} selected={option.default}>{option.label}</option> </template> </select> </div> </template>
UI-API – Option 1
using getPicklistValues with dynamic context object and a defined schema field.
import { LightningElement, api, wire } from 'lwc'; import { getObjectInfo } from 'lightning/uiObjectInfoApi'; import { getPicklistValues } from 'lightning/uiObjectInfoApi'; import INDUSTRY_FIELD from '@salesforce/schema/Account.Industry'; export default class Example extends LightningElement { @api objectApiName; // Account _picklistField; // get context object metdata @wire(getObjectInfo, { objectApiName:'$objectApiName' }) objectInfo; @wire(getPicklistValues, { recordTypeId: '$objectInfo.data.defaultRecordTypeId', fieldApiName: INDUSTRY_FIELD }) IndustryPicklistValues; // get the picklist field details get picklistField(){ if(this.objectInfo.data && this.picklistFields.data){ const picklistOptions = this.IndustryPicklistValues.map(item => ({ name: item.value, label: item.label })); this._picklistField = { name: this.objectInfo.data.fields.Industry.apiName, label: this.objectInfo.data.fields.Industry.label, items: picklistOptions } } return this._picklistField ? this._picklistField : false; }
UI-API – OPTION 2
Using getPicklistValuesByRecordType with dynamic context and dynamic fieldName assignment
import { LightningElement, api, track, wire } from 'lwc'; import { getObjectInfo } from 'lightning/uiObjectInfoApi'; import { getPicklistValuesByRecordType } from 'lightning/uiObjectInfoApi'; export default class Example extends LightningElement { @api objectApiName; // Account @wire(getObjectInfo, { objectApiName:'$objectApiName' }) objectInfo; @track picklistField; @wire(getPicklistValuesByRecordType, { objectApiName: '$objectApiName', recordTypeId: '$objectInfo.data.defaultRecordTypeId' }) picklistFields; connectedCallback(){ // sets field name const selectedFieldName = 'Industry'; this.getPicklistOptionsByFieldName(selectedFieldName); } // assign a field name dynamically and filter the picklist fields list getPicklistOptionsByFieldName(fieldName){ if(this.objectInfo.data && this.picklistFields.data){ const picklistOptionsList = this.picklistFields.data.picklistFieldValues[fieldName].values; const picklistOptions = picklistOptionsList.map(item => ({ name: item.value, label: item.label })); this.picklistField = { name: this.objectInfo.data.fields[fieldName].apiName, label: this.objectInfo.data.fields[fieldName].label, items: picklistOptions } } } }
APEX
The Old school way, we are using Apex class and schema describe methods to fetch the values.
public with sharing class PicklistOptionsController { /* * @description: will return the field details with the option values. * @params: objectApiName and picklist fieldName */ @AuraEnabled public static string getPicklistOptionsByFieldName(String objectApiName, String fieldName){ Map<String,Object> fieldDetails = new Map<String,Object>(); // describe field Schema.DescribeSObjectResult contextObject = Schema.getGlobalDescribe().get(objectApiName).getDescribe(); Schema.DescribeFieldResult fieldDescribe = contextObject.fields.getMap().get(fieldName).getDescribe(); // Check if it's actual a picklist Field type if(fieldDescribe.getType() == Schema.DisplayType.PICKLIST) { // gets the picklist values from the field List<Schema.PicklistEntry> picklistRawOptions = fieldDescribe.getPicklistValues(); List<Map<String,Object>> picklistOptions = new List<Map<String,Object>>(); if(picklistRawOptions.size()>0){ for(Schema.PicklistEntry entry: picklistRawOptions) { // get all options from the picklist option Map<String,Object> optionDetails = new Map<String,Object>{ 'label' => entry.getLabel(), 'name' => entry.getValue(), 'active' => entry.isActive(), 'default' => entry.isDefaultValue() }; picklistOptions.add(optionDetails); } } // put field picklist values with the field label fieldDetails = new Map<String,Object>{ 'label' => fieldDescribe.getLabel(), 'name' => fieldDescribe.getName(), 'items' => picklistOptions }; } else { System.debug('This field is not a picklist field - ' + fieldDescribe.getName()); } return JSON.serialize(fieldDetails); } }
Reference your apex in your Javascript
Calling the apex method to retrieve the picklist values and to assign them into the UI Select input.
import { LightningElement,api,track } from 'lwc'; import getPicklistOptionsByFieldName from '@salesforce/apex/PicklistOptionsController.getPicklistOptionsByFieldName'; export default class Example extends LightningElement { @api objectApiName; // Account @api recordId; @track picklistField; @track selectedFieldName; connectedCallback(){ this.selectedFieldName = 'Industry'; this.fetchPicklistValues(); } // fetch values of picklist field options fetchPicklistValues(){ getPicklistOptionsByFieldName({ objectApiName : this.objectApiName, fieldName : this.selectedFieldName }).then( result => { this.picklistField = JSON.parse(result); }).catch(error =>{ console.log('error ' + error.body.message); }); } onChangeFieldValue(event){ const selectedFieldValue = event.target.value; console.log('selectedFieldValue ' + selectedFieldValue); } }
Resources:
- PicklistEntry Class – Documentation