Navigation Mechanism in Lightning Web Component

Navigation Mechanism is the way to redirect a new web page, new record, edit record, record detail page etc. without using Apex Class.

We have created one Lightning Web Component named “lightningNavigation“.

Step 1: Need to update the lightningNavigation.js-meta.xml file to set the visibility in Lightning App Builder.

lightningNavigation.js-meta.xml

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

Step 2: Need to write html file.

lightningNavigation.html

<template>
        <lightning-card title="Navigation System">    
                <lightning-layout multiplerows="true" verticalalign="center">                        
                        <lightning-layout-item padding="around-small" size="3">
                                <lightning-button variant="brand" label="Current Tab" title="Current Tab" onclick={navigateCurrentTab}>
                                </lightning-button>
                        </lightning-layout-item>
                        <lightning-layout-item padding="around-small" size="3">
                                <lightning-button variant="brand" label="Object Home" title="Object Home" onclick={navigateToObjectHome}>
                                </lightning-button>
                        </lightning-layout-item>
                        <lightning-layout-item padding="around-small" size="3">
                                <lightning-button variant="brand" label="List View" title="List View" onclick={navigateToListView}>
                                </lightning-button>
                        </lightning-layout-item>
                        <lightning-layout-item padding="around-small" size="3">
                                <lightning-button variant="brand" label="View Record" title="View Record" onclick={navigateToRecordView}>
                                </lightning-button>
                        </lightning-layout-item>
                </lightning-layout>
                <lightning-layout multiplerows="true" verticalalign="center">
                        <lightning-layout-item padding="around-small" size="3">
                                <lightning-button variant="success" label="New Record" title="New Record" onclick={navigateToNewRecord}>
                                </lightning-button> 
                        </lightning-layout-item>
                        <lightning-layout-item padding="around-small" size="3">            
                                <lightning-button variant="success" label="Edit Record" title="Edit Record" onclick={navigateToRecordEditPage}>
                                </lightning-button>
                        </lightning-layout-item>
                        <lightning-layout-item padding="around-small" size="3">
                                <lightning-button variant="success" label="Related List View" title="Related List View" onclick={navigateToRelatedList}>
                                </lightning-button>
                        </lightning-layout-item>
                        <lightning-layout-item padding="around-small" size="3">
                                <lightning-button variant="success" label="Web Page" title="Web Page" onclick={navigateToWebPage}>
                                </lightning-button>
                        </lightning-layout-item>                    
                </lightning-layout>
        </lightning-card>
</template>

Step 3: We have updated the JS file according to the navigation procedure.

lightningNavigation.js

import { LightningElement } from 'lwc';
import { NavigationMixin } from 'lightning/navigation';

export default class LightningNavigation extends NavigationMixin(LightningElement) {

    navigateCurrentTab(){
        this[NavigationMixin.Navigate]({
            type: 'standard__navItemPage',
            attributes: {
                apiName: "LWC",                
            }
        });
    }

    navigateToObjectHome(){
        this[NavigationMixin.Navigate]({
            type: 'standard__objectPage',
            attributes: {
                "objectApiName": "Contact",
                "actionName": "home"          
            }
        });
    }

    navigateToListView(){
        this[NavigationMixin.Navigate]({
            type: 'standard__objectPage',
            attributes: {
                "objectApiName": "Contact",
                "actionName": "list"          
            },
            state: {
                filterName: 'Recent'
            }
        });
    }

    navigateToNewRecord() {
        this[NavigationMixin.Navigate]({
            type: 'standard__objectPage',
            attributes: {
                objectApiName: 'Contact',
                actionName: 'new'
            }
        });
    }

    navigateToRecordView() {
        this[NavigationMixin.Navigate]({
            type: 'standard__recordPage',
            attributes: {
                recordId: "0030o00002dCDi7AAG",
                objectApiName: 'Contact', // objectApiName is optional
                actionName: 'view'
            }
        });
    }

    navigateToRecordEditPage() {
        // Opens the Account record modal
        // to view a particular record.
        this[NavigationMixin.Navigate]({
            type: 'standard__recordPage',
            attributes: {
                recordId: "0030o00002dCDi7AAG",
                objectApiName: 'Contact', // objectApiName is optional
                actionName: 'edit'
            }
        });
    }

