LaceySnr.com - Salesforce Development Posts by Matt Lacey

Styling <apex:selectOptions> - Stack 'em Vertically

Posted: 2011-05-05

Since writing this, Tish pointed out in a comment that vertical stacking of these buttons is available through a parameter on the <apex:selectRadio> tag. See the documentation here, specifically you want to specify the layout attribute to be "pageDirection"

Original Post:

For some reason that I just can't fathom, when you use an <apex:selectOptions> tag inside of an <apex:selectList> or similar, the options get built out into a table(!), with each option occupying it's own table cell, all in one table row. This really isn't that handy for those cases where say, I don't know, you want the options in a vertical list maybe?

To me it seems that this is often more desirable than having them horizontally laid out side by side, but somebody within Salesforce obviously though different. You may think it can be solved by using an <apex:repeat> inside of the <apex:selectList> and using <apex:selectOption> (not the lack of a plural here) to generate each one individually,  encased in a <div>, <li> or what have you — you'll soon discover however that the Visualforce validation parser that runs when you save your page will inform you that the options must be an immediate child of the parent list. Nuts.

The way I solved this problem is by wrapping the list in a <div> and using some CSS to force the table cells to use "display: block" which then prevents them from displaying on the same line; I don't believe this is particularly elegant as that's not what tables are for (and no I'm not a CSS purist who believes that spending a day screwing about with CSS is better than just using a table to lay something out in 2 minutes—in the real world people need things done quickly and the chances of requiring a totally different style are quite minimal in Visualforce pages).

Example page markup:

<div class="questionContent">
  <apex:selectRadio value="{!q.strSelectedAnswer}">
    <apex:selectOptions value="{!q.liAnswers}"/>
    <apex:actionSupport event="onchange" action="{!SaveProgress}" status="SaveStatus" rerender="SaveStatus"/>
  </apex:selectRadio>
</div>

and, of course, the CSS:

.question table tr td
{
  display: block;
}

Random side note: I do in fact use tabs for all my indenting (set to four spaces), but for the sake of space saving in examples etc. I don't bother to make sure they're always that size in this blog. Plus it's a bit of a pain to do in blogger (or so it seems).