The <flow:interview> component is designed to make it easy to develop complex Visualforce interactions. You can access additional features in your flow by creating a custom controller. With custom controllers, you can build a page with multiple components that can interact with each other. Any flow within your organization can be individually referenced by its own Apex type, and the variables in the flow can be accessed as member variables.
You can set only variables that allow input access, and you can get only variables that allow output access. For a variable that doesn’t allow input or output access, attempts to get the variable are ignored, and compilation may fail for the Visualforce page, its <apex:page> component, or the Apex class.
Note
For our next example, the flow with API name “ModemTroubleShooting” is referenced as Flow.Interview.ModemTroubleShooting. The markup illustrates how to display a value of a flow variable in a different part of the page:
If the flow is from a managed package, the name attribute must be in this format: namespace.flowuniquename.
Note
The controller for the above markup looks like this:
1public class ModemTroubleShootingCustomSimple{23 // You don't need to explicitly instantiate the Flow object;4 // the class constructor is invoked automatically56 public Flow.Interview.ModemTroubleShooting myflow{get; set; }7 public String casePriority;8 public String getCasePriority(){9 // Access flow variables as simple member variables with get/set methods10 if(myflow == null)return 'High';11 else return myflow.vaCasePriority;12}13}
If you’re using a custom controller, you can also set the initial values of the variables at the beginning of the flow in the constructor of the flow. Passing in variables using the constructor is optional and isn’t necessary if you’re using <apex:param> tags to set the value.
Here’s an example of a custom controller that sets the values of flow variables in a constructor.
1public class ModemTroubleShootingCustomSetVariables{2 public Flow.Interview.ModemTroubleShooting myflow{get; set; }34 public ModemTroubleShootingCustomSetVariables(){5 Map<String, Object>myMap = new Map<String, Object>();6 myMap.put('vaCaseNumber','123456');7 myflow = new Flow.Interview.ModemTroubleShooting(myMap);8}910 public String caseNumber{set; }11 public String getCaseNumber(){12 return myflow.vaCaseNumber;13}14}
You can use the getVariableValue method in the Flow.Interview class to access the value of a flow variable. The variable may be in the flow embedded in the Visualforce page or in a separate flow that is called by a Subflow element. The returned variable value comes from whichever flow the interview is currently running. If the specified variable can’t be found in that flow, the method returns null. This method checks for the existence of the variable at run time only, not at compile time.
This sample uses the getVariableValue method to obtain breadcrumb (navigation) information from a flow. If that flow contains subflow elements, and each of the referenced flows also contains a vaBreadCrumb variable, you can provide users with breadcrumbs regardless of which flow the interview is running.
1public with sharing class SampleController {23 //Instance of the flow4 public Flow.Interview.Flow_Template_Gallery myFlow {get; set;}56 public String getBreadCrumb() {7 String aBreadCrumb;8 if (myFlow==null) { return 'Home';}9 else aBreadCrumb = (String) myFlow.getVariableValue('vaBreadCrumb');1011 return(aBreadCrumb==null ? 'Home': aBreadCrumb);1213 }14}
The following table shows the differences in the naming of supported data types between the flow and Apex.
Flow
Apex
Text
String
Number
Decimal
Currency
Decimal
Date
Date, DateTime
Boolean
Boolean
Record, with a specified object
The API name of the specified object, such as Account or Case
As it’s a good practice to write tests against your Apex code, the following is a trivial example of writing a test class for ModemTroubleShootingCustomSetVariables:
1@isTest2private class ModemTroubleShootingCustomSetVariablesTest{34 static testmethod void ModemTroubleShootingCustomSetVariablestests(){5 PageReference pageRef = Page.ModemTroubleShootingSetVariables;6 Test.setCurrentPage(pageRef);7 ModemTroubleShootingCustomSetVariables mytestController = 8 new ModemTroubleShootingCustomSetVariables();9 System.assertEquals(mytestController.getcaseNumber(), '01212212');10}11}
Setting the reRender Attribute
By using the reRender attribute, the <flow:interview /> component re-renders the flow without refreshing the whole page:
If you don’t set the reRender attribute, when you click a button to navigate to a different screen in a flow, the entire Visualforce page refreshes, not just the <flow:interview> component.