PDA

View Full Version : Velocity Macro - Select List



2devnull
Aug 19th, 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="$&#123;status.expression&#125;" $&#123;attributes&#125;>
#foreach&#40;$option in $options&#41;
<option
#if&#40;$status.value && $status.value == $option&#41;
selected="true"
#end>
$&#123;option&#125;</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
Aug 19th, 2004, 11:06 AM
I think it should be


#**
* springFormSingleSelect
*
* Show a selectbox &#40;dropdown&#41; 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 &#40;sequence&#41; of all the available options
* @param attributes any additional attributes for the element &#40;such as class
* or CSS styles or size
*#
#macro&#40; springFormSingleSelect $path $options $attributes &#41;
#springBind&#40;$path&#41;
<select name="$&#123;status.expression&#125;" $&#123;attributes&#125;>
#foreach&#40;$option in $options&#41;
<option
#if&#40;$status.value && $status.value == $option&#41;
value="$status.value" selected="true"
#end>
$&#123;option&#125;</option>
#end
</select>
#end

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

2devnull
Aug 19th, 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
Aug 19th, 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
Aug 19th, 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 &#40;select $name $selected $labels $values $attr&#41;
## The velocityCounter starts at 1 by default, so we use our own zero-based counter.
#set&#40;$s="NULL" &#41;
#set&#40;$s=$selected &#41;
#set&#40;$i=0 &#41;
<select name="$name" $attr>
#foreach &#40;$v in $values&#41;
<option value="$v"#if&#40;$v==$s&#41; selected#end>$labels.get&#40;$i&#41;</option>
#set&#40;$i=1+$i&#41;
#end
</select>
#end



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

davison
Aug 21st, 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
Aug 21st, 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 &#40;selectListOfMaps $name $selected $list $valueKey $optionKey $attr $defaultOption&#41;
#set&#40;$s=$selected&#41;
<select name='$name' $attr>
$defaultOption
#foreach &#40;$item in $list&#41;
#set&#40;$v = $item.get&#40;$valueKey&#41;&#41;
<option value='$v'#if&#40;$v==$s&#41;selected#end>$item.get&#40;$optionKey&#41;</option>
#end
</select>
#end

irbouho
Aug 21st, 2004, 09:16 AM
2devnull,

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