    navigateToRelatedList() {
        this[NavigationMixin.Navigate]({
            type: 'standard__recordRelationshipPage',
            attributes: {
                recordId: '0010o00002Dw6eGAAR',
                objectApiName: 'Account',
                relationshipApiName: 'Contacts',
                actionName: 'view'
            }
        });
    }

    navigateToWebPage() {
        this[NavigationMixin.Navigate]({
            type: 'standard__webPage',
            attributes: {
                url: 'https://www.salesforce.com'
            }
        })        
    }
}

Step 4: Then, we have added the component into the Lightning App Page.

Result

Toast Notification in Lightning Web Component

In this section, we will see how to display toast notification and how to take user input through Lightning Web Component. The toast notification behavior is same as Lightning Aura Component. Following steps need to be maintained to fulfill the business.

We have created a Lightning Web Component named “displayToast.html

Step 1: First, we need to update the displayToast.js-meta.xml file to set the LWC visibility in App Builder.

displayToast.js-meta.xml

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

Step 2: We have updated the html file in such a way user can select the toast variant such as Success, Warning & Error along with the input message.

displayToast.html

<template>
        <lightning-card title="Show Toast Message">    
            
<div class="inputClass">
                <lightning-layout >
                    <lightning-layout-item flexibility="auto" padding="around-small">
                        <lightning-input type="text" label="Message " value={msg} onchange={trackMessage}></lightning-input>
                        <lightning-combobox label="Variant" value={variant} onchange={updateVariant} options={variantOptions}></lightning-combobox>
                        
<div class="slds-float_right slds-m-top_medium">
                            <lightning-button variant="brand" label="Show Notification" onclick={showToast} ></lightning-button> &nbsp;&nbsp;
                            <lightning-button variant="brand" label="Reset" onclick={doReset}></lightning-button>
                        </div>

  
                    </lightning-layout-item>
                </lightning-layout>
            </div>

        </lightning-card>
</template>

Step 3: Need to update the JS file.

displayToast.js

import { LightningElement, track } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';

export default class DisplayToast extends LightningElement {
    @track msg;
    @track variant; /* understand the with/without @track &amp;amp; api*/
    title="Notification"
    variant = 'success';
    variantOptions = [
        {label : 'error', value : 'error'},
        {label : 'warning', value : 'warning'},
        {label : 'success', value : 'success'},
        {label : 'info', value : 'info'}
    ];

    updateVariant(event){
        this.variant = event.target.value;
    }

    trackMessage(event){
        this.msg = event.target.value;
    }

    showToast(){
        /*eslint-disable-next-line  no-console*/
        console.log('entry point');
        const evt = new ShowToastEvent({
            
            title: this.title,
            message: this.msg,
            variant: this.variant
        });
        this.dispatchEvent(evt);
    }

    doReset(){
        this.msg = '';
        this.variant = 'success';
    }
}

If you see the second line of this JS file, we have imported “platformShowToastEvent” to use the toast function in our Lightning web Component.

We have declared variantOptions to display the variants to the user. trackMessage() & updateVariant() functions have been used to get the input message & toast variant type from the end user.

In showToast() function, we have used standard ShowToastEvent() event along with the properties such as title, message, variant and dispatch the standard toast event. This showToast() function is invoked after clicked on “Show Toast Notification” button.

Reset has been used to restore the previous inputs.

Step 4: At last, need to add this LWC in Lightning App Page.

Result

 

 

 

 

 

 

 

Here, We have selected the variant as “success” and entered the message as “Showing Toast Example”, so after clicked on “Show Toast Notification” button, it’s displaying the toast message.

Notes
One more property called “mode” is present in ShowToastEvent(). There are three types of mode such as

  • dismissable: It’s automatically dismissed until you have not clicked in 3 seconds. It is the default property.
  • pester: It’s visible until user is clicked close button.
  • sticky: It’s visible for 3 seconds.

19,223 total views, 15 views today

Visual Studio Code for Lightning Web Component

There are many tools to develop Lightning Web Component. In this session, we will see how to set up Visual Studio Code for developing Lightning Web Component.

