Hello and welcome back! 😀
In our previous post, we discussed how we can validate custom flow screen components, and towards the end of it we also touched upon the different limitations of this validation approach.
In today’s article we shall aim at finding the solution to one of the limitations we discussed in the previous post, i.e. Previous inputs from user get lost when the component rerenders.
So in order to get around this we can use SessionStorage to store the input values. With SessionStorage, web applications can store data locally within the user’s browser per session. To know more, follow this link:
https://www.w3schools.com/html/html5_webstorage.asp
This idea was suggested to me by Alex Edelstein, Product Manager of Flows, Salesforce. Unfortunately, this doesn’t provide us a complete solution to our problem which we will address towards the end of this article. Right now, let’s see how we can achieve this.
Logic
The idea is to temporarily store the values input by user into the the SessionStorage of the web browser everytime a user hits the Next button, and initialize the component input fields with those values when component validation fails.
Let’s flow!
To keep things simple, I created a simple flow screen lightning component with two inputs.
FlowScreenCMPsValidation.cmp
<aura:component implements="lightning:availableForFlowScreens" access="global">
<aura:handler name="init" value="{!this}" action="{!c.init}"/>
<aura:attribute name="validate" type="Aura.Action"
description="Custom validation function to run when the flow is navigated to the next screen. The function must evaluate the component and return values for isValid and errorMessage."
/>
<aura:attribute name="firstName" type="String"/>
<aura:attribute name="lastName" type="String"/>
<lightning:input type="text" label="First Name" value="{!v.firstName}" required="true"/>
<lightning:input type="text" label="Last Name" value="{!v.lastName}" required="true"/>
</aura:component>
FlowScreenCMPsValidationController.js
({
init: function(component, event, helper) {
//Get inputs when validation failed
if(sessionStorage){
if(sessionStorage.getItem('validationfailed')){
if(sessionStorage.getItem('isFirstNameValid'))
component.set('v.firstName',sessionStorage.getItem('firstName'));
if(sessionStorage.getItem('isLastNameValid'))
component.set('v.lastName',sessionStorage.getItem('lastName'));
}
}
// Set the validate attribute to a function that includes validation logic
component.set('v.validate', function() {
var isFirstNameValid=false; //Check if input is valid
var firstName = component.get('v.firstName');
if(firstName && firstName.length>0)
isFirstNameValid = true;
var isLastNameValid=false; //Check if input is valid
var lastName = component.get('v.lastName');
if(lastName && lastName.length>0)
isLastNameValid = true;
//When all fields are valid, remove the values from sessionStorage
if(isFirstNameValid && isLastNameValid){
if(sessionStorage){
sessionStorage.removeItem('validationfailed'); sessionStorage.removeItem('firstName');
sessionStorage.removeItem('lastName'); sessionStorage.removeItem('isFirstNameValid');
sessionStorage.removeItem('isLastNameValid');
}
return { isValid: true };
}
// When validation fails
else{
if(sessionStorage){
//Set the input values into sessionStorage
sessionStorage.setItem('validationfailed',true);
sessionStorage.setItem('isFirstNameValid',isFirstNameValid);
sessionStorage.setItem('isLastNameValid',isLastNameValid);
if(isFirstNameValid)
sessionStorage.setItem('firstName',firstName);
else
sessionStorage.setItem('firstName','');
if(isLastNameValid)
sessionStorage.setItem('lastName',lastName);
else
sessionStorage.setItem('lastName','');
}
return {isValid: false,
//Validation Error message
errorMessage: 'Please fill all the required fields on the page.'
};
}
})
}
})
Time for some action!

