Salesforce Lightning Web Component To Create Record Form, Dependant Picklist, Modal Popup In LWC

LWC Salesforce

LWC To Create Record Form, Dependant Picklist, Modal Popup in Salesforce

In the previous EPISODE, we have created search LWC component in salesforce.

In this EPISODE, We are going to discuss the following things :
  • How to create record form in Salesforce Lightning Web Component.
  • How to create dependent picklist in Salesforce Lightning Web Component.
  • Create Model Popup or Add LWC component in Quick action in Salesforce Lightning Web Component.
Let's have a look at today's recipe :
--------------------------------------------------------------------------
Custom Quick Action Button :

LWC Salesforce
LWC Component Inside Quick Action :



Dependant Picklist :






--------------------------------------------------------------------------

So are you excited kid to try this out ??

Let's begin.........

So in today's cookbook, we are going to add guest inside the hotel.

STEP 1 :
Please create the following data model inside your org :

OBJECT 1 :

  • Create a Hotel object (Hotel__c) [we required only Name fields hence we are not going to create extra fields inside this]
OBJECT 2 :

  • Create Guest Object (Guest__c).
  Fields for Guest Object :

  1. Address__c [Data Type : Long Text]
  2. Email__c [Data Type : Email]
  3. Phone__c [Data Type : Phone]
  4. Meal_Preference__c [Data Type : Picklist]
    Values : [Veg, Non Veg]
  5. Meal_Type__c [Data Type : Picklist]
    Values : [Veg Sandwich, Paneer Tikka, Paneer Sizzler, Chicken Sandwich,  Chicken Hot Dog, Chicken Burger]


In the above data model, Meal_Preference__c and Meal_Type__c are dependants values (dependent picklist) hence no need to create field dependency based on the controlling field as Meal_Preference__c and dependant field as Meal_Type__c.

Please include dependent values as below : 
--------------------------------------------------------------------------






--------------------------------------------------------------------------

Now we are good to go Kid...Go..Go...Go

STEP 2 : 
  1. Open Visual Studio Code (VS CODE)
  2. Connect your org [Please follow the same steps to connect salesforce org which are mention in the previous blog post]
  3. Click On LWC and Create New Lightning Web Component
Now, Let's first understand how to create Dependent picklist in LWC.

So in Salesforce Lightning Web Component, unlike Lightning component, we don't have to create any kind of events to pass the values as we have @api here.


How to create dependent picklist in LWC component ?

lightning-combobox :
  • lightning-combobox is an input element that enables a single selection from a list of options. 
  • The result of the selection is displayed as the value of the input. 
  • Multiple selections are currently not supported. 
  • To support multiple selections, use lightning-dual-listbox instead.


Why Dependent Picklist ?
  • So basically we are giving flexibility to the user to select the appropriate meal type. like for example if a user selects Veg then the only veg option is visible to the user.
  • Use dependent picklists to help your users enter accurate and consistent data. 
  • A dependent picklist is a custom or multi-select picklist for which the valid values depend on the value of another field, called the controlling field

This example creates a list of options with a default selection.

In the below code example Meal Preference is the controlling field and the Meal type is the dependent field.

For Example - If you select Meal Preference vegetarian then in meal type it will show only vegetarian food and if you select non-vegiterian in meal preference then it will show non-vegiterian food in meal type.

MARKUP (.html file)
--------------------------------------------------------------------------

<lightning-combobox label="Meal Preference" 
   name="MealPreference" 
   onchange={handleMealPreferenceChange} 
   options={controllingValues} 
   placeholder="--None--" 
   value={selectedMealPreference}>
</lightning-combobox><br/>
                
<lightning-combobox label="Meal Type" 
   name="state"
   onchange={handleMealTypeChange} 
   options={dependentValues} 
   placeholder="--None--" 
   value={selectedType}
   disabled={isEmpty}>
</lightning-combobox><br/>

--------------------------------------------------------------------------


Controller.js
--------------------------------------------------------------------------