Step 1: Need to install Salesforce CLI (Command Line Interface) using the following link

Windows 32 bit OS -> https://sfdc.co/sfdx_cli_win
Windows 64 bit OS -> https://sfdc.co/sfdx_cli_win64
macOS ->                         https://sfdc.co/sfdx_cli_osx

We will focus on how to set up Visual Studio Code in Windows OS. However, you can set up the Visual Studio Code in macOS.

Step 2: Please set the environment variable in a path in the “Advance Settings” of “My Computer“.

Step 3: Please open the Command Prompt and write “sfdx” and enter. You will see the output like the following image.


 

 

 

 

If you want to see the version of Salesforce CLI, you can enter “sfdx –version“.

Whoever has installed the Salesforce CLI before Spring 19 release, please uninstall and update the Salesforce CLI with the following commands.

sfdx plugins:uninstall salesforcedx
sfdx update

Step 4: Please install the Visual Studio Code from here.

Step 5: Launch Visual Studio Code and Please install the extension named “Salesforce Extension Pack” as per the following image.

Please activate the extension.

Step 6: Please open the Command Palette by Ctrl + Shift + P in the Visual Studio Code and enter SFDX. You will get the SFDX commands just like:

Step 7: Open the Command Palette and search SFDX: Create Project. Just select this and enter Project Name which will be created as part of the SFDX project.

Step 8: Need to connect and authorize the development org. Again Open the Command Palette and search SFDX: Authorize an Org. It will automatically open the default browser where you need to enter the user name and password for your Salesforce Development Org. After authentication, click Allow to successful handshaking between Salesforce and visual Studio Code.

Step 9: Up to this, we have created a project and connected a development org through Visual Studio Code. Now, we will create a Lightning Web Component. Again we need to open Command Palette and search SFDX: Create Lightning Web Component. Press enter to allow the default location and after this enter component name. Remember, all Lightning Web Components will be created under force-app/main/default/lwc.

Here we have created a Lightning Web Component named “welcomeWindow” under “LWCPro” project.

Step 10: We will get three sub-files such as welcomeWindow.html, welcomeWindow.js, welcomeWindow.js-meta.xml for the Lightning Web Component named “welcomeWindow“. Please refer to the next session about the detailed discussion on this Lightning Web Component. For now, we are going to update the sub-files.

welcomeWindow.html

<template>
    <lightning-card title="Welcome My Friends">    
        <lightning-layout>
                <lightning-layout-item flexibility="auto" padding="around-small">                    
                        Welcome to LWC Training Class
                </lightning-layout-item>
            </lightning-layout>
    </lightning-card>     
</template>

welcomeWindow.js — currently we will not touch this JS.


welcomeWindow.js-meta.xmlneed to update this file to set the visibility into Lightning App Builder.

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

Step 11: Now, we need to deploy the component. Please do right click on the Component Name from the left side panel of Visual Studio Code and you will find out the command to deploy like SFDX: Deploy Source To Org. After selection of this command, the respective Lightning Web Component will be deployed. If you will get this type of output with exit code 0 in the Visual Studio Code Output Section, that means deployment is successful.

Step 12: Ensure that “My Domain” has been enabled in your Org.

Step 13: Create a Lightning App Page from Lightning App Builder and place the component into the Lightning App Page. Drag this component into the Lightning App page and save & activate it.

Result

19,155 total views, 9 views today

Welcome to Lightning Web Component

Definition

Lightning Web Components are built with Custom HTML elements comprises of Salesforce Design Systems and modern Javascript like ES6. Lightning Web Component follows Web Component standards. We can work on Lightning Web Component with the existing web technologies framework.

Why?

All modern web browsers are based on web standards and they are improving their performance every day. Lightning Web Component also follows W3C web component standards to take advantage of modern technologies and native browser’s feature to execute it as fast with the use of minimally network bandwidth.

Remember, as per current Salesforce release (Spring’19), we have to develop Lightning web Component outside of the Salesforce Environment.

Lightning Web Component and Lightning Aura Component can co-exist together in your application. However, you can easily migrate to the Lightning Web Component Model from Lightning Aura Component Model.

 

 

8,889 total views, 12 views today

