Custom Navigation Model for Flow Screens with Lightning Component

In this blog, I am going to explain how to use the custom lightning component button that is used to control the navigation of flow.By default, users navigate a flow by clicking standard buttons at the bottom of each screen. The lightning:availableForFlowScreens interface provides two attributes to help you fully customize your screen’s navigation. To figure out which navigation actions are available for the screen, loop through the availableActions attribute. To programmatically trigger one of those actions, call the navigateFlow action from your JavaScript controller.

Flow Navigation Actions

The availableActions attribute lists the valid navigation actions for that screen NEXT, BACK, PAUSE, RESUME, FINISH are the possible actions. A screen’s available actions are determined by:

  • Where in the flow the screen is. For example, Previous isn’t supported on the first screen in a flow, Finish is supported for only the last screen in a flow, and you can never have both Next and Finish.
  • Whether the flow creator opted to hide any of the actions in the screen’s Navigation Actions controls. For example, if Allow Pause is de-selected, the Pause action isn’t included in availableActions.

Component 

Here is the lightning component

<aura:component implements="lightning:availableForFlowScreens" access="global" >
    <!-- Get the script text from the flow -->    
    <aura:attribute name="scriptText" type="String" required="true" />
    <!-- Pass the value of the selected option back to the flow -->
    <aura:attribute name="value" type="String" />
    <aura:attribute name="action" type="String" />
    <div class="script-container">
        Navigation Action :   {!v.value}
    </div>
    <!-- Buttons for the agent to click, according to the customer’s response -->
    <div class="slds-p-top_large slds-p-bottom_large">
        <p><lightning:formattedText value="Customer Response" 
                                    class="slds-text-body_small" /></p>
        <lightning:buttongroup >
            <lightning:button label="Previous" aura:id="previousId" 
                              variant="neutral" onclick="{!c.handleChange}"/>
            <lightning:button label="Next" aura:id="nextId" 
                              variant="neutral" onclick="{!c.handleChange}"/>
            <lightning:button label="Finish" aura:id="finishId" 
                              variant="neutral" onclick="{!c.handleChange}"/>
            
        </lightning:buttongroup>
    </div>
</aura:component>

 

({
    handleChange : function(component, event, helper) {
        // When an option is selected, navigate to the next screen
        var response = event.getSource().getLocalId();
        component.set("v.value", response);
        var navigate = component.get("v.navigateFlow");
        console.log('navigate'+navigate)
        if(response=='previousId'){
            navigate("BACK");
        }
        if(response=='nextId'){
            navigate("NEXT");
        }
        if(response=='finishId'){
            navigate("FINISH");
        }  
    }
})

 

<design:component>
    <design:attribute name="scriptText" label="Script Text" 
                      description="What the agent should say to the customer" />
    <design:attribute name="action" label="Navigation Action" 
                      description="" />
        
</design:component>

Flow 

Here the simple flow that I created for testing
You can see below the image that shows how the lightning component interacts with flow navigation.
Once you click the next button on the component it will take to the next action i.e Finish.

Using Lightning Components In Visualforce page

In this blog, I am going to explain how to invoke the lightning component from the visualforce page by using Lightning out. Add Lightning components to your Visualforce pages to combine features you’ve built using both solutions. Implement new functionality using Lightning components and then use it with existing Visualforce pages. Lightning Components for Visualforce is based on Lightning Out, a powerful and flexible feature that lets you embed Lightning components into almost any web page.

Step 1: Create Sample Component

Create a lightning component with below code which contains two attributes

<aura:component access="global">
    <aura:attribute name="greeting" type="String" default="Hello" access="global" />
    <aura:attribute name="subject" type="String" default="World" access="global" />
    <div style="box">
        <span class="greeting">{!v.greeting}</span>, {!v.subject}!
    </div>
    
</aura:component>

Step 2: Create  Lightning Dependency App

To use Lightning Components for Visualforce, define component dependencies by referencing a Lightning dependency app. This app is globally accessible and extends ltng:outApp. The app declares dependencies on any Lightning definitions (like components) that it uses.

<aura:application access="GLOBAL" extends="ltng:outApp">
    <aura:dependency resource="c:helloworld"/>   
</aura:application>

Step 3: Using in Visualforce from the page

There are three steps to add Lightning components to a Visualforce page.

  1. Add the Lightning Components for Visualforce JavaScript library to your Visualforce page using the <apex:includeLightning/>  component.
    <apex:includeLightning/>
  2. To reference this app on your page, use the following JavaScript code.
    $Lightning.use("theNamespace:lcvfTest", function() {});
    
  3. Finally, add your top-level component to a page using $Lightning.createComponent(String type, Object attributes, String locator, function callback). This function is similar to $A.createComponent(), but includes an additional parameter, domLocator, which specifies the DOM element where you want the component inserted.

Here is the final code.

