One of my background tasks right now is writing an app for Force.com Labs, a collection of free applications built by Salesforce.com employees. My app will use the Endicia Label Server API to create mailing labels, part of the UI employing a pair of selectLists allowing the user to set the label type and label size. All very straightforward, but there is a dependency between the two lists – there are different sets of label sizes for different label types, so, when the user changes the label type, the content of the label size selectList needs to change accordingly.
After a bit of headscratching and documentation reading, I came up with what I think is a nice, simple, concise solution.
My Visualforce page has a form including an actionFunction and the two selectLists:
The label size list is populated by a controller function, getLabelSizes(). This returns the appropriate list of label sizes based on the value of the labelType variable:
For now, I have those lists of label sizes in the code. I’ll move them out of there at some point in the future, populating options from the database. [UPDATE – Paul Eaklor correctly points out in the comments that a round-trip to the server is overkill for such a simple dependency. Watch for more samples in the future showing how to update simple dependencies on the client-side, and a more complex scenario that does justify the round-trip.]
As you might know, actionFunctions are often used for invoking controller action methods, but you might not know that you don’t need to call an action method – you can quite legally omit the action attribute. Here I’ve done just that, but set the rerender attribute to chooseLabelSize. Now, when the user changes the selection in the label type selectList, updateLabelSize will be invoked, which will cause the label size selectList to be rerendered with the appropriate set of sizes, since labelType is bound to the label type selectList.