PDA

View Full Version : Velocity Macro - Select List


2devnull
08-19-2004, 10:52 AM
#**
* springFormSingleSelect
*
* Show a selectbox (dropdown) input element allowing a single value to be chosen
* from a list of options.
*
* @param path the name of the field to bind to
* @param options a list (sequence) of all the available options
* @param attributes any additional attributes for the element (such as class
* or CSS styles or size
*#
#macro( springFormSingleSelect $path $options $attributes )
#springBind($path)
<select name="${status.expression}" ${attributes}>
#foreach($option in $options)
<option
#if($status.value && $status.value == $option)
selected="true"
#end>
${option}</option>
#end
</select>
#end

How does the value attribute in the <OPTION> tag get populated?

e.g.
<select name="states">
....
<option value="FL">Florida</OPTION>
....
</select>

:?:

irbouho
08-19-2004, 11:06 AM
I think it should be

#**
* springFormSingleSelect
*
* Show a selectbox (dropdown) input element allowing a single value to be chosen
* from a list of options.
*
* @param path the name of the field to bind to
* @param options a list (sequence) of all the available options
* @param attributes any additional attributes for the element (such as class
* or CSS styles or size
*#
#macro( springFormSingleSelect $path $options $attributes )
#springBind($path)
<select name="${status.expression}" ${attributes}>
#foreach($option in $options)
<option
#if($status.value && $status.value == $option)
value="$status.value" selected="true"
#end>
${option}</option>
#end
</select>
#end

2devnull
08-19-2004, 11:41 AM
That's what I think also, but this code is from 1.1 RC2.

2devnull
08-19-2004, 11:50 AM
The other thing is, should there not be two list or a map as parameter. i.e. One for the value attribute e.g. VA, FL, CA, NY and one for the actual display name between <OPTION></OPTION>, e.g. New York, Florida, etc.

irbouho
08-19-2004, 03:03 PM
current implementation will build

select name="states">
....
<option>Florida</option>
....
</select>

I do agree it can be nicer. I will post a more complete (I hope) macro on JIRA.

2devnull
08-19-2004, 04:32 PM
These are the two I am using. One uses a map. It could be modified accordingly to work with SpringBind.

#macro (select $name $selected $labels $values $attr)
## The velocityCounter starts at 1 by default, so we use our own zero-based counter.
#set($s="NULL" )
#set($s=$selected )
#set($i=0 )
<select name="$name" $attr>
#foreach ($v in $values)
<option value="$v"#if($v==$s) selected#end>$labels.get($i)</option>
#set($i=1+$i)
#end
</select>
#end



#macro (selectList $name $selected $map $attr)
#set($s=$selected )
<select name='$name' $attr>
#foreach( $key in $map.keySet() )
#set($v = $key)
<option value='$v'#if($v==$s)selected#end>$map.get($key)</option>
#end
</select>
#end

davison
08-21-2004, 06:41 AM
I'm fixing these now.

Regarding the map v list for option values and labels, a map is simplest and most natural to handle I think..
{"FL":"Florida", "WA":"Washington" ...}, BUT there are likely to be times when you need an ordering on the display that has no natural Comparator. So even a SortedMap would be no good.

For this reason, I think it has to be implemented with two lists rather than a Map. The only other option is two separate macros as you showed in your example, but Velocity can't overload macro signatures so it's still a bit clunky. What do you think?

BTW another error crept in between committing the code and releasing RC2. If a value for $springHtmlEscape is not defined in a template, all macro calls will result in Velocity errors. This has been reverted to the working version too where $springHtmlEscape is optional.

Regards,

2devnull
08-21-2004, 07:46 AM
For what it's worth, this is the macro I am now using to allow me to use a map. Also, I think Velocity has a fix, since declaring maps in the latest release version does not work. Anyway, this works for me with a list of maps from a DB etc.

#macro (selectListOfMaps $name $selected $list $valueKey $optionKey $attr $defaultOption)
#set($s=$selected)
<select name='$name' $attr>
$defaultOption
#foreach ($item in $list)
#set($v = $item.get($valueKey))
<option value='$v'#if($v==$s)selected#end>$item.get($optionKey)</option>
#end
</select>
#end

irbouho
08-21-2004, 09:16 AM
2devnull,

your macro is very simillar to Struts html:collections.
+1 to integrate it into Spring.