<apex:page docType="html-5.0" standardStylesheets="false" >
    <apex:includeLightning />
    
    <div id="lightning" />
    
    <script>
    $Lightning.use("c:helloworldApp", function() {
        $Lightning.createComponent("c:helloworld",
                                   {
                                       "greeting" : "Hello" ,
                                       "subject" : "World!" 
                                   },
                                   "lightning",
                                   function(cmp) {
                                       // do some stuff
                                   });
    });
    </script>
</apex:page>

 

 

Dynamically Update a Flow Screen with a Lightning Component

In this post, I am going to explain how to dynamically update the flow screen with the lightning component. To conditionally display a field on your screen, build a Lightning component that uses aura: if to check when parts of the component should appear. This component displays a custom script component and a group of radio buttons. The component gets the user feedback based on user-selected yes or no options.

If the user selects the Yes radio button, the component displays  form for the user get in touch details

If the user selects the Yes radio button, the component displays thanks message.

Here is the lightning component

<aura:component access="global" implements="lightning:availableForFlowScreens">
    
    <aura:attribute name="radioOptions" type="List" default="[
                                                             {'label': 'Yes', 'value': 'false'},
                                                             {'label': 'No', 'value': 'true'} ]"/>
    <aura:attribute name="radioValue" type="Boolean" default="true"/>
    <div class="survey-container">
        <div class="slds-card__header slds-grid slds-p-bottom_small slds-m-bottom_none">
            <div class="slds-media slds-media_center slds-has-flexi-truncate" >
                <div class="slds-media__figure slds-align-top">
                    <h2><lightning:icon iconName="utility:quotation_marks"
                                        title="Get in touch Details" /></h2>
                </div>
                <div class="slds-media__body">
                    <ui:outputRichText class="script" value="{!'Would you like to Get in touch with Sales?'}"/>
                </div>
            </div>
        </div>
    </div>
    
    <div class="slds-p-top_medium slds-p-bottom_medium">
        <lightning:radioGroup aura:id="rbg_correct" name="rbg_correct"
                              label="Would you like to take survey?"
                              options="{! v.radioOptions }" value="{! v.radioValue }" />
        <aura:if isTrue="{!v.radioValue}">
            <div class="slds-media__body">
                <ui:outputRichText class="script" value="{!'Thanks for your Time'}"/>
            </div>
        </aura:if>
        
        <aura:if isTrue="{!v.radioValue}">
            <aura:set attribute="else">
                <lightning:input label="Name" name="Name" class="slds-p-top_small" />
                <lightning:input type="tel"  label="Phone" class="slds-p-top_small"/>
                <lightning:input type="date" label="Birthday" name="date" class="slds-p-top_small"/>
                <lightning:input type="email" label="Email" name="email" value="abc@domain.com" class="slds-p-top_small"/>
            </aura:set>
            
        </aura:if>
        
    </div>
    
    
</aura:component>

Here is the flow which created for this example 

Below image shows how to invoke the lightning component in flow designer.

 

Width Aware Lightning Page Components

In this post, I am going to show how to design you are lighting component region aware to adjust the width by using lightning:flexipageRegionInfo which Provides Lightning page region information to the component that contains it and passes the width of the region that the component is dropped into in the Lightning App Builder. When you add a component to a region on a page in the Lightning App Builder, the lightning:flexipageRegionInfo sub-component passes the width of that region to its parent component. With lightning:flexipageRegionInfo and some strategic CSS, you can tell the parent component to render in different ways in different regions at runtime. For example, the ListView component renders differently in a large region than it does in a small region as it’s a width-aware component. Valid region width values are Small, Medium, Large, and Xlarge.You can use CSS to style your component and to help determine how your component renders. The following example component has two fields, field1 and field2. The component renders with the fields side by side, filling 50% of the region’s available width when not in a small region. When the component is in a small region, the fields render as a list, using 100% of the region’s width.

<aura:component implements="flexipage:availableForAllPageTypes">
    <aura:attribute name="width" type="String"/>
    <lightning:flexipageRegionInfo width="{!v.width}"/>
    <div class="{! 'container' + (v.width=='SMALL'?' narrowRegion':'')}">
        <div class="{! 'eachField f1' + (v.width=='SMALL'?' narrowRegion':'')}">
            <lightning:input name="field1" label="First Name"/>
        </div>
        <div class="{! 'eachField f2' + (v.width=='SMALL'?' narrowRegion':'')}">
            <lightning:input name="field2" label="Last Name"/>
        </div>
    </div>
</aura:component>
.THIS .eachField.narrowRegion{
    width:100%;
}
.THIS .eachField{
    width:50%;
    display:inline-block;
}

If you use this component it will adjust the width dynamically based on the CSS which you defined.

The component renders with the fields side by side, filling 50% of the region’s available width when not in a small region. When the component is in a small region, the fields render as a list, using 100% of the region’s width.