querySelectorAll), clearing their values, wiping any custom errors, and resetting the underlying tracked component state without writing manual reset lines for every single field.
Form handling is a core part of building enterprise Salesforce apps. As forms expand with dozens of fields—such as text inputs, comboboxes, and textareas—manually setting every variable to an empty string becomes repetitive and prone to bugs. Creating a reusable, dynamic reset pattern keeps your code clean, maintainable, and scalable.
Prerequisites
- A Salesforce Developer Edition, Scratch Org, or Sandbox environment.
- Salesforce CLI (
sf) configured and authenticated to your org. - Basic understanding of LWC template querying (
this.template.querySelectorAll) and data binding.
Step 1: Set Up the Component Bundle
sf lightning generate component -n resetInputFields -d force-app/main/default/lwc --type lwc
Step 2: Build the Dynamic Form Template
In resetInputFields.html, add multiple inputs across different field types. Group them with a custom class or data-field identifier so they can be targeted cleanly in JavaScript:
<template>
<lightning-card title="Dynamic Form Reset Demo" icon-name="utility:form">
<div class="slds-p-around_medium">
<div class="slds-grid slds-gutters slds-wrap">
<div class="slds-col slds-size_1-of-1 slds-medium-size_1-of-2 slds-m-bottom_small">
<lightning-input
label="Full Name"
data-field="fullName"
value={formData.fullName}
onchange={handleInputChange}
required>
</lightning-input>
</div>
<div class="slds-col slds-size_1-of-1 slds-medium-size_1-of-2 slds-m-bottom_small">
<lightning-input
type="email"
label="Email Address"
data-field="email"
value={formData.email}
onchange={handleInputChange}
required>
</lightning-input>
</div>
<div class="slds-col slds-size_1-of-1 slds-medium-size_1-of-2 slds-m-bottom_small">
<lightning-combobox
label="Industry"
data-field="industry"
value={formData.industry}
options={industryOptions}
onchange={handleInputChange}>
</lightning-combobox>
</div>
<div class="slds-col slds-size_1-of-1 slds-medium-size_1-of-2 slds-m-bottom_small">
<lightning-input
type="tel"
label="Phone Number"
data-field="phone"
value={formData.phone}
onchange={handleInputChange}>
</lightning-input>
</div>
<div class="slds-col slds-size_1-of-1 slds-m-bottom_medium">
<lightning-textarea
label="Additional Notes"
data-field="notes"
value={formData.notes}
onchange={handleInputChange}>
</lightning-textarea>
</div>
</div>
<!-- Action Buttons -->
<div class="slds-button-group" role="group">
<lightning-button
variant="brand"
label="Submit Form"
onclick={handleSubmit}>
</lightning-button>
<lightning-button
variant="neutral"
label="Reset All Fields"
onclick={handleReset}>
</lightning-button>
</div>
</div>
</lightning-card>
</template>
Step 3: Implement Dynamic Form Clearing & State Synchronization
In resetInputFields.js, store form values in a single state object. Query the DOM elements dynamically, clear both DOM values and validation messages, and reset your component state object back to its initial shape:
import { LightningElement, track } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
const INITIAL_STATE = {
fullName: '',
email: '',
industry: '',
phone: '',
notes: ''
};
export default class ResetInputFields extends LightningElement {
@track formData = { ...INITIAL_STATE };
get industryOptions() {
return [
{ label: 'Technology', value: 'Technology' },
{ label: 'Healthcare', value: 'Healthcare' },
{ label: 'Finance', value: 'Finance' },
{ label: 'Manufacturing', value: 'Manufacturing' }
];
}
handleInputChange(event) {
const fieldName = event.target.dataset.field;
this.formData[fieldName] = event.target.value;
}
handleReset() {
// Step 1: Query all standard form input controls in the template
const inputControls = this.template.querySelectorAll(
'lightning-input, lightning-combobox, lightning-textarea'
);
// Step 2: Clear values and reset visual validation error states
inputControls.forEach(control => {
control.value = '';
if (typeof control.setCustomValidity === 'function') {
control.setCustomValidity('');
control.reportValidity();
}
});
// Step 3: Reset JavaScript state object
this.formData = { ...INITIAL_STATE };
this.showToast('Form Reset', 'All input fields have been cleared.', 'info');
}
handleSubmit() {
const allValid = [
...this.template.querySelectorAll('lightning-input, lightning-combobox, lightning-textarea')
].reduce((validSoFar, inputCmp) => {
inputCmp.reportValidity();
return validSoFar && inputCmp.checkValidity();
}, true);
if (allValid) {
this.showToast('Success', 'Form submitted successfully!', 'success');
} else {
this.showToast('Error', 'Please complete all required fields.', 'error');
}
}
showToast(title, message, variant) {
this.dispatchEvent(new ShowToastEvent({ title, message, variant }));
}
}
control.value = '') without resetting your internal JavaScript state (this.formData) creates a state desynchronization bug. If a user enters data, clicks reset, and submits without retyping, the stale state in JavaScript would still send old data to your Apex backend. Always reset both DOM values and JavaScript state together.
- Selector Grouping: Use a comma-separated query selector (
'lightning-input, lightning-combobox, lightning-textarea') to target all input variants in a single loop. - Validation Clearing: Always invoke
setCustomValidity('')andreportValidity()when resetting to clear red error outlines. - Lightning Record Edit Forms: If you are using
lightning-record-edit-form, callfield.reset()on eachlightning-input-fieldchild instead of setting string values directly.
Step 4: Expose and Deploy the Component
Update resetInputFields.js-meta.xml to make the component available on Lightning pages:
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>60.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
<target>lightning__RecordPage</target>
<target>lightning__HomePage</target>
</targets>
</LightningComponentBundle>
# Deploy the component bundle
sf project deploy start
# Open target org in browser
sf org open
- In Salesforce Setup, navigate to Lightning App Builder.
- Place
resetInputFieldson any App or Record Page, save, and activate. - Fill in form fields, trigger validation errors, and click Reset All Fields to confirm all inputs and validation errors clear simultaneously.
querySelectorAll combined with an immutable initial state object ensures full, reliable form clearing across any number of inputs with minimal boilerplate code.