Andy in the Cloud

From BBC Basic to Force.com and beyond…

Visual Flow with List View and Related List Buttons

35 Comments

Last years blog Clicks not Code with Visual Flow Custom Buttons has continued to be quite well received, so i thought i would explore what more could be done and address a few questions that have come up since. This blog does make some assumptions that you are already familiar with the approach from my previous blog.

This time i want to focus on using Visual Flows with list Custom Buttons, such buttons can be placed on List View layouts and Related List sections on Detail layouts. Salesforce also provides a means for the user to select specific records to process. These buttons apply to both Salesforce Classic and Salesforce Lighting Experience.

AccountFlowListView

As before we are keeping in the spirit of Clicks not Code, well with a little bit of reusable Visualforce code. But don’t worry you can easily copy and paste to adapt with a few changes. Critically with this approach you don’t need to resort to JavaScript based Custom Buttons, which will no longer be supported in Lighting Experience.

Handling Record Lists from Custom Buttons

First things first, ensure you have created a SObjectCollection variable in your Flow and ensured its designated as Input. For this blog we are simply going to display a step in the UI for each selected record. Using the Loop and Screen elements. One thing to keep track of is the fields your referencing within the Flow, in this case i’m using Account Name and Annual Amount.

SelectedAccountsFlow

List View Custom Button Example

Lets get started with a Custom Button on the Account List View. When adding a List Custom Button you have two choices, do you want the user to be able to select records or not? If not, then your button will pass all the records in the List View (currently limited to 2000).

So if when creating your Custom Button you plan to select the Display Checkboxes (for Multi-Record Selection) option. Then create the following Visualforce page, changing the object name and list of fields accordingly. This will ensure selected records are passed to your Flow.

<apex:page standardController="Account" tabStyle="Account" recordSetVar="AllAccounts" >
    <!-- Add below each field you reference in your Flow -->    
    <apex:repeat value="{!AllAccounts}" var="row" rendered="false">
        {!row.Name}
        {!row.AnnualRevenue}
    </apex:repeat>
    <!-- Runs your Flow -->    
    <flow:interview name="SelectedAccounts" 
          finishLocation="{!URLFOR($Action.Account.Tab, $ObjectType.Account)}">
        <apex:param name="SelectedRows" value="{!Selected}"/>
    </flow:interview>
</apex:page>

IMPLEMENTATION NOTE: If you want to avoid bothering with changes between lines 3-6, simply re-query the records in the Flow using the Fast Lookup element. Thought it’s less efficient this way since your not leveraging the query made by Visualforce.

If you don’t want the ability for the users to select records and want all records, the main difference to the above is a change to the line 10, passing in the AllAccounts binding.

    <!-- Runs your Flow -->    
    <flow:interview name="SelectedAccounts" 
          finishLocation="{!URLFOR($Action.Account.Tab, $ObjectType.Account)}">
        <apex:param name="SelectedRows" value="{!AllAccounts}"/>
    </flow:interview>

Don’t forget to add your button to the List View layout, select some records and give it a try!

SelectedAccountRow

Related List Custom Button Example

In this case the Visualforce page is much the same, accept that of course your placing the associated button on the Layout of the parent object by editing the applicable related list section. The following example shows a button on the Opportunities related list on the Account object.

<apex:page standardController="Opportunity" tabStyle="Opportunity" recordSetVar="AllOpportunities">
    <!-- Add below each field you reference in your Flow -->
    <apex:repeat value="{!AllOpportunities}" var="row" rendered="false">
        {!row.Name}
        {!row.Amount}
    </apex:repeat>
    <!-- Runs your Flow -->
    <flow:interview name="SelectedOpportunities" 
          finishLocation="{!$CurrentPage.parameters.retURL}">
        <apex:param name="SelectedRows" value="{!Selected}"/>
    </flow:interview>    
</apex:page>

RelatedListFlowButton

IMPLEMENTATION NOTE: Note that the above Visualforce page code uses a URL parameter retURL, which is not available in Lighting Experience. It still works, but leaves the user on the finish page.

Summary

For more information on passing values to Flows using Visualforce check out the docs here. With the exception of the retURL hack above, i’m pleased to see support in Classic and Lighting Experience. Though the later, has yet to obtain support for providing the record selection support, so only the all records use case is available.