But there’s a catch!
As we discussed in the beginning, this workaround doesn’t really provide us the complete solution. Why? Because the SessionStorage is browser dependent. So if a user is running the flow via Mobile app, this solution will not work. So the hunt for a better solution is still on!
Now if you are wondering, what about the second limitation which we discussed in my previous post. We shall try to address it in the part of this series. 🙂
I dropped an idea on the community for the same. Please upvote to make our life easy!
Thank you for being an awesome reader! Subscribe to this blog for all the updates delivered straight to your inbox. 🙂
Pingback: Adding Validation Errors on Individual Inputs in custom Flow Screen Components – Part 3 | forcePanda
Narender, Thank you for this post. If you click the Previous button, does it show the screens with previously entered values ? I mean, screen with Y value –> click Previous –> Screen with X value.
I am validating with Decision element and I am facing this issue.Looks like Salesforce is storing a snapshot of each screen. Is there a workaround?
I do have issues with retaining the value with decision element and that’s how I found your post. I understand this is an old post but hope you would answer. Thanks again.
LikeLike
Hi Sano,
This post is only applicable when you are validating the inputs for a custom lightning component placed on a flow screen. To get more context of what I’m talking about, you should read the part 1 of this article. https://forcepanda.wordpress.com/2019/07/09/how-to-validate-custom-flow-screen-components-in-flows-part-1/
And for your use case, I’m not really sure how you are using a decision element to validate the inputs for a lightning component because that’s not possible as far as I know.
LikeLike
Oh ok. Thanks for the context.In my case, I am unable to validate that a number/ text field can’t be null in a flow screen. ISNULL/ISBLANK doesn’t seem to work. I have to use a decision element to check and then route back to the screen if the field is null . When the screen is displayed again, all the other entered values are wiped out. Ideally, all entered values need to be retained and the error message displayed for the null field.
On a out of the box flow screen with date/text/number component,is it possible to have custom code only for the Next button, to check & retain values?
Is Validate the wrong word in this scenario? Just checking because I am not a born English speaker.Thank you.
LikeLike
Are you using the standard flow screen input component to get the user input or are you getting the input in a custom flow screen lightning component?
P.S. Validate is indeed the RIGHT word here. 🙂
LikeLike
I ma using the standard flow screen input component
LikeLike
In that case, validating the input should not be a problem. You can simply check if the input is blank or not like this:
NOT(ISBLANK( {!input} ))
NOTE: In flows, the validation triggers when the expression returns false.
Also, if you just want to have check for NULL, why not just make the input required by checking the ‘Require’ checkbox. 🙂
LikeLike
This was the first formula I tried, NOT(ISBLANK( {!input} )) — Doesn’t work. It is so weird though. I don’t understand why Salesforce doesn’t recognize this.
Required Checkbox displays a generic message. It has a second sentence ‘ Input is not optional’ which is quite off-putting. So, we want to do a custom message.
is it possible to have custom code only for the Next button?Thank you.
LikeLike
Oh yes, it won’t work. Because according to the documentation, if the input is left blank and is not marked required, the validation will not be triggered.
LikeLike
And for overriding the standard behavior for flow buttons, you can refer this: https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/components_config_for_flow_screens_replace_footer.htm
LikeLike
Hi , can you implement the same with lightning web component and demo it.
Currently am using LWC screens with Lightning Flows.
Once the flow is launched the LWC screen will be displayed and if User missed any of the fields the validation needs to throw a toast message and error message also display at the field level. After all the fields are having values onClick of next button , need to pass the values to Flow. and create element in flow would create the record.
am able to validate the input values but nothing moves forward after validation the toast message keeps on coming when i click next button.
LikeLike
am working with a combination of lightning-record-edit-form and lightning-input-field in LWC
LikeLike
Pingback: From Josh Dayment & Ryan Mercer: Improved File Upload in Flow Screens – UnofficialSF
Thanks for making me feel like I’m not crazy. I spent the better part of two hours yesterday trying to implement flowAttributeChangeEvents to solve for this problem, and for the life of me couldn’t get values to stick on rerender when we were performing a validate() in a custom LWC.
Surprising to me that this isn’t a base level of behavior for LWCs.
LikeLike