Retain input values while validating custom Flow Screen Lightning components – Part 2

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. 🙂

14 thoughts on “Retain input values while validating custom Flow Screen Lightning components – Part 2

  1. Pingback: Adding Validation Errors on Individual Inputs in custom Flow Screen Components – Part 3 |  forcePanda

  2. 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.

    Like

  3. 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.

    Like

    • 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. 🙂

      Like

    • 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. 🙂

      Like

  4. 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.

    Like

  5. 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.

    Like

  6. Pingback: From Josh Dayment & Ryan Mercer: Improved File Upload in Flow Screens – UnofficialSF

  7. 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.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.