One of the features of using maps in Salesforce is their ability to be used on a Visualforce page by looping of their keys and using the key to fetch whatever is stored at that position in a map. For example, assume we have a map called mapMenu and each key (defined as a string) is pointing to a string. We could loop over the contents printing all menu items by doing the following:
<apex:repeat value="{!mapMenu}" var="key ">
<apex:repeat value="{!mapMenu[key]" var="item">
{!item}
</apex:repeat>
</apex:repeat>
Now, not taking into account that the keys are returned in arbitrary order we have used this method in various ways to display data. However, one of the issues I would like to address is the manipulation of the key on the Visualforce page. Let us assume we would like to use the key not only the fetch the item, but also use it to create a link with a query string that will display some kind of sub category page:
<apex:repeat value="{!mapMenu}" var="key ">
<apex:repeat value="{!mapMenu[key]" var="item">
<a href="{!$Page.SubCategory}?category={!key}"> {!item} </a>
</apex:repeat>
</apex:repeat>
Great! Now we have a link pointing to some kind of sub category page with the ‘item’ as its title. But what if need to manipulate the key, for example strip out spaces when passing it as a query string? Now here is the issue. Since a key in a map can be any primitive type it is considered an object, so doing:
<a href="{!$Page.SubCategory}?category={!SUBSTITUTE(key,’ ’,’’)}">
{!item}
</a>
Will result in:
Error: Incorrect parameter for function ‘SUBSTITUTE()’. Expected Text, received Object
Ok, that’s fine we say, since we know the key is actually a string we can try and cast it:
<a href="{!$Page.SubCategory}?category={!SUBSTITUTE( TEXT(key) ,’ ’,’’)}"> {!item} </a>
But this will result in:
Error: Incorrect parameter for function ‘TEXT()’. Expected Number, Date, DateTime, received Object
Blast. It seems we are unable to perform any manipulation on the keys of the map as it is considered an object by all functions. However, we can still cast it into a string by assigning it to a Visualforce variable:
<apex:repeat value="{!mapMenu}" var="key ">
<apex:repeat value="{!mapMenu[key]" var="item">
<apex:variable value="{!key} " var="strParsedKey" />
<a href="{!$Page.SubCategory}?category={!SUBSTITUTE(strParsedKey,’ ‘,’’}">
{!item}
</a>
</apex:repeat>
</apex:repeat>
Notice how we assign it to the variable strParsedKey and we add an extra space t0 the value: value=”{!key} “. By adding this extra character (any character) we are forcing Visualforce to cast it into a string and now we can use any of the manipulation functions.
Hope this helps!