How to use Salesforce Resources in Lightning Web Component?

Salesforce ResourceSyntax to use
Static Resourceimport sampleResource from '@salesforce/resourceUrl/resourceReference';

Only, we need to enter Static Resource Name in the place of resourceReference and then refer to the property in JS file.If there is a specific namespace in your org, please put the Static Resource Name with the namespace i.e., namespace__StaticResourceName.
Custom Labelimport labelName from '@salesforce/label/labelReference';


Only, we need to enter Custom Label Name with namespace in the place of labelReference and then refer to the property in JS file. If there is no specific namespace in your org, please put the Custom Label Name with default namespace c.
Current User Idimport userId from '@salesforce/user/Id';
SVG ResourceWe can directly write down the SVG in template of the HTML file using tag.
You can also import the SVG from static resource.

11,543 total views, 6 views today

How to use CSS in Lightning Web Component?

The beauty of Lightning Component Framework is the uniform UI which is consistent in Lightning Design System. So, the styles of Custom Lightning Component and Standard Lightning Component are in uniform. All elements using lightning namespace use Lightning Design System. Also, you can provide slds (Salesforce Lightning Design System) in class attribute of any custom element. Now, we can build the CSS file to provide custom styles for the elements mentioned in the html file.

We can consider the first Lightning Web Component named “welcomeWindow“. Now, we will apply the styles for the welcome content.

Step 1: Need to update the welcomeWindow.js-meta.xml to set the visibility in Lightning App Builder.

welcomeWindow.js-meta.xml

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

Step 2: Need to update the welcomeWindow.html file.

welcomeWindow.html

<template>
    <lightning-card title="Welcome My Friends">    
        <lightning-layout>
                <lightning-layout-item flexibility="auto" padding="around-small">                    
                        Welcome to LWC Training Class
                </lightning-layout-item>
            </lightning-layout>
    </lightning-card>     
</template>

Step 3: Create a CSS file named “welcomeWindow.css” under welcomeWindow folder.

welcomeWindow.css

.contentClass{
    color:green;
    font-weight: bold;
}

.messageClass{
    border-top: 1px solid #ccc;
    width:100%;
}

Step 4: Again, we have updated welcomeWindow.html file.

welcomeWindow.html

<template>
    <lightning-card title="Welcome My Friends">        
         <div class="messageClass">    
            <lightning-layout>
                    <lightning-layout-item flexibility="auto" padding="around-small">                        
		        <div class="contentClass">                   
                            Welcome to LWC Training Class
                        </div>
                    </lightning-layout-item>
            </lightning-layout>
        </div>
    </lightning-card>     
</template>

Here, we have used messageClass to define the header border and contentClass to define the color of content from the CSS file.

Result

115,736 total views, 18 views today

How to use Custom Label in Lightning Web Component?

In this session, we will learn how to use Custom Label in Lightning Web Component.

To do this exercise, We can consider the first Lightning Web Component named “welcomeWindow“.

Step 1: Need to update the welcomeWindow.js-meta.xml to set the visibility in Lightning App Builder.

welcomeWindow.js-meta.xml

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

Step 2: We have created a custom label named “Welcome_Message” where the content will be stored for welcoming.

Step 3: Need to update the JS file.

welcomeWindow.js

import { LightningElement } from 'lwc';
import WELCOME_MESSAGE from '@salesforce/label/c.Welcome_Message';

export default class WelcomeWindow extends LightningElement {
    welcomeMessage = WELCOME_MESSAGE;//'Welcome to LWC Training Class';
}

Here, we have imported Welcome_Message custom label and assign to the “welcomeMessage” property which is referred into the html file. We can import the custom label in this way

@salesforce/label/namespace.customLabelName

In our example, the default namespace is c.

Step 4: Need to update the welcomeWindow.html file.

welcomeWindow.html

<template>
    <lightning-card title="Welcome My Friends">    
        <lightning-layout>
                <lightning-layout-item flexibility="auto" padding="around-small">                    
                        {welcomeMessage}
                </lightning-layout-item>
            </lightning-layout>
    </lightning-card>     
</template>

Here, we have used “welcomeMessage” property to display the welcome message.

Result