import { LightningElement, track, wire } from 'lwc';
import { getPicklistValuesByRecordType } from 'lightning/uiObjectInfoApi';
import { getObjectInfo } from 'lightning/uiObjectInfoApi';
import GUEST_OBJECT from '@salesforce/schema/Guest__c';
    
    export default class GuestComponent extends LightningElement {
  
    @track recordId;
    @track controllingValues = [];
    @track dependentValues = [];
    @track selectedType;
    @track selectedMealPreference;
    @track isEmpty = false;
    @track error;
    controlValues;
    totalDependentValues = [];
    @track data;


@wire(getObjectInfo, { objectApiName: GUEST_OBJECT })
objectInfo;

// Picklist values based on record type
@wire(getPicklistValuesByRecordType, { objectApiName: GUEST_OBJECT, recordTypeId: '$objectInfo.data.defaultRecordTypeId'})
countryPicklistValues({error, data}) {
                       if(data) {
                       this.error = null;                 
                       let mealOptions = [{label:'--None--', value:'--None--'}];
                                           data.picklistFieldValues.Meal_Preference__c.values.forEach(key => {
                      mealOptions.push({
                      label : key.label,
                      value: key.value
                      })
});

this.controllingValues = mealOptions;

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

this.controlValues = data.picklistFieldValues.Meal_Type__c.controllerValues;

this.totalDependentValues = data.picklistFieldValues.Meal_Type__c.values;

this.totalDependentValues.forEach(key => {
    typeOptions.push({
    label : key.label,
    value: key.value
})
});

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

handleMealPreferenceChange(event) {
    // Selected Meal Preference Value
    this.selectedMealPreference = event.target.value;
    this.isEmpty = false;
    let dependValues = [];
    
    if(this.selectedMealPreference) {
        // if Selected Meal Preference is none returns nothing
        if(this.selectedMealPreference === '--None--') {
            this.isEmpty = true;
            dependValues = [{label:'--None--', value:'--None--'}];
            this.selectedMealPreference = null;
            this.selectedType = null;
            return;
        }
        
        // filter the total dependent values based on selected meal preference value 
        this.totalDependentValues.forEach(conValues => {
            if(conValues.validFor[0] === this.controlValues[this.selectedMealPreference]) {
            dependValues.push({
            label: conValues.label,
            value: conValues.value
        })
    }
})

this.dependentValues = dependValues;
}
}

handleMealTypeChange(event) {
    this.selectedType = event.target.value;
}

--------------------------------------------------------------------------

Now let's cook the actual recipe,

----------------------guestComponentLWC.html--------------------

<template>
    <lightning-card>
       
     <lightning-input type="text" name="GuestName" label="Guest Name" onchange={guestChangeName}></lightning-input>
               
     <lightning-input type="text" name="Address" label="Guest Address" onchange={changeAddress}></lightning-input>
               
                    <lightning-combobox label="Meal Preference" 
                                        name="MealPreference" 
                                        onchange={handleMealPreferenceChange} 
                                        options={controllingValues} 
                                        placeholder="--None--" 
                                        value={selectedMealPreference}></lightning-combobox><br/>
                
                    <lightning-combobox label="Meal Type" 
                                        name="state"
                                        onchange={handleMealTypeChange} 
                                        options={dependentValues} 
                                        placeholder="--None--" 
                                        value={selectedType}
                                        disabled={isEmpty}></lightning-combobox><br/>                
                
        
                    <lightning-input type="text" name="Email" label="Email" onchange={onChangeEmail}></lightning-input>
                
                    <lightning-input type="text" name="Phone" label="Phone" onchange={onChangePhone}></lightning-input>
               
        <div class="slds-p-top_medium">
        <div class="modal-footer slds-modal__footer slds-size_1-of-1">
                <div class="forceChangeRecordTypeFooter">
                <lightning-button variant="brand" label="Save" onclick={saveRecord}></lightning-button>
                </div>
        </div>
        </div>
    </lightning-card>
</template>
--------------------------------------------------------------------------


--------------------guestComponentLWC.js-----------------------

import { LightningElement, track, wire } from 'lwc';
import { getPicklistValuesByRecordType } from 'lightning/uiObjectInfoApi';
import { getObjectInfo } from 'lightning/uiObjectInfoApi';
import GUEST_OBJECT from '@salesforce/schema/Guest__c';

import saveGuest from '@salesforce/apex/GuestController.createGuest';
    
    export default class GuestComponent extends LightningElement {
    @track guestName;
    @track address;
    @track phone;
    @track email;
    @track recordId;
    
    @track controllingValues = [];
    @track dependentValues = [];
    @track selectedType;
    @track selectedMealPreference;
    @track isEmpty = false;
    @track error;
    controlValues;
    totalDependentValues = [];
    @track data;
    
guestChangeName(event) {
    this.guestName = event.detail.value;
}
changeAddress(event) {
    this.address = event.detail.value;
}
onChangePhone(event) {
    this.phone = event.detail.value;
}
onChangeEmail(event) {
    this.email = event.detail.value;
}

@wire(getObjectInfo, { objectApiName: GUEST_OBJECT })
objectInfo;

// Picklist values based on record type
@wire(getPicklistValuesByRecordType, { objectApiName: GUEST_OBJECT, recordTypeId: '$objectInfo.data.defaultRecordTypeId'})
countryPicklistValues({error, data}) {
                       if(data) {
                       this.error = null;
                       
                       let mealOptions = [{label:'--None--', value:'--None--'}];
                      
                      
                      data.picklistFieldValues.Meal_Preference__c.values.forEach(key => {
                      mealOptions.push({
                      label : key.label,
                      value: key.value
                      })
});

this.controllingValues = mealOptions;

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

this.controlValues = data.picklistFieldValues.Meal_Type__c.controllerValues;
this.totalDependentValues = data.picklistFieldValues.Meal_Type__c.values;
this.totalDependentValues.forEach(key => {
    typeOptions.push({
    label : key.label,
    value: key.value
})
});

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

handleMealPreferenceChange(event) {
    // Selected Meal Preference Value
    this.selectedMealPreference = event.target.value;
    this.isEmpty = false;
    let dependValues = [];
    
    if(this.selectedMealPreference) {
        // if Selected Meal Preference is none returns nothing
        if(this.selectedMealPreference === '--None--') {
            this.isEmpty = true;
            dependValues = [{label:'--None--', value:'--None--'}];
            this.selectedMealPreference = null;
            this.selectedType = null;
            return;
        }
        
        // filter the total dependent values based on selected meal preference value 
        this.totalDependentValues.forEach(conValues => {
            if(conValues.validFor[0] === this.controlValues[this.selectedMealPreference]) {
            dependValues.push({
            label: conValues.label,
            value: conValues.value
        })
    }
})

this.dependentValues = dependValues;
}
}

handleMealTypeChange(event) {
    this.selectedType = event.target.value;
}

//To Save the Record 
saveRecord() {
    
    let guestObj = { 'sobjectType': 'Guest__c' };
    guestObj.Name = this.guestName;
    guestObj.Address__c = this.address;
    guestObj.Email__c = this.email;
    guestObj.Phone__c = this.phone;
    guestObj.Meal_Preference__c = this.selectedMealPreference;
    guestObj.Meal_Type__c = this.selectedType;

    const value = true;
    const valueChangeEvent = new CustomEvent("valuechange", {
      detail: { value }
    });
    // Fire the custom event
    this.dispatchEvent(valueChangeEvent);

    saveGuest({newRecord: guestObj})
        .then(result => {
            this.recordId = result;
        })
        .catch(error => {
            this.error = error;
        });
}
}
---------------------------------------------------------------


------------guestComponentLWC.js-meta.xml--------------

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

-----------------------------------------------------------------

APEX CLASS :

----------------GuestController.apxc-------------------

public with sharing class GuestController {

    @AuraEnabled
    public static Guest__c createGuest(Guest__c newRecord) {
       insert newRecord;
       return null;
    }
}
-----------------------------------------------------------------

Now right-click on LWC component in VS code and deploy to source org.

STEP 3 :

To add LWC component inside lightning-quick action we will add guestComponentLWC to add This LWC component inside a lightning component to use it as a quick action.

IMPORTANT*
To close the quick action when a record is saved we will pass the boolean value and when that user click save we will get that boolean value as a true and then we will click the lightning-quick action. Hence in the below component code, "change" handler will call as soon as a value is a change (When Save button is clicked). 
Then It will get the Boolean value and check whether the boolean values is changed or not. If changed then it will call "{!c.handleValueChange}" 
method and close the lightning-quick action.

Lightning Component
-------------------------------guestAction.cmp--------------------

<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickActionWithoutHeader" access="global" >
    <aura:attribute name="inputValue" type="String"/>
    <aura:handler name="change" value="{!v.inputValue}" action="{!c.handleValueChange}"/>
    <c:guestComponent onvaluechange="{!c.getValueFromLwc}"></c:guestComponent>  
</aura:component>
---------------------------------------------------------------------

-------------------------------guestAction.js--------------------
({
    getValueFromLwc : function(component, event, helper) {
        component.set("v.inputValue",event.getParam('value'));
    },
    
    handleValueChange : function(cmp, event, helper) {
        $A.get("e.force:closeQuickAction").fire();
    }
})
--------------------------------------------------------------------

Now create custom action on Hotel Object.
  • Add lightning component inside the action Add Guest.
  • Add the custom action button on Hotel layout.
And finally kid, you will get the following output :

Output :
--------------------------------------------------------------------






Once You click on Save Button 





Finally, we have created the lightning component with dependent picklist, added that lightning component or record form inside salesforce lightning component as quick action option currently not supported with LWC.


WOHOOO !! YOU HAVE JUST COMPLETED SALESFORCE LIGHTNING WEB COMPONENT (LWC) RECORD FORM, DEPENDANT PICKLIST, MODAL POPUP CREATION EPISODE
If you like this salesforcekid learning platform please let me know in the Comment section...Also, Share with your salesforce folks wish you all

Happy Learning ☁️⚡️ (Learn. Help. Share.) 😊

<< PREVIOUS                                    NEXT >>              


Salesforce Lightning Web Component To Create Record Form, Dependant Picklist, Modal Popup In LWC Salesforce Lightning Web Component To Create Record Form, Dependant Picklist, Modal Popup In LWC Reviewed by on Rating: 5

No comments:

HELP !! SHARE !! SUGGEST !!

Powered by Blogger.