At present Visual Flow styling does not quite look at home either in Lightning Experience, which made me wonder about trying SLDS styling with Flow’s CSS customisation abilities (i will let everyone known how successful this is!)…

AccountFlowListViewLEX

FlowInLEX

Finally both these approaches will also work equally well with Automation Flows (aka Headless Flows), just in case, as with the example in my earlier blog you just want to do some kind of calculations without prompting the user.

35 thoughts on “Visual Flow with List View and Related List Buttons

  1. I tried this for Opportunities but it will only show one record without looping and I the related list has more than 5 entries the checkboxes do not appear after selected Go to list (xx).

    • Yeah i hit this at first. Its not that obvious for a single element loop. But you have to connect your Screen element step back to your loop element. Note that mine has arrows point back and forth between the loop element.

  2. Thanks Andy, that was it.

    Is it possible to do a similar flow with Opportunity Line Items as the related list?

  3. Hello Andy, I am trying to use the Process Builder to Update the Quote Line Items retrieving the values from another object.
    For example:
    in Quote Line Items I have a custom field Route (example : Japan-Italy ) and Rate
    also I have a custom Object “Route” which stores the rate for a specific route.

    How can I update the Rate field QuoteLineItem records by record lookup on Object Route ?
    I created an Auto launch flow for Record Lookup and Update , but I can I pass the variable to the autolaunch flow for query?

    Thanks in advance
    Dimi

    • Yes you can pass the record itself or fields from the record. Create variables (of sobject type or text for example) in the flow and mark them as input, then they will appear in process builder to map to.

  4. Can this be done without creating a visual force page? Like if we just wanted to use the “list button” with option for “Display Checkboxes (for Multi-Record Selection)”. If so what would we pass to URL or ForURL fuction?

    • I don’t see how this can be done with just url only as it there is no way to encode multipe times. Why don’t you want to use vf page out of interest?

      • Visual force pages don’t have drag & drop layouts. That and why have an option to use related list checkbox if the checked IDs can not be passed as a value to URL or flow?
        It looks like there’s some javascript that will allow a button to determine is there has been greater then 0 boxes checked but its not clear how to pass that result to a flow & then the whole javascript end of support issue. I guess we could value “selectedOpportunityIds” to URL if using this javascript https://developer.salesforce.com/forums/?id=906F00000008ojdIAA

      • The option is available for Visualforce pages and JavaScript buttons. JavaScript buttons will not be supported in the new lightning experience ui so be careful with those. I am not sure what you mean by not having drag and drop layouts, your not really using Visualforce here for any ui, just as a means to launch a flow.

      • Also there is no string manipulation operations in flow to unpack your string.

  5. Pingback: Visual Flow with List View and Related List Buttons | SutoCom Solutions

  6. A note to those who might have been wondering like I did, the “param name” in the “flow:interview” is what your input variable name should be.

    Scott

  7. Hi Andrew,
    That’s a great post but I have one issue though.
    If I use relationships,some how they dont seem to work in Flows.
    Sales engineer is a custom lookup field to the user object on my opportunity and I added this {!row.Sales_Engineer__r.name} and turned the rendered on repeat to true which works perfectly fine but the flow fails saying “The flow failed to access the value for name.Sales_Engineer__r.Name because it hasn’t been set or assigned”.
    Everything else is similar to what you did.
    Any idea the reason and how to resolve this.

    • Hmmm that’s odd, it must be Salesforce is cloning the standard controller records, and only doing a shallow clone? You will have to query in the flow itself it seems. I am away from my computer at present, but if you want to send me a Gist snippet of your VF page and the bit of your Flow that is failing I can look later. Also try to enable the Workflow debug levels and see if they yield anything of interest.

  8. Sorry for all the duplicate comments, Apex tags were not getting rendered in the comments and I could not delete the comments later.

    Please see the code here http://pastebin.com/QvVTUJNr

    • I’ve reproduced this scenario and it partially works. I created a Test Custom Object and then added a Test__c lookup field to Account. I used {!row.Test__r.Name} in my VF page and in the Display Text element. What i found is it displayed correctly for records that had the Test__c field populated. But for records where this lookup field was not populated it bombs with platform error (maybe this can be worked around in the Flow formula to avoid this). I notice that the UI in the Flow designer does not support selecting relationship. My recommendation is you raise a support case with Salesforce to look into this. Or if it can work for you, create a Formula field on the Opportunity object that references Sales_Engineer__r.name. Finally it should not make a difference but try ‘Name’ instead of ‘name’.

  9. Hi Andrew,

    Thank you for this post. Concerning “Though the later, has yet to obtain support for providing the record selection support, so only the all records use case is available.” As I understood the multiselect (when checked ‘Display Checkboxes (for Multi-Record Selection)’ on a list button does not work for lightning so we have to pass AllAccounts into recordSetVar and create custom vf list view with check boxes for multiselect. Is this the only option for lightning if we need multiselect?

  10. Andrew, Thanks for your great posts! A question for you. When passing data in from the visualforce page (lines 3-6) if the record does not contain a value in a particular field and we try to access the value in that field we receive an error “The flow failed to access the value for because it hasn’t been set or assigned.” However sometimes a blank value is an appropriate thing for a field to contain. I’ve tried error capturing with a decision element but even the decision element fails with the same error. So generally i have to fall back to the other option you describe in your Implementation Note: “If you want to avoid bothering with changes between lines 3-6, simply re-query the records in the Flow using the Fast Lookup element. Though it’s less efficient this way since you’re not leveraging the query made by Visualforce.”

    So two questions:
    1. Is there a better way to pass data in from a Visualforce page when the field may not contain a value so that flow can handle it?

    2. If we need to requery the records in the flow, do you have a faster way to do the “simply re-query the records” step than what I am currently doing?

    Current process:
    1. Add a text field to the object for the records being queried.
    2. Use a Fast Update – update all selected records and put some unique value (typically using the current date/time) into the new text field just created.
    3. Use a Fast Lookup to then query those same records using the temporary ID field as the criteria to lookup the same set of records.

    For some reason the flow treats records queried in a fast lookup differently than those passed in from a visualforce page and I can evaluate blank fields from a fast lookup. Any thoughts or suggestions would be appreciated. Thanks!

  11. Hi I am getting the below error when i am saving the above code
    Error: Flow “SelectedAccounts” is not found or doesn’t have an active version. Can you please provide the solution.

  12. Hi again. Just wanted to leave this additional tidbit of information about setting the finish location. I’ve only just figured this out and it seems to work for me although I haven’t tested it thoroughly. With the example in the post setting the finish location to this

    finishLocation=”{!URLFOR($Action.Account.Tab, $ObjectType.Account)}”>

    takes the user back to the tab but NOT into the list view which is a bit confusing of an experience. However if I do this instead it takes me to the list view:

    finishLocation=”/{!$ObjectType.Account}”>

    Perhaps someone else will have some additional insight or thoughts on this?

  13. Hi Andrew, I have two quick questions:

    Does below code work in the Service Cloud Console?
    finishLocation=”{!URLFOR($Action.Account.Tab, $ObjectType.Account)}”>

    Does below code work in the Service Cloud Console?
    finishLocation=”{!$CurrentPage.parameters.retURL}”>

  14. Pingback: Flow in Winter’17 Lightning Experience | Andy in the Cloud

  15. Hi Andy,

    Thanks for this post – we’ve built a whole new operational process around it, and everyone loves it! The one tweak I’d like to make is delivering an error screen when the no records have been selected from the list view (“Please return to the list view and make a selection”). Evaluating the “SelectedRows” collection variable according to the criteria “is null {!$GlobalConstant.True}” doesn’t work (http://salesforce.stackexchange.com/questions/51797/visual-workflow-how-to-evaluate-whether-an-sobject-collection-variable-isnull), presumably because when the collection is “empty” it’s not “null.” You can set the variable to null when using a Fast Lookup element to pull the collection – could you potentially edit the Visualforce page to do the same, or do you have another suggestion on how to incorporate this check within the flow?

    • Yeah best bet is to use conditional display of a apex:pageMessage element to show the message vs showing the interview flow element using the rendered attributes of each with an appropriate expression

      • Since I’m not a pro with Apex I continued experimenting with the flow yesterday and ended up adding a loop before the action to count the records selected (using this post as a starting point: https://developer.salesforce.com/forums/?id=906F0000000BNOnIAO) and conditionally display the error if total # = 0, or a confirmation screen (Do you want to [perform actions] on the [total #] records selected?) if a selection has been made. Might not be the cleanest route, but it works great and having the count on the confirmation screen is a plus!

      • Excellent! Thanks for sharing

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 )

Google+ photo

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

Connecting to %s