Visualforce pages that use dynamic bindings can reference the Apex Map and List data types in their markup.
For example, if an Apex List is defined as:
public List<String> people {
get {
return new List<String>{'Winston', 'Julia', 'Brien'};
}
set;
}
public List<Integer> iter {
get {
return new List<Integer>{0, 1, 2};
}
set;
}
You can access the list values in a Visualforce page using {!object} syntax and array notation.
<apex:repeat value="{!iter}" var="pos">
<apex:outputText value="{!people[pos]}" /><br/>
</apex:repeat>
Similarly, if you have this Apex Map:
public Map<String,String> directors {
get {
return new Map<String, String> {
'Kieslowski' => 'Poland',
'del Toro' => 'Mexico',
'Gondry' => 'France'
};
}
set;
}
You can access the map’s keys and values in a Visualforce page using {!object} syntax and array notation.
<apex:repeat value="{!directors}" var="dirKey">
<apex:outputText value="{!dirKey}" /> --
<apex:outputText value="{!directors[dirKey]}" /><br/>
</apex:repeat>
Use dynamic references to lists and maps in an <apex:inputText> tag to create forms using data that isn’t in your organization’s custom objects. Working with a single map can be much simpler than creating a series of instance variables in an Apex controller or creating a custom object just for the form data.
Here’s a Visualforce page that uses a map to hold form data for processing by a custom controller.
<!-- otherprops: apex_page set_clipboard --><apex:page controller="ListsMapsController">
<apex:outputPanel id="box" layout="block">
<apex:pageMessages/>
<apex:form >
<apex:repeat value="{!inputFields}" var="fieldKey">
<apex:outputText value="{!fieldKey}"/>:
<apex:inputText value="{!inputFields[fieldKey]}"/><br/>
</apex:repeat>
<apex:commandButton action="{!submitFieldData}"
value="Submit" id="button" rerender="box"/>
</apex:form>
</apex:outputPanel>
</apex:page>
And here’s a simple controller that works with the form.
<!-- otherprops: apex_code set_clipboard -->public class ListsMapsController {
public Map<String, String> inputFields { get; set; }
public ListsMapsController() {
inputFields = new Map<String, String> {
'firstName' => 'Jonny', 'lastName' => 'Appleseed', 'age' => '42' };
}
public PageReference submitFieldData() {
doSomethingInterestingWithInput();
return null;
}
public void doSomethingInterestingWithInput() {
inputFields.put('age', (Integer.valueOf(inputFields.get('age')) + 10).format());
}
}
A Map can contain references to sObjects or sObject fields. To update those items, reference a field name in the input field.
public with sharing class MapAccCont {
Map<Integer, Account> mapToAccount = new Map<Integer, Account>();
public MapAccCont() {
Integer i = 0;
for (Account a : [SELECT Id, Name FROM Account LIMIT 10]) {
mapToAccount.put(i, a);
i++;
}
}
public Map<Integer, Account> getMapToAccount() {
return mapToAccount;
}
}
<apex:page controller="MapAccCont">
<apex:form>
<apex:repeat value="{!mapToAccount}" var="accNum">
<apex:inputField value="{!mapToAccount[accNum].Name}" />
</apex:repeat>
</apex:form>
</apex:page>
Unresolved Dynamic References
Keep in mind the following issues that can arise at run time if a dynamic reference doesn’t resolve:
-
If there isn’t a value mapped to a particular key or the value is
null, the Visualforce page returns an error message. For example, with this controller:public class ToolController { public Map<String, String> toolMap { get; set; } public String myKey { get; set; } public ToolController() { Map<String, String> toolMap = new Map<String, String>(); toolMap.put('Stapler', 'Keeps things organized'); toolMap.put('Notebook', null); } }This page causes an error at run time.
<apex:page controller="ToolController"> <!-- Both outputText values render an error on the page --> <apex:outputText value="{!toolMap['Paperclip']}" /> <apex:outputText value="{!toolMap['Notebook']}" /> </apex:page> -
If the key is
null, the Visualforce page renders an empty string. For example, using the same controller as above, this page shows an empty space.<apex:page controller="ToolController"> <!-- This renders a blank space --> <apex:outputText value="{!toolMap[null]}" /> </apex:page>