2

tl;dr - How does one get input validation to work for an LWC in the flow builder?

Background

I have created an LWC for text input that will alert the user when they are approaching or have exceeded the character limit for that field. I want the flow to prevent the user from going to the next flow page if the text entered into my component is greater than the passed character limit. My component is working fine, but I am having trouble getting the Flow to validate the data entered.

I have tried following the instructions on the Develop Components for Flow Screens section for adding a validation method, and have added a "validate" method to the javascript of the component. However, when I enter a value over the passed character limit and click "next" in the flow page, no error occurs.

One solution I found here suggests adding a "Next" button as part of the component, but I'd prefer to use the native flow "Next" button if possible. Can this be done, and if so, what is missing from my code?

Code

HTML

<template>
  <lightning-input
    name={field}
    label={fieldName}
    onchange={handleChange}
  ></lightning-input>
  <template if:true={isErrorMessage}>
    <span class="slds-text-color_error">{errorMessage}</span>
  </template>
</template>

JS

import { LightningElement, api } from "lwc";

export default class TextInputForFlow extends LightningElement {
  @api fieldName;
  @api characterLimit = 255;
  @api fieldValue;

  errorMessage = "";

  get errorMessageLength() {
    return this.errorMessage.length;
  }
  set errorMessageLength(event) {
    return this.errorMessage.length;
  }

  get isErrorMessage() {
    return this.errorMessageLength > 0;
  }
  set isErrorMessage(event) {
    return this.errorMessageLength > 0;
  }

  handleChange(event) {
    let length = event.target.value.length;
    // console.log(`length: ${length}`);
    if (length > this.characterLimit) {
      this.errorMessage = `Your answer must be less than 255 characters. Your character counts is ${length}`;
      this.validate();
    } else if (
      (length <= this.characterLimit) &
      (length > this.characterLimit - 25)
    ) {
      let left = this.characterLimit - length;
      this.errorMessage = `You have ${left} of ${this.characterLimit} characters remaining`;
      this.fieldValue = event.target.value;
      this.validate();
    } else {
      this.errorMessage = "";
      this.fieldValue = event.target.value;
      this.validate();
    }
  }

  @api
  validate() {
    if (this.fieldValue.length <= this.characterLimit) {
      return { isValid: true };
    }
    return {
      isValid: false,
      errorMessage: "/*Your answer must be less than 255 characters*/"
    };
  }
}

XML

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>48.0</apiVersion>
    <isExposed>True</isExposed>
    <targets>
        <target>lightning__FlowScreen</target>
        <target>lightning__HomePage</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="lightning__FlowScreen, lightning__HomePage">
            <property name="fieldName" label="Field Name" type="String" />
            <property name="characterLimit" label="Character Limit" type="Integer" />
            <property name="fieldValue" label="Field Value" type="String" />
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>

3 Answers 3

3

You will also need to dispatch the FlowAttributeChangeEvent telling flow the attribute value has changed like this

 handleChange(event) {
    let length = event.target.value.length;
    const attributeChangeEvent = new FlowAttributeChangeEvent('fieldValue', event.target.value);
        this.dispatchEvent(attributeChangeEvent);  


    // console.log(`length: ${length}`);
    if (length > this.characterLimit) {
      this.errorMessage = `Your answer must be less than 255 characters. Your character counts is ${length}`;

    } else if (
      (length <= this.characterLimit) &
      (length > this.characterLimit - 25)
    ) {
      let left = this.characterLimit - length;
      this.errorMessage = `You have ${left} of ${this.characterLimit} characters remaining`;
      this.fieldValue = event.target.value;

    } else {
      this.errorMessage = "";
      this.fieldValue = event.target.value;

    }
  }
2
  • Thanks so much. This code is working, with one strange exception. If I click "next" on the flow without having entered any data into the lwc-field, the button does not respond and remains unresponsive even after entering data. Do you have any idea as to what might be causing this?
    – Jwok
    May 14, 2020 at 17:07
  • Nevermind, I seem to have fixed the problem by setting fieldValue = "" at the start of the JS file
    – Jwok
    May 14, 2020 at 17:22
