Skip to main content

How to Dynamically Reset Form Input Fields in Salesforce LWC

In plain words: Resetting input fields dynamically in Lightning Web Components (LWC) means using JavaScript to select all form inputs in one step (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

Generate Component via CLI:
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 }));
    }
}
Warning Trap: Clearing only the DOM elements (e.g. 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.
360 Architecture Summary:
  • 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('') and reportValidity() when resetting to clear red error outlines.
  • Lightning Record Edit Forms: If you are using lightning-record-edit-form, call field.reset() on each lightning-input-field child 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>
Deployment & Testing:
# 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 resetInputFields on 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.
Core Takeaway: Selecting form controls dynamically via querySelectorAll combined with an immutable initial state object ensures full, reliable form clearing across any number of inputs with minimal boilerplate code.