Binding enumerations with radio buttons or select list

201 views
Skip to first unread message

Strom

unread,
Oct 28, 2009, 2:59:16 PM10/28/09
to Lift
Has anyone figure out how to bind enumerations as radio buttons or a
drop down list?

I have an enumeration:
object ExchangeMethod extends Enumeration {
val Pickup = Value("Pickup")
val Ship = Value("Ship")
val PickupOrShip = Value("Pickup or Ship")
}

And I want to put radio buttons in an html file from this enumeration
without hardcoding the number of options (say I add another
ExchangeMethod.Value called "Online Transfer").

Basically I'm trying to get this enumeration to display as radio
buttons with text labels for each value in a form that I can customize
with CSS.

Ross Mellgren

unread,
Oct 28, 2009, 3:06:53 PM10/28/09
to lif...@googlegroups.com
SHtml.selectObj[ExchangeMethod.Value](ExchangeMethod.elements.map(el
=> (el, el.toString)), Empty, selected => println(selected))

?

-Ross

Strom

unread,
Oct 28, 2009, 5:18:41 PM10/28/09
to Lift
Hey Ross. Thanks for the tips. I found out you have to call the toList
() method before you can map the enumeration elements.

So it would be like this:
XTHML:
<item:exchangeMethod />

Snippet:
def SnippetName(xhtml:NodeSeq): NodeSeq = {
var exchangeMethod: Box[ExchangeMethod.Value] = Empty
...
bind("item", xhtml,
"exchangeMethod" -> SHtml.selectObj[ExchangeMethod.Value]
( ExchangeMethod.elements.toList.map(v => (v,v.toString)), Empty,
selected => exchangeMethod = Full(selected) )
...) //end bind
}

The missing key for me was the type declaration for selectObj. Now
does anyone know how to do the same type of thing with radio buttons?

Ross Mellgren

unread,
Oct 28, 2009, 5:47:34 PM10/28/09
to lif...@googlegroups.com
(untested, uncompiled, and generally just a suggestion ;-) )

XHTML:

<item:exchangeMethod>
<method:input /> <method:label />
</item>

var exchangeMethod: Box[ExchangeMethod.Value] = Empty

bind("item", xhtml",
"exchangeMethod" -> { (ns: NodeSeq) =>
(SHtml.radio(ExchangeMethod.elements.map(_.toString).toList,
exchangeMethod, s => exchangeMethod =
ExchangeMethod.valueOf(s))
.flatMap(choice => bind("method", ns, "input" ->
choice.xhtml, "label" -> choice.key)))
})


Note that I didn't do the right thing with the label for each input
here -- good practices dictates that the label should be wrapped with
<label for="field">...</label> for accessibility and clickability.

-Ross

Strom

unread,
Oct 28, 2009, 8:35:11 PM10/28/09
to Lift
Thanks again Ross!

I also found out that I could use the ChoiceHolder.toForm method for a
little less customization (saves a ton of code though).

The following rundown is for newbies like me who are having trouble
with radio buttons and enumerations. Please see the enumeration
definition in my first post, and also make sure to name your
Enumeration.Value what you want to show to end users, as the following
code uses the Value's toString method to populate the XHTML.

XHTML:
<item:exchangeMethod />

Snippet:
def SnippetName(xhtml: NodeSeq) : NodeSeq = {
...
val radios = SHtml.radio( ExchangeMethod.elements.toList.map
( _.toString ), Empty,
selected => exchangeMethod = Box
( ExchangeMethod.valueOf( selected ) )
)
...
bind( "item", xhtml,
"exchangeMethod" -> radios.toForm
...//more binding for other tags
)
...
}

Explanation:
1. The XHTML should be pretty self explanatory, as it's the same as
all other bind tags.

2a. In the snippet, I made a "val radios" that uses the method:
SHtml.radio( radioChoices: Seq[String], defaultVal: Box[String],
submitFunction: (String) => Any, attributes: (String, String)* )

2b. ExchangeMethod.elements.toList returns List[ExchangeMethod.Value],
so I had to use the map method on lists to convert it to List[String],
which matches the SHtml.radio method signature.

2c. There is no default value for the radio choices, so use Empty,
which is the EmptyBox singleton (see "Notes on Box" below).

2d. The function executed on submit is using Box's apply(in: Option
[T]) "constructor" to yield a new Box from an Option, since
ExchangeMethod.valueOf(selected: String) returns an Option.

3. Calling radio.toForm XHTML-izes the radio buttons for you. "val
radio" is actually a ChoiceHolder (more info:
http://scala-tools.org/scaladocs/liftweb/1.0/net/liftweb/http/SHtml/ChoiceHolder.html).

The actual structure for my "val radio" is
ChoiceHolder( List(
ChoiceItem(Pickup, ...XHTML...),
ChoiceItem(Ship, ...XHTML...),
ChoiceItem(Pickup or Ship, ...XHTML...) ) )

You could probably manipulate the XHTML if you wanted to, but I
haven't gotten that far yet.

**Notes on Box**
Boxes are like Scala's Option class with extra goodies, so basically
it's just a container for things so you don't get Null Pointer
Exceptions all over the place. Use Full(object) to make a Box that
contains something, or Empty if you want an empty Box. David Pollack
says the Box class and object are moving to net.liftweb.common from
net.liftweb.util, so just be aware if you're using Lift 1.0 or Lift
1.1. However, for my purposes I was using this explanation of Box:
http://scala-tools.org/scaladocs/liftweb/1.0/net/liftweb/util/Box.html

This post might be overkill, but I figured someone who is completely
lost, like I was, will find some useful information.

Strom

Naftoli Gugenheim

unread,
Oct 28, 2009, 8:38:06 PM10/28/09
to lif...@googlegroups.com
Why not put it on the wiki? :)

-------------------------------------

Ross Mellgren

unread,
Oct 28, 2009, 8:39:04 PM10/28/09
to lif...@googlegroups.com
+1 -- nice detailed writeup

-Ross

Strom

unread,
Oct 28, 2009, 8:51:26 PM10/28/09
to Lift
I would post on the wiki, but I've never added content to a wiki, and
I can't create an account for the LiftWiki (only admins can make new
accounts?). If someone wants to post this information on there
somewhere, go for it!

Strom

On Oct 28, 5:39 pm, Ross Mellgren <dri...@gmail.com> wrote:
> +1  --  nice detailed writeup
>
> -Ross
>
> On Oct 28, 2009, at 8:38 PM, Naftoli Gugenheim wrote:
>
>
>
> > Why not put it on the wiki? :)
>
> > -------------------------------------
> >http://scala-tools.org/scaladocs/liftweb/1.0/net/liftweb/http/SHtml/C...

Naftoli Gugenheim

unread,
Oct 28, 2009, 8:53:39 PM10/28/09
to lif...@googlegroups.com
The wiki on GitHub. You probably only need a GitHub account.

-------------------------------------

Strom

unread,
Oct 29, 2009, 2:39:50 AM10/29/09
to Lift
Ok, I've made an in depth article on the wiki for this:
http://wiki.github.com/dpp/liftweb/how-to-make-radio-lists-and-drop-downs-from-enumerations

Let me know if I'm missing anything.
Strom

On Oct 28, 5:53 pm, Naftoli Gugenheim <naftoli...@gmail.com> wrote:
> The wiki on GitHub. You probably only need a GitHub account.
>
> -------------------------------------
>
Reply all
Reply to author
Forward
0 new messages