Tweet |
I've created a small example to demonstrate the usefulness of this new feature. This is a page that displays either all accounts in the system:
or just those that begin with a particular letter,
depending on the option that the user selects from a list. Prior to Spring 11, I'd have to generate the list of accounts based on the user's selection server side. As I said earlier, not a lot of work but I'd still prefer not to have to do it.
With the new feature, I can simply set up all my data in a map when constructing the page controller and then dynamically render the appropriate value from the map, based on the key, which is the user's selection.
The page markup is shown below:
<apex:page controller="DynamicBindingsMapExample"> <apex:form > <apex:actionFunction name="redraw_accounts" rerender="accs" status="status"/> <apex:pageBlock title="Criteria"> <apex:outputLabel value="Starting Letter"/> <apex:selectList value="{!selectedKey}" size="1" onchange="redraw_accounts()"> <apex:selectOptions value="{!keys}" /> </apex:selectList> </apex:pageBlock> <apex:pageBlock title="Accounts"> <apex:actionstatus id="status"> <apex:facet name="start"/> <apex:facet name="stop"> <apex:outputPanel id="accs"> <apex:pageBlockTable value="{!accountsMap[selectedKey]}" var="acc"> <apex:column value="{!acc.name}"/> <apex:column value="{!acc.BillingStreet}"/> <apex:column value="{!acc.BillingCity}"/> <apex:column value="{!acc.BillingPostalCode}"/> </apex:pageBlockTable> </apex:outputPanel> </apex:facet> </apex:actionstatus> </apex:pageBlock> </apex:form> </apex:page>
The accounts are made available to the page via a map property on the controller that associates a letter (or the String 'All') with a list of Accounts starting with that letter (or every account in the case of 'All').
public Map<String, List<Account>> accountsMap {get; set;}
The user's selection is stored in the selectedKey controller property and this is used to extract the appropriate accounts from the map in the pageblocktable component:
<apex:pageBlockTable value="{!accountsMap[selectedKey]}" var="acc">
When the user's selection changes, the redraw actionfunction is executed to redraw the pageBlockTable containing the accounts. Note that there is no action attribute specified, as I haven't had to write any server side code to change the accounts displayed - everything is handled client side.
<apex:actionFunction name="redraw_accounts" rerender="accs" status="status"/>
Update 12/02/2012 - as requested by Raj in the comments, here is the controller class:
public class DynamicBindingsMapExample { public Map> accountsMap {get; set;} public List keys {get; set;} public String selectedKey {get; set;} public Map accsByName {get; set;} public Set getMapKeys() { return accountsMap.keySet(); } public DynamicBindingsMapExample() { accsByName=new Map (); List sortedKeys=new List (); accountsMap=new Map >(); accountsMap.put('All', new List ()); List accs=[select id, Name, BillingStreet, BillingCity, BillingPostalCode from Account order by Name asc]; for (Account acc : accs) { accountsMap.get('All').add(acc); String start=acc.Name.substring(0,1); List accsFromMap=accountsMap.get(start); if (null==accsFromMap) { accsFromMap=new List (); accountsMap.put(start, accsFromMap); } accsFromMap.add(acc); accsByName.put(acc.name, acc); } keys=new List (); for (String key : accountsMap.keySet()) { if (key != 'All') { sortedKeys.add(key); } } sortedKeys.sort(); sortedKeys.add(0, 'All'); for (String key : sortedKeys) { keys.add(new SelectOption(key, key)); } selectedKey='All'; } }
Nice post. I found that I ran into an issue trying to use tags within the context of a list of sobjects referenced as a map value. It looks like your use of "value" in the columns of your table above didn't have the same effect, which is good news.
ReplyDeleteI look forward to being able to use this approach with input fields. Until then, I'm still making custom wrappers.
Great post! I had no idea we could use the fieldset notation in this fashion, I'd thought it could only be used to reference a field in an sobject.
ReplyDeleteHey bob
ReplyDeleteCould you please provide controller for this since i started to read your blog recently.I will understand better if you provide controller code.
Hi Raj,
ReplyDeleteI've updated the post to include the controller code.
Error: DynamicBindingsMapExample Compile Error: expecting a right angle bracket, found '=' at line 3 column 36
ReplyDeleteBy using SOQL query, one of the syntax
ReplyDeleteMap objname=new Map([query statement]);
here my requirement is how can we display the id and query in VF page, please help me
Bod Buzzard ,I received same error as that of Anand
ReplyDeleteThanks Bob.@Rastogi Anand : The above controller worked with minimum changes to control like using public Map> accountsMap {get; set;} accsByName.put(acc.name, accs);
ReplyDeleteHi Bob,
ReplyDeleteHow can i use these bindings to get value like
It is throwing me error on vf page .
Incorrect parameter type for subscript. Expected Number, received Text
I am getting below error -
ReplyDeleteUnknown property 'DynamicBindingsMapExample.key': Markup