1

For any future readers, the final code for this project was as follows:

HTML

<template>
  <lightning-input
    name={field}
    label={fieldName}
    onchange={handleChange}
  ></lightning-input>
  <template if:true={isErrorMessage}>
    <span class="slds-text-color_error">{errorMessage}</span>
  </template>
</template>

JS

import { LightningElement, api } from "lwc";
import { FlowAttributeChangeEvent } from "lightning/flowSupport";

export default class TextInputForFlow extends LightningElement {
  @api fieldName;
  @api characterLimit = 255;
  @api fieldValue = "";

  errorMessage = "";

  renderedCallback(){
    this.validate();
  }

  get errorMessageLength() {
    return this.errorMessage.length;
  }
  set errorMessageLength(event) {
    return this.errorMessage.length;
  }

  get isErrorMessage() {
    return this.errorMessageLength > 0;
  }
  set isErrorMessage(event) {
    return this.errorMessageLength > 0;
  }

  handleChange(event) {
    let length = event.target.value.length;

    const attributeChangeEvent = new FlowAttributeChangeEvent(
      "fieldValue",
      event.target.value
    );

    this.dispatchEvent(attributeChangeEvent);

    if (length > this.characterLimit) {
      this.errorMessage = `Your answer must be less than 255 characters. Your character counts is ${length}`;
    } else if (
      (length <= this.characterLimit) &
      (length > this.characterLimit - 25)
    ) {
      let left = this.characterLimit - length;
      this.errorMessage = `You have ${left} of ${this.characterLimit} characters remaining`;
      this.fieldValue = event.target.value;
    } else {
      this.errorMessage = "";
      this.fieldValue = event.target.value;
    }

  }

  @api
  validate() {
    let length = this.fieldValue.length;
    console.log(`length: ${length}`);
    if ((length <= this.characterLimit) & (length > 0)) {
      return { isValid: true };
    } else if (length === 0 || this.fieldValue === null) {
      return {
        isValid: false,
        errorMessage: "This field is required"
      };
    }
    return {
      isValid: false,
      errorMessage: "Your answer must be less than 255 characters"
    };
  }
}

XML

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>48.0</apiVersion>
    <isExposed>True</isExposed>
    <targets>
        <target>lightning__FlowScreen</target>
        <target>lightning__HomePage</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="lightning__FlowScreen, lightning__HomePage">
            <property name="fieldName" label="Field Name" type="String" />
            <property name="characterLimit" label="Character Limit" type="Integer" />
            <property name="fieldValue" label="Field Value" type="String" />
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>

The only issue I am now facing is that if an end-user selects "next" while there are more than the allotted characters allowed in the field, the field value resets to blank when the screen reloads and the error message is displayed. I will likely post this as a new question if I cannot resolve it internally.

2
  • Were you able to find solution for the screen reload? May 10 at 20:57
  • @VinodAgrawal unfortunately I'm no longer at the job where I did this work so I can't review the flow in question. I'd recommend you create a new question for your issue
    – Jwok
    May 11 at 23:42
0

I have tried to incorporate this solution in my scenario yet but I am still being able to move forward without giving any input, Please help. I have a search field were on typing an some characters I get back accounts, I use this component in a flow and what I want to achieve is, if no account is chosen then it should not allow me to move forward.(I also want to use standard footers)

2
  • If you have a new question, please ask it by clicking the Ask Question button. Include a link to this question if it helps provide context. - From Review
    – Derek F
    Jun 23 at 11:32
  • Welcome to Salesforce Stack Exchange (SFSE)! Please see the note about "commentary on...other answers" in Why and how are some answers deleted? & be aware that this "answer" will most likely be deleted. Please contribute to SFSE in other ways so you gain reputation - you only need 15 rep to upvote a post & only 50 to comment under someone else's post. Or you could ask a new question & in it link to this question's other answer for reference.
    – Moonpie
    Jun 23 at 12:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.