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 .

 

Usage Of lightning-record-view-form

Let us discuss here how to use the lightning-record-view-form. A lightning-record-view-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 using lightning-output-fieldlightning-record-view-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.

Displaying Record Fields

Create a Lightning web component using the below SFDX command.

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

Use the below recordview.html code

<template>
    <lightning-record-view-form record-id={recordId} object-api-name="Contact">
        <div class="slds-box">
            <lightning-output-field field-name="FirstName">
            </lightning-output-field>
            <lightning-output-field field-name="LastName">
            </lightning-output-field>
            <lightning-output-field field-name="MobilePhone">
            </lightning-output-field>
            <lightning-output-field field-name="Email">
            </lightning-output-field>
        </div>
    </lightning-record-view-form>
</template>

Use the below recordview.js code

import { LightningElement ,api} from 'lwc';

export default class Recordview extends LightningElement {
    @api recordId ;
}

Use the below recordview.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 changes and add to the page layouts.you can able to see the below output.

To create a multi-column layout for your record view, use the Grid utility classes in Lightning Design System. This example creates a two-column layout.

Update the code as shown below.

<template>
    <lightning-record-view-form record-id={recordId} object-api-name="Account">
        <div class="slds-grid">
            <div class="slds-col slds-size_1-of-2">
                <lightning-output-field field-name="Name"></lightning-output-field>
                <lightning-output-field field-name="Phone"></lightning-output-field>
            </div>
            <div class="slds-col slds-size_1-of-2">
                <lightning-output-field field-name="Industry"></lightning-output-field>
                <lightning-output-field field-name="AnnualRevenue"></lightning-output-field>
            </div>
        </div>
    </lightning-record-view-form>
</template>

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

 

We’ve seen how record fields render using lightning-input-field and lightning-output-field. To render data in a custom way, use the getRecord or getRecordUi wire adapters.

Update the code as shown below.

<template>
    <lightning-record-view-form record-id={recordId} object-api-name={accountObject}>
        <div class="slds-grid">
            <div class="slds-col slds-size_1-of-2">
                <!-- Other record data here -->
            </div>
            <div class="slds-col slds-size_1-of-2">
                <lightning-formatted-text value={nameValue} class="slds-text-heading_large">
                </lightning-formatted-text>
            </div>
        </div>
    </lightning-record-view-form>
</template>

 

In the component’s JavaScript code, import references to the account object and the name field. The getRecord wire adapter loads the name field for custom rendering in the lightning-formatted-text component instead of the standard lightning-output-field used by lightning-record-view-form.

update the code as shown below.

import {
    LightningElement,
    api,
    wire
} from 'lwc';
/* Wire adapter to fetch record data */
import {
    getRecord,
    getFieldValue
} from 'lightning/uiRecordApi';
import ACCOUNT_OBJECT from '@salesforce/schema/Account';
import NAME_FIELD from '@salesforce/schema/Account.Name';
export default class Recordview extends LightningElement {
    /** Id of record to display. */
    @api recordId;

    /* Expose schema objects/fields to the template. */
    accountObject = ACCOUNT_OBJECT;

    /* Load Account.Name for custom rendering */
    @wire(getRecord, {
        recordId: '$recordId',
        fields: [NAME_FIELD]
    })
    record;

    /** Gets the Account.Name value. */
    get nameValue() {
        return this.record.data ? getFieldValue(this.record.data, NAME_FIELD) : '';
    }
}

 

You can able to see the UI as shown below.