Child-to-Parent Communication In LWC With Example

Scenario: Build a Lightning Web Components (LWC) system demonstrating Child-to-Parent Communication

Requirements:

  1. Create a Parent Component that initially displays a button labeled “Fill the Data”.
  2. Upon clicking this button, a Child Component is rendered as a multi-step form:
  3. The Child Component should display three input fields:
    • Step 1: Collects Name and Email.
    • Step 2: Collects Phone Number and shows the Submit button.
    • User can navigate between steps using “Next” and “Back” buttons.
  4. When the user clicks the Submit button, the entered data is passed from the Child to the Parent using an event.
  5. After receiving the data, the Parent Component should display a confirmation message in the following format: “Welcome [Name], you are registered successfully.”

Parent Component

HTML-

<template>
    <div class="slds-p-around_medium">
        <template lwc:if={isDataSubmitted}>
            <div class="slds-box slds-theme_success slds-m-bottom_medium">
                <p class="slds-text-heading_small">
                    Welcome, <strong>{name}</strong>! You have registered successfully.
                </p>
                <p class="slds-m-top_small">Here are your submitted details:</p>
                <ul class="slds-list_dotted slds-m-top_x-small">
                    <li><strong>Name:</strong> {name}</li>
                    <li><strong>Email:</strong> {email}</li>
                    <li><strong>Phone:</strong> {phone}</li>
                </ul>
            </div>
        </template>

        <template lwc:else>
            <lightning-button 
                variant="brand" 
                label="Fill User Details" 
                onclick={showChildCmp}>
            </lightning-button>
        </template>

        <template if:true={showChild}>
            <c-child-component onsubmit={handleSubmit}></c-child-component>
        </template>
    </div>
</template>

JavaScript-

import { LightningElement } from 'lwc';

export default class ParentComponent extends LightningElement {
    showChild = false;
    isDataSubmitted = false;

    name = '';
    email = '';
    phone = '';

    showChildCmp() {
        this.showChild = true;
    }

    handleSubmit(event) {
        const { name, email, phone } = event.detail;

        this.name = name;
        this.email = email;
        this.phone = phone;

        this.showChild = false;
        this.isDataSubmitted = true;
    }
}

Child Component

HTML-

<template>
    <div class="form-container">
        <template lwc:if={isStepOne}>
            <lightning-input
                type="text"
                name="name"
                label="Enter your name"
                value={name}
                onchange={handleInputChange}>
            </lightning-input>

            <lightning-input
                type="email"
                name="email"
                label="Enter your email"
                value={email}
                onchange={handleInputChange}>
            </lightning-input>

            <lightning-button
                label="Next"
                variant="brand"
                class="slds-m-top_medium"
                onclick={goToStepTwo}>
            </lightning-button>
        </template>

        <template lwc:if={isStepTwo}>
            <lightning-input
                type="tel"
                name="phone"
                label="Enter your phone number"
                value={phone}
                onchange={handleInputChange}>
            </lightning-input>

            <div class="slds-m-top_medium">
                <lightning-button
                    label="Back"
                    class="slds-m-right_small"
                    onclick={goToStepOne}>
                </lightning-button>

                <lightning-button
                    label="Submit"
                    variant="brand"
                    onclick={handleSubmit}>
                </lightning-button>
            </div>
        </template>
    </div>
</template>

JavaScript-

import { LightningElement } from 'lwc';

export default class ChildComponent extends LightningElement {
    name = '';
    email = '';
    phone = '';
    isStepOne = true;
    isStepTwo = false;

    handleInputChange(event) {
        const field = event.target.name;
        this[field] = event.target.value;
    }

    goToStepTwo() {
        if (!this.name.trim() || !this.email.trim()) {
            alert('Please complete all fields in Step 1');
            return;
        }
        this.isStepOne = false;
        this.isStepTwo = true;
    }

    goToStepOne() {
        this.isStepTwo = false;
        this.isStepOne = true;
    }

    handleSubmit() {
        if (!this.phone.trim()) {
            alert('Please enter your phone number');
            return;
        }

        const userDetails = {
            name: this.name,
            email: this.email,
            phone: this.phone
        };

        this.dispatchEvent(new CustomEvent('submit', {
            detail: userDetails
        }));
    }
}

CSS-

.form-container {
    padding: 1rem;
    background-color: #f4f6f9;
    border-radius: 10px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

Leave a Comment

Your email address will not be published. Required fields are marked *