10,324 total views, 18 views today

Import/Export JavaScript file in LWC

In ES6 JS architecture, we can export the variables or functions in JS file, so other module can use.

Here, we will create simple calculator using import/export functionality in Lightning Web Component framework. Let’s see.

Step 1: First, we are going to create a LWC named “calculator” where we will define only JS file that is “calculator.js”.

calculator.js

const calculator = (first_param, second_param, mode) => {
    if (mode === "add" || mode === "+" || mode === "Add" || mode === "ADD") {
      return +first_param + +second_param;
    }
  
    if (
      mode === "subtraction" ||
      mode === "-" ||
      mode === "Subtraction" ||
      mode === "SUBTRACTION"
    ) {
      return first_param - second_param;
    }
  
    if (
      mode === "divide" ||
      mode === "/" ||
      mode === "Divide" ||
      mode === "DIVIDE"
    ) {
      return first_param / second_param;
    }
  
    if (
      mode === "multiplication" ||
      mode === "*" ||
      mode === "Multi" ||
      mode === "ADD"
    ) {
      return first_param * second_param;
    }
    return 0;
  };
  
  export { calculator };
  

Here we have defined a function named “calculator” in which there are three parameters such as first_param, second_param and mode which denotes the operation type of calculation.

At last, we have explicitly exported the function as calculator so other LWC can import it.

Step 2: Next, we will create a LWC named “calculation” which will display the result.

So, we need to update the calculation.js-meta.xml to set the visibility in Lightning App Builder.

calculation.js-meta.xml

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

Then, we will write calculation.html file.

calculation.html

<template>
  <lightning-card title="Calculator">
    
<div class="slds-float_right">
      <label class="resClass">{result}</label>
    </div>

    <lightning-layout>
      <lightning-layout-item flexibility="auto" padding="around-small">
        <lightning-input type="number" label="Input 1 " value={input1} onchange={changeInput1}></lightning-input>
        <lightning-combobox label="" value={mode} options={modeOptions} onchange={changeMode}></lightning-combobox>
        <lightning-input type="number" label="Input 2 " value={input2} onchange={changeInput2}></lightning-input>

        
<div class="slds-float_right slds-m-top_medium">
          <lightning-button variant="brand" label="Calculate" onclick={doCalculation}></lightning-button>
          &nbsp;&nbsp;
          <lightning-button variant="brand" label="Reset" onclick={doReset}></lightning-button>
        </div>

      </lightning-layout-item>
    </lightning-layout>
  </lightning-card>
</template>      

Then, we need to update calculation.js file.

calculation.js

import { LightningElement, track } from 'lwc';
import { calculator } from 'c/calculator';

export default class Calculation extends LightningElement {

  @track result = "";
  @track input1;
  @track input2;
  @track mode;

  modeOptions = [
    { label: "+", value: "+" },
    { label: "-", value: "-" },
    { label: "*", value: "*" },
    { label: "/", value: "/" }
  ];

  changeInput1(event) {
    this.input1 = event.target.value;
  }

  changeInput2(event) {
    this.input2 = event.target.value;
  }

  changeMode(event) {
    this.mode = event.target.value;
  }

  doCalculation() {
    /*eslint-disable-next-line*/
    console.log("input1--->" +this.input1 + "input2---->" +this.input2 +"mode--->" +this.mode);
    this.result = calculator(this.input1, this.input2, this.mode);
  }

  doReset(){
    this.input1 = null;
    this.input2 = null;
    this.mode = null;
  }
}

Here, you can see we have imported the function calculator from “calculator.js” file. In doCalculation() function, we have invoked calculator function from calculator.js using three attributes.

At last, we have defined calculator.css file to beautify the output.

calculator.css

.resClass {
    color: green;
    font-weight: bold;
    font-size: 50px;
}  

Result

 

 

 

 

 

 

 

 

So, here we have given the first param as 8, second param as 7, mode of operation as “+” and we will get the result as summation of two integers as 15 in Lightning Web Component through calculator.js file.

55,831 total views, 15 views today

Publish Subscriber model in Lightning Web Component

