Reference Apex Maps and Lists

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