How to Use Lightning Web Components in Communities

Let’s discuss here how to use the lightning web component(lwc) in communities. In Aura, To appear in Community Builder, a component must implement the forceCommunity:availableForAllPageTypes interface. But in case of the Lightning web components we will use configure the details in configuration file—<component>.js-meta.xml file—that defines the metadata values for the componentMake a custom Lightning web component available in Community Builder, where users can drag it onto the page. After you configure the component, it appears in the Components panel of all Lightning communities in your Org.

sfdx force:lightning:component:create --type lwc --componentname communityexample --outputdir force-app\main\default\lwc

In this example, we will be using the custom component that will allow you to create a case from the community

 

communityexample.html

<template>
    <lightning-card title={title} icon-name="standard:record">
        <div class="slds-m-around_medium">
            <lightning-input label="Case Subject" onchange={handleChange} class="slds-m-bottom_x-small"></lightning-input>
            <lightning-input label="Case Description" onchange={handleChange} class="slds-m-bottom_x-small"></lightning-input>
            <lightning-button label={buttonlabel} variant="brand" onclick={submitCase}></lightning-button>
        </div>
    </lightning-card>
</template>

communityexample.js

import {
    LightningElement,
    track,
    api
} from 'lwc';
import {
    createRecord
} from 'lightning/uiRecordApi';
import {
    ShowToastEvent
} from 'lightning/platformShowToastEvent';
import CASE_OBJECT from '@salesforce/schema/Case';
import SUBJECT_FIELD from '@salesforce/schema/Case.Subject';
import DESC_FIELD from '@salesforce/schema/Case.Description';
import STATUS_FIELD from '@salesforce/schema/Case.Status';
import ORIGIN_FIELD from '@salesforce/schema/Case.Origin';

export default class Communityexample extends LightningElement {

    @api title;
    @api buttonlabel;

    @track subject = '';
    @track desc = '123234345345';

    handleChange(event) {
        if (event.target.label === 'Case Subject') {
            this.subject = event.target.value;
        }
        if (event.target.label === 'Case Description') {
            this.desc = event.target.value;
        }
    }
    submitCase() {
        const fields = {};
        fields[SUBJECT_FIELD.fieldApiName] = this.subject;
        fields[DESC_FIELD.fieldApiName] = this.desc;
        fields[STATUS_FIELD.fieldApiName] = 'New';
        fields[ORIGIN_FIELD.fieldApiName] = 'Web';

        const recordInput = {
            apiName: CASE_OBJECT.objectApiName,
            fields
        };
        createRecord(recordInput)
            .then(case =>{
                    this.dispatchEvent(
                        new ShowToastEvent({
                            title: 'Success',
                            message: 'Case is submitted : ' + this.case.id,
                            variant: 'success',
                        }),
                    );
                })
            .catch(error => {
                this.dispatchEvent(
                    new ShowToastEvent({
                        title: 'Error creating record',
                        message: error.message,
                        variant: 'error',
                    }),
                );
            });
    }
}

 

communityexample.js-meta.xml

To use a component in Community Builder, edit the file to define the component’s design configuration values.

  • To make your component usable in Community Builder and in managed packages, set isExposed to true.
  • To make your component available in the Components tab in Community Builder, define lightningCommunity__Page in targets. Without this tag, your component can’t appear in Community Builder.
  • To include properties that are editable when the component is selected in Community Builder, define lightningCommunity__Default in targets and define the properties in targetConfigs.
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="helloWorld">
    <apiVersion>45.0</apiVersion>
    <isExposed>true</isExposed>
    <masterLabel>Case Create</masterLabel>
    <targets>
        <target>lightningCommunity__Page</target>
        <target>lightningCommunity__Default</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="lightningCommunity__Default">
            <property name="title" type="String" default="Submit Case"></property>
            <property name="buttonlabel" type="String" default="Submit Case"></property>
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>

 

Add an SVG Resource to Your Component Bundle

To define a custom icon for your component, add an SVG resource to your component’s folder. If you don’t include an SVG resource, the system uses a default icon (Lightning).

An SVG resource must be named component.svg. You can only have one SVG per folder.

communityexample.svg

 

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400">
    <circle cx="100" cy="100" r="50" stroke="black" stroke-width="5" fill="red" />
</svg>

 

Push changes to scratch org and add the changes to a community builder. Go to community builder and you can able to the LWC in community builder as shown below

 

 

 

Handle Input Changes in Lightning Web Components

Let us discuss here how to detect the input field value changes in lightning web components.T o listen for changes from an element in your template that accepts input, such as a text field. use the onchange or onkeypress event with an @track property.

Create a new Lightning Web component using the below SFDX command. In this example first, we are using the HTML input tag

sfdx force:lightning:component:create --type lwc --componentname inputchangeex --outputdir force-app\main\default\lwc

Use the below inputchangeex.html code

<template>
    Enterd Value - {myValue}
    <br />
    <input type="text" value={myValue} onkeypress={handleChange} />
</template>

Use the below inputchangeex.js code