In this Publish Subscriber model, components are not situated in the same DOM tree or in the same containment hierarchy. If the components want to communicate between themselves, we have to use publish subscriber model in Lightning Web Component, You can compare this model as Application Event in Lightning Aura Component.

Publish Subscriber Model Rules

  • Need to use a singleton library which follows the publish-subscriber pattern. Salesforce has already provided one file called pubsub.js by which we can build the publish subscriber communication.
  • import fireEvent from pubsub.js file in the publisher component. Define the pageReference as currentPageReference and fire or publish the event using this pageReference, event name and event detail in the publisher component.
  • import registerListener, unregisterAllListeners from pubsub.js file in the subscriber component. Then register the event and get the value in the subscriber component.

For example, we have made canvas and palette component. When user select the color in palette, canvas will display the respective color. Obviously, palette is the publisher and canvas is the subscriber. Let’s see:

Step 1: First, we need to copy the pubsub.js file from Salesforce library and create the LWC named “pubsub“.

In the pubsub component we only define the pubsub.js file, which will be used later.

/**
 * A basic pub-sub mechanism for sibling component communication
 *
 * TODO - adopt standard flexipage sibling communication mechanism when it's available.
 */

const events = {};

const samePageRef = (pageRef1, pageRef2) => {
  const obj1 = pageRef1.attributes;
  const obj2 = pageRef2.attributes;
  return Object.keys(obj1)
    .concat(Object.keys(obj2))
    .every(key => {
      return obj1[key] === obj2[key];
    });
};

/**
 * Registers a callback for an event
 * @param {string} eventName - Name of the event to listen for.
 * @param {function} callback - Function to invoke when said event is fired.
 * @param {object} thisArg - The value to be passed as the this parameter to the callback function is bound.
 */
const registerListener = (eventName, callback, thisArg) => {
  // Checking that the listener has a pageRef property. We rely on that property for filtering purpose in fireEvent()
  if (!thisArg.pageRef) {
    throw new Error(
      'pubsub listeners need a "@wire(CurrentPageReference) pageRef" property'
    );
  }

  if (!events[eventName]) {
    events[eventName] = [];
  }
  const duplicate = events[eventName].find(listener => {
    return listener.callback === callback && listener.thisArg === thisArg;
  });
  if (!duplicate) {
    events[eventName].push({ callback, thisArg });
  }
};

/**
 * Unregisters a callback for an event
 * @param {string} eventName - Name of the event to unregister from.
 * @param {function} callback - Function to unregister.
 * @param {object} thisArg - The value to be passed as the this parameter to the callback function is bound.
 */
const unregisterListener = (eventName, callback, thisArg) => {
  if (events[eventName]) {
    events[eventName] = events[eventName].filter(
      listener => listener.callback !== callback || listener.thisArg !== thisArg
    );
  }
};

/**
 * Unregisters all event listeners bound to an object.
 * @param {object} thisArg - All the callbacks bound to this object will be removed.
 */
const unregisterAllListeners = thisArg => {
  Object.keys(events).forEach(eventName => {
    events[eventName] = events[eventName].filter(
      listener => listener.thisArg !== thisArg
    );
  });
};

/**
 * Fires an event to listeners.
 * @param {object} pageRef - Reference of the page that represents the event scope.
 * @param {string} eventName - Name of the event to fire.
 * @param {*} payload - Payload of the event to fire.
 */
const fireEvent = (pageRef, eventName, payload) => {
  if (events[eventName]) {
    const listeners = events[eventName];
    listeners.forEach(listener => {
      if (samePageRef(pageRef, listener.thisArg.pageRef)) {
        try {
          listener.callback.call(listener.thisArg, payload);
        } catch (error) {
          // fail silently
        }
      }
    });
  }
};

export {
  registerListener,
  unregisterListener,
  unregisterAllListeners,
  fireEvent
};

Step 2: Then, we need to define palette component named “palettePublisher”.

First, we need to update the palettePublisher.js-meta.xml to set the visibility in Lightning App Builder.

palettePublisher.js-meta.xml

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

Then, we need to write palettePublisher.html file.

palettePublisher.html

<template>
        <lightning-card title="Pallete Publisher">
            <lightning-layout>
                <lightning-layout-item flexibility="auto" padding="around-small">
                    <lightning-combobox label="Color" value={color} options={colorCodeOptions} onchange={changeColor}></lightning-combobox>
                    <div class="slds-p-top_small">
                        <lightning-button label="Change Color!" variant="brand" onclick={handleChangeColor}></lightning-button>
                    </div>                    
                </lightning-layout-item>
            </lightning-layout>          
        </lightning-card>
</template>
      

Through this html, user can select the color from the defined picklist, color.

Then, we need to update palettePublisher.js file.

palettePublisher.js

import { LightningElement, track, wire } from 'lwc';
import { CurrentPageReference } from 'lightning/navigation';
import { fireEvent } from 'c/pubsub';

export default class PalletePublisher extends LightningElement {
    @track color;

  @wire(CurrentPageReference) pageRef;

  colorCodeOptions = [
    { label: "green", value: "green" },
    { label: "red", value: "red" },
    { label: "yellow", value: "yellow" },
    { label: "blue", value: "blue" }
  ];

  changeColor(event) {
    this.color = event.target.value;
  }

  handleSearchKeyChange(searchKey) {
    this.searchKey = searchKey;
  }

  handleChangeColor() {
    /*eslint-disable-next-line*/
    console.log("color srs-->" + this.color);
    fireEvent(this.pageRef, "changedColor", this.color);
  }
}

In this js file, we have triggered the event named “changedColor” with color code. Remember, we need to send the page reference attribute as current page reference for successful communication.

Step 3: Need to define the canvas component named “canvasSubscriber“.

First, we need to update the canvasSubscriber.js-meta.xml.

canvasSubscriber.js-meta.xml

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

Then, we need to write canvasSubscriber.html file.

canvasSubscriber.html

<template>
    <lightning-card title="Canvas Subscriber">
        <lightning-layout-item flexibility="grow">
            
<div class="templateBodyClass" style={colorStyle}></div>

        </lightning-layout-item>
    </lightning-card>
</template>      

We are showing the color in canvas based on the selection of color in palette.

Then, we need to write canvasSubscriber.js file.

canvasSubscriber.js

import { LightningElement, track, wire } from 'lwc';
import { registerListener, unregisterAllListeners } from 'c/pubsub';
import { CurrentPageReference } from 'lightning/navigation';

export default class CanvasSubscriber extends LightningElement {
    @track color;
  @wire(CurrentPageReference) pageRef;

  connectedCallback() {
    registerListener("changedColor", this.handleChangedColor, this);
  }

  disconnectedCallback() {
    unregisterAllListeners(this);
  }

  handleChangedColor(colorCode) {
    /*eslint-disable-next-line*/
    console.log("color--->" + colorCode);
    this.color = colorCode;
  }

  get colorStyle() {
    return `background-color: ${this.color}`;
  }
}

In this JS file, we have invoked registeredListener() and unregisterAllListeners() in the respective methods such as connectedCallback() and disconnectedCallback().
From the connectedCallback(), we are calling handleChangedColor() where we have set the color and at last we have used getter method of colorStyle property to set the background color.

To make the style for canvas, we have defined canvasSubscriber.css file.

canvasSubscriber.css

.templateBodyClass {
    height: 80px;
}

Result

 

 

 

 

 

 

 

So, whenever we will select the color in Palette, Canvas will show that color in the screen.

31,433 total views, 15 views today

Custom Event Communication in Lightning Web Component

Custom Event is used in Lightning Web Components(LWC) to make the communication from Child Component to Parent Component in the containment hierarchy. Lightning Web Components can create and dispatch custom events.

Custom Event Rules

  • To create custom events in LWC, need to use CustomEvent() constructor which will contain one required parameter as Custom Event Name and the detail of the event. It will pass any kind of data using detail property.
  • To dispatch custom events in LWC, need to use EventTarget.dispatchEvent() method.
  • To listen the event, we have two types such as Event Listener in Declaratively and Event Listener in Programmatically.
  • We need to add “on” in prefix in the event name in Parent Component during calling of Child Component to make the Event Listener in Declaratively.
  • We need to make the event listener using this.template.addEventListener() or this.addEventListener() in the constructor() of the Parent Component’s JS file as the part of Event Listener in Programmatically.

Let’s see how we will use custom event.

Step 1: First, we will create a child component named “childComponent”.

We will update the childComponent.html.

childComponent.html

<template>
    <lightning-button label="Yes, Papa" onclick={handleResponse}></lightning-button>
</template>

Here, we have declared one lightning-button by which user can send the label of the button to the parent component by handleResponse method.

We need to update childComponent.js file.

import { LightningElement } from 'lwc';

export default class ChildComponent extends LightningElement {
    handleResponse(event) {
        event.target.disabled = true;
        const btnName = event.target.label;
        const answerEvent = new CustomEvent("answer", { detail: btnName });
        this.dispatchEvent(answerEvent);
    }
}

Here we have defined a method named handleResponse() which has standard event attribute. As per the standard rule of Custom Event creation, we have used CustomEvent() constructor where we have declared the custom event as “answer” and this event will send the label of button (‘Yes, Papa’) via detail property. After that, we have dispatched the custom event using dispatchEvent() method. event.target.disabled equals to true to change the state of the button as disabled after clicked once.

Step 2: Now need to define Parent Component. So, we are going to create a parent component named as “parentComponent”.

We need to update the parentComponent.js-meta.xml to set the visibility into Lightning App Builder.

parentComponent.js-meta.xml

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

Then, we need to work on parentComponent.html file.

parentComponent.html

<template>
        <lightning-card title="Custom Event Communication">
          <lightning-layout>
            <lightning-layout-item flexibility="auto" padding="around-small">
              <div class="padding-around:small">
                {question}
              </div>
              <div class="answClass">
                {answer}
              </div>
              <div class="slds-m-top_medium">
                <c-child-component onanswer={handleAnswer}></c-child-component>
              </div>
            </lightning-layout-item>
          </lightning-layout>
        </lightning-card>
</template>

Here, we have called the child component and used event listener declaratively. We need to add prefix as “on” before the custom event name. As we discussed earlier, we have created a custom event named “answer”. So, in parent component we need to invoke the event listener as handleAnswer using onanswer attribute.

After that, we need to update the parentComponent.js file.

parentComponent.js

import { LightningElement, track } from 'lwc';

export default class ParentComponent extends LightningElement {
    @track answer = "Child: ";
    question = "Parent: Have you completed study for today?";
  
    handleAnswer(event) {
      /*eslint-disable-next-line*/
      console.log("res-->" + event.detail);
      const res = event.detail;
      this.answer = this.answer + res;
    }
}

In the handleAnswer() method, we can get the detail of the event using event.detail.

Now, to make the beautiful UI, we have created on CSS file named parentComponent.css.

parentComponent.css

.answClass {
    color: green;
    font-weight: bold;
  }  

Result

 

 

 

 

 

If you will see the result, parent is asking to child as “Have you completed study for today?” from parent component. Now, Child is trying to give the answer as “Yes, Papa” by clicking the button in Child Component.

How do you use the Event Listener programmatically?

If we will take the same parentComponent.js file, it looks like:

import { LightningElement, track } from 'lwc';

export default class ParentComponent extends LightningElement {
    @track answer = "Child: ";
    question = "Parent: Have you completed study for today?";

    constructor() { 
      super();     
      this.template.addEventListener('answer', this.handleAnswer.bind(this));
    }
  
    handleAnswer(event) { 
      /*eslint-disable-next-line*/
      console.log("res--&gt;" + event.detail);
      const res = event.detail;
      this.answer = this.answer + res;
    }
}

To add an event listener to an element with in a shadow boundary, please use this.template.addEventListener() method, but to add an event listener to an element that the template doesn’t own, please use this.addEventListener() method directly.

Then , need to remove onanswer attribute during the calling of the child component from parentComponent.html file.

You can set bubbles equals to true during creation of the custom event just like:

import { LightningElement } from 'lwc';

export default class ChildComponent extends LightningElement {
    handleResponse(event) {
        event.target.disabled = true;
        const btnName = event.target.label;
        const answerEvent = new CustomEvent("answer", { detail: btnName, bubbles: true });
        this.dispatchEvent(answerEvent);
    }
}

 

28,776 total views, 6 views today