Custom Validations between Child, Parent and Grandparent component in LWC | LWC Stack ☁️⚡️

 In this blog you will learn how you may use validation between Child, Parent and Grandparent component.

The requirement was to have a button on the parent component and validate all child components validation on that button click.

To call the validation we will be using input report validity and checking the custom inputs validation. And to get the validation from child one we will use @api to call a function on the child component which will be checking the validation in it and send us a flag contains true or false.

Please follow the code snippet below : 


Child HTML

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<template>
  <div class="slds-box slds-theme_default">
    I am child
    <lightning-layout multiple-rows>
      <lightning-layout-item size="12" padding="around-small">
        <lightning-input
          label="Child Name"
          type="text"
          class="slds-p-top_medium"
          required
          onchange={handleChange}
        ></lightning-input>
      </lightning-layout-item>
      <lightning-layout-item size="12" padding="around-small">
        <lightning-input
          label="Child Phone"
          type="number"
          class="slds-p-top_medium"
          onchange={handleChange}
        ></lightning-input>
      </lightning-layout-item>
    </lightning-layout>
  </div>
</template>


Child JS

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import { LightningElement, api } from "lwc";

export default class Zchild extends LightningElement {
  @api
  checkValidity() {
    let isSelfValidated = false;
    isSelfValidated = [
      ...this.template.querySelectorAll("lightning-input")
    ].reduce((validSoFar, inputField) => {
      inputField.reportValidity();
      return validSoFar && inputField.checkValidity();
    }, true);
    return isSelfValidated;
  }
  handleChange() {}
}


Parent HTML

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<template>
  <div class="slds-box slds-theme_shade">
    I am parent
    <lightning-layout multiple-rows>
      <lightning-layout-item size="12" padding="around-small">
        <lightning-input
          label="Parent Name"
          type="text"
          class="slds-p-top_medium"
          required
          onchange={handleChange}
        ></lightning-input>
      </lightning-layout-item>
      <lightning-layout-item size="12" padding="around-small">
        <lightning-input
          label="Parent Phone"
          type="number"
          class="slds-p-top_medium"
          onchange={handleChange}
        ></lightning-input>
      </lightning-layout-item>
    </lightning-layout>
  </div>
  <c-zchild></c-zchild>
</template>


Parent JS

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import { LightningElement, api } from "lwc";

export default class Zparent extends LightningElement {
  @api
  checkValidity() {
    let isChildValidated = true;
    [...this.template.querySelectorAll("c-zchild")].forEach((element) => {
      if (element.checkValidity() === false) {
        isChildValidated = false;
      }
    });
    let isSelfValidated = true;
    isSelfValidated = [
      ...this.template.querySelectorAll("lightning-input")
    ].reduce((validSoFar, inputField) => {
      inputField.reportValidity();
      return validSoFar && inputField.checkValidity();
    }, true);
    if (isChildValidated && isSelfValidated) {
      return true;
    } else {
      return false;
    }
  }
  handleChange() {}
}


Grandparent HTML

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<template>
  <div class="slds-box slds-theme_shade slds-theme_alert-texture">
    I am grandparent
    <lightning-layout multiple-rows>
      <lightning-layout-item size="12" padding="around-small">
        <lightning-input
          label="Grandparent Name"
          type="text"
          class="slds-p-top_medium"
          onchange={handleChange}
          required
        ></lightning-input>
      </lightning-layout-item>
      <lightning-layout-item size="12" padding="around-small">
        <lightning-input
          label="Grandparent Phone"
          type="number"
          class="slds-p-top_medium"
          onchange={handleChange}
        ></lightning-input>
      </lightning-layout-item>
    </lightning-layout>
  </div>
  <c-zparent></c-zparent>
  <div class="slds-box slds-theme_shade slds-theme_alert-texture">
    <div class="slds-p-around_small">
      <div class="slds-clearfix">
        <div class="slds-float_right">
          <lightning-button
            label="Validate Components"
            class="slds-p-around_small"
            title="Validate Components"
            onclick={validate}
          ></lightning-button>
        </div>
      </div>
    </div>
  </div>
</template>


Grandparent JS

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import { LightningElement } from "lwc";
import { ShowToastEvent } from "lightning/platformShowToastEvent";

export default class ZgrandParent extends LightningElement {
  handleChange() {}
  validate() {
    let isSelfValidated = true;
    isSelfValidated = [
      ...this.template.querySelectorAll("lightning-input")
    ].reduce((validSoFar, inputField) => {
      inputField.reportValidity();
      return validSoFar && inputField.checkValidity();
    }, true);

    let isChildValidated = true;
    [...this.template.querySelectorAll("c-zparent")].forEach((element) => {
      if (element.checkValidity() === false) {
        isChildValidated = false;
      }
    });
    if (isChildValidated && isSelfValidated) {
      this.dispatchEvent(
        new ShowToastEvent({
          title: "Success.",
          message: "Validated Successfully.",
          variant: "success"
        })
      );
    } else {
      this.dispatchEvent(
        new ShowToastEvent({
          title: "Error.",
          message: "Input values are not correct !",
          variant: "error"
        })
      );
    }
  }
}


Output



Checkout complete tutorial below

 If you have any question please leave a comment below.

If you would like to add something to this post please leave a comment below.
Share this blog with your friends if you find it helpful somehow !

Thanks
Happy Coding :)

Post a Comment

2 Comments