import {
    LightningElement,
    track
} from 'lwc';

export default class Inputchangeex extends LightningElement {
    @track myValue = "initial value";
    handleChange(evt) {
        this.myValue = evt.target.value;
        console.log('Current value of the input: ' + evt.target.value);
    }

}

Use the below inputchange.js-meta.xml

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

 

Push the changes using the below SFDX command

 sfdx force:source:push

 

Add this component to the record page and you can able to see the output like below.

 

 

Let’s define the same code to use lightning-input . A lightning-input component creates an HTML input element.

Update the Html code as shown below and push the changes

<template>
    Lightning Input Value - {myValue}
    <br />
    <lightning-input type="text" value={myValue} onchange={handleChange} ></lightning-input>
</template>

You can able to see the input keypress changes

 

Lightning Web Component Methods

Let us Discuss here how to use the Lightning Web Component Methods. Use a JavaScript method to communicate down the containment hierarchy. For example, a parent component calls a method on a child component that it contains. Methods are part of a component’s API. Expose a method by adding the @api decorator to the method. To communicate up the containment hierarchy, fire an event in the child component with the dispatchEvent method, and handle it in the parent component. Please refer this link to Aura method 

1. Create a Lightning web Component

Create a lightning web component using the below SFDX command

sfdx force:lightning:component:create --type lwc --componentname inputmethod --outputdir force-app\main\default\lwc

This component contains one method that will convert the text into the upper cases. This example exposes changeUpperCase(), methods in a c-inputmethod component by adding the @api decorator to the methods. A parent component that contains c-inputmethod can call these methods.

Use the below inputmethod.html code

<template>
Upper Case : {upperCase} <br/>
</template>

Use the below inputmethod.js code

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

export default class Inputmethod extends LightningElement {
    @track upperCase;
    @api
    changeUpperCase(text) {
        this.upperCase = text.toUpperCase();
    }
   
}

Use the below inputmethod.js-meta.xml code

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

 

 

Call a Method

Now let’s see how to call the above method in the code  The c-method caller component contains c-inputmethod that call the changeuppercase() method in input change.  The this.template.querySelector() call is useful to get access to a child component so that you can call a method on the component.

Return Values

Use the return statement to return a value from a JavaScript method

@api
    changeUpperCase(text) {
        return 'value'
    }

 

Method Parameters

To pass data to a JavaScript method, define one or more parameters for the method. For example, you could define the change()
method to take an input parameter.

@api change(inp) { … }

 

2. Create a Lightning Web Component

Create another that will be calling the method.

sfdx force:lightning:component:create --type lwc --componentname methodcaller --outputdir force-app\main\default\lwc

 

use the below methodcaller.html code

<template>
    <lightning-card title="Container Cmp">
        <lightning-layout>
            <lightning-layout-item flexibility="auto">
                <lightning-input label="Input Phrase" onchange={handleChange}></lightning-input><br />
            </lightning-layout-item>
            <lightning-layout-item flexibility="auto">
                <h3> Method Source</h3>
                <c-changecase></c-changecase>
            </lightning-layout-item>
        </lightning-layout>
    </lightning-card>
</template>

 

use the below methodcaller.js code

import {
    LightningElement
} from 'lwc';

export default class Methodcaller extends LightningElement {
    handleChange(event) {
        this.template.querySelector('c-changecase').changeUpperCase(event.target.value);

    }
}

Use the below methodcaller.js-meta.xml code

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

 

push the changes and add it to the page layout and you can able to see the output as shown below.

Usage Of lightning-record-edit-form

Let us discuss here how to use the lightning-record-edit-form . A lightning-record-edit-form component is a wrapper component that accepts a record ID and is used to display one or more fields and labels associated with that record. The lightning-input-field component is used inside the lightning-record-edit-form to create editable fields. The lightning-output-field component and other display components such as lightning-formatted-name can be used to display read-only information in your form.lightning-record-edit-form requires a record ID to display the fields on the record. It doesn’t require additional Apex controllers or Lightning Data Service to display record data. This component also takes care of field-level security and sharing for you, so users see only the data they have access to.

lightning-record-edit-form and lightning-input-field support the following features.

  • Display a record edit layout for editing a specified record
  • Display a record create the layout for creating a new record

 

Editing a Record

To enable record editing, pass in the ID of the record and the corresponding object API name to be edited. Specify the fields you want to include in the record edit layout using lightning-input-field. Create a Lightning Web component using the below SFDX command

sfdx force:lightning:component:create --type lwc --componentname recordeditform --outputdir force-app\main\default\lwc

Use the below recordeditform.html code

<template>
<lightning-record-edit-form record-id={recordId} object-api-name="Contact"
onsuccess={handleSuccess} onsubmit ={handleSubmit} >
        <lightning-messages>
        </lightning-messages>
        <lightning-output-field field-name="AccountId">
        </lightning-output-field>
        <lightning-input-field field-name="FirstName">
        </lightning-input-field>
        <lightning-input-field field-name="LastName">
        </lightning-input-field>
        <lightning-input-field field-name="Email">
        </lightning-input-field>
        <lightning-button class="slds-m-top_small" variant="brand" type="submit" name="update" label="Update">
        </lightning-button>
    </lightning-record-edit-form>
</template>

Use the below recordeditform.js code

import {
    LightningElement,
    api
} from 'lwc';

export default class Recordeditform extends LightningElement {
    @api recordId;
    handleSubmit(event) {
        console.log('onsubmit: '+ event.detail.fields);

    }
    handleSuccess(event) {
        const updatedRecord = event.detail.id;
        console.log('onsuccess: ', updatedRecord);
    }
}

Use the recordeditform.js-meta.xml code

 

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

Push the changes and you can able to see the below screen and you can able to edit the contact record

 

 

 

Creating a Record

To enable record creation, pass in the object API name for the record to be created. Specify the fields you want to include in the record create layout using lightning-input-field components.  A record Id is generated when a record is created successfully. To return the Id, use the onsuccess handler.

Use the below recordeditform code.

<template>
    <lightning-record-edit-form object-api-name="Contact" onsuccess={handleSuccess}>
        <lightning-messages></lightning-messages>
        <div class="slds-m-around_medium">
            <lightning-input-field field-name='Id' value={contactId}></lightning-input-field>
            <lightning-input-field field-name='LastName'></lightning-input-field>
            <lightning-input-field field-name='FirstName'></lightning-input-field>
            <lightning-input-field field-name='Email'></lightning-input-field>
            <lightning-input-field field-name='AccountId'></lightning-input-field>

            <div class="slds-m-top_medium">
                <lightning-button variant="brand" type="submit" name="save" label="Create Contact">
                </lightning-button>
            </div>
        </div>
    </lightning-record-edit-form>
</template>
import {
    LightningElement,
    api,track
} from 'lwc';

export default class Recordeditform extends LightningElement {
    @track contactId;
    handleSuccess(event) {
        this.contactId = event.detail.id;
    }

}

 

Push the changes and you can able to see the below details as shown below.

Overriding Default Behaviors

To customize the behavior of your form when it loads or when data is submitted, use the onload and onsubmit attributes to specify event handlers. If you capture the submit event and submit the form programmatically, use event.preventDefault() to cancel the default behavior of the event. This prevents a duplicate form submission. Here in the example, we will be setting the fields values on the onsubmit behaviors.

Update the code as shown below which will set some of the account field values automatically.

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

export default class Recordeditform extends LightningElement {
    handleSubmit(event) {
        event.preventDefault(); // stop the form from submitting
        const fields = event.detail.fields;
        console.log(JSON.stringify(fields));

        fields.title = 'VP of Opearations';
        fields.MobilePhone = '2123123123213';
        fields.LeadSource = 'Web';
        this.template.querySelector('lightning-record-edit-form').submit(fields);
    }
    handleSuccess(event) {
        const payload = event.detail;
        console.log(JSON.stringify(payload));

        const updatedRecord = event.detail.id;
        console.log('onsuccess: ', updatedRecord);
    }

}

Use the below HTML code.

<template>
<lightning-record-edit-form object-api-name="Contact" onsuccess={handleSuccess} onsubmit={handleSubmit}>
        <lightning-messages></lightning-messages>
        <div class="slds-m-around_medium">
            <lightning-input-field field-name='Id' value={contactId}></lightning-input-field>
            <lightning-input-field field-name='LastName'></lightning-input-field>
            <lightning-input-field field-name='FirstName'></lightning-input-field>
            <lightning-input-field field-name='Email'></lightning-input-field>
            <lightning-input-field field-name='AccountId'></lightning-input-field>

            <div class="slds-m-top_medium">
                <lightning-button variant="brand" type="submit" name="save" label="Create Contact">
                </lightning-button>
            </div>
        </div>
    </lightning-record-edit-form>
</template>

 

Using Record Types

If your org uses record types, picklist fields display values according to your record types. You must provide a record type ID using the record-type-id attribute if you have multiple record types on an object and you don’t have a default record type. Otherwise, the default record type ID is used like below.

<lightning-record-edit-form object-api-name="Contact" record-type-id="003XXXXXXXXXXXXXXX" onsuccess={handleSuccess}>

</lightning-record-edit-form>

Error Handling

You must include lightning-messages to support error handling and displaying of error messages. If the record edit layout includes a lightning-button component with type="submit", when the button is clicked the lightning-record-edit-form component automatically performs error handling and saves any changes in the input fields. Similarly, if the record create layout provides a submit button, when the button is clicked error handling is automatically performed and a new record is created with the input data you provide. Additionally, the lightning-record-edit-form component provides basic input validation like below.

<template>
    <lightning-record-edit-form object-api-name="Contact"  onsuccess={handleSuccess}>
        <lightning-messages></lightning-messages>
        <div class="slds-m-around_medium">
          
        </div>
    </lightning-record-edit-form>
</template>

 

You can able to see the errors as shown below .