Spring Form taglib的选项组功能

时间:2012-07-19 06:47:27

标签: java spring select spring-mvc taglib

在HTML中我们可以写

<select name="..." value"...">
 <optgroup label="Category 1">
  <option ... />
  <option ... />
 </optgroup>
 <optgroup label="Category 2">
  <option ... />
  <option ... />
 </optgroup>
</select>

在Spring <form>标签中,我们如何编写类似于组项的内容。

3 个答案:

答案 0 :(得分:5)

不幸的是,目前spring mvc并没有通过其标签提供这样的功能。这可以通过给定here的良好逻辑来实现。

答案 1 :(得分:2)

https://jira.springsource.org/browse/SPR-3742仍有待解决。 建议而不是使用表单:选项使用jstl和el来构建列表。

答案 2 :(得分:0)

控制器

请注意,集合是Map<String, List<KeyValueBean>>

它存储例如Group 1 -> { ("Option 1.1 Label","OPTION_1_1_VAL"), ("Option 1.2 Label","OPTION_1_2_VAL"), ..}

@ModelAttribute("careerOptions")
Map<String, List<KeyValueBean>> getCareerOptions() {        
    HashMap<String, List<KeyValueBean>> result = new HashMap<String, List<KeyValueBean>>();
    result.put("Grp1", new ArrayList<KeyValueBean>());
    result.get("Grp1").add(new KeyValueBean("Option 1.1", "OPT_1_1"));
    result.get("Grp1").add(new KeyValueBean("Option 1.2", "OPT_1_2"));
    result.put("Grp2", new ArrayList<KeyValueBean>());
    result.get("Grp2").add(new KeyValueBean("Option 2.1", "OPT_2_1"));

    return result;
}       

JSP

<form:select path="careerSelected" id="careerElement">
    <form:option label="" value="" />
    <c:forEach var="optionGroup" items="${careerOptions}">
       <optgroup label="${optionGroup.key}">
       <c:forEach var="option" items="${optionGroup.value}">
          <form:option label="${option.key}" value="${option.value}" />                             
       </c:forEach>                                                          
       </optgroup>
    </c:forEach>
</form:select>

KeyValueBean (我创建了自己的,但是Java内置的是AbstractMap.SimpleEntry<K,V> -您可以使用它,只是代码有点难看)

public class KeyValueBean implements Serializable {

    private static final long serialVersionUID = 1L;

    private String key;
    private String value;

    public KeyValueBean(String key, String value) {
        this.key = key;
        this.value = value;
    }

    public String getKey() {
        return key;
    }
    public void setKey(String key) {
        this.key = key;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }

}

另一种情况:有时选择项是 MIXED (与OptGroup平混)

A
B
C (subgroup)
  - C.1
  - C.2

在这种情况下,集合可以是Map<String,Object>,其中每个条目都将被键入到 Object (1)字符串或(2)一个HashMap,我们可以从JSP中找到它。

用于混合数据结构的控制器

@ModelAttribute("careerOptionsMixed")
Map<String, Object> getCareerOptionsMixed() {

    LinkedHashMap<String, Object> result = new LinkedHashMap<String, Object>();

    result.put("Flat Option 1", "OPT_1_FLAT");
    result.put("Group Option 2", myHashMap); // Fill out your HashMap for Group (Key->Value) and add it here
    result.put("Flat Option 3", "OPT_3_FLAT");

    return result;
}           

用于混合数据结构的JSP(确定是否需要收集的技巧,通过迭代和设置变量来完成) 在JSP中,我们需要确定是获取Collection还是String。唯一的方法就是通过迭代并设置一个变量。

<form:select path="career" id="careerField">
   <form:option label="" value="" />
   <c:forEach var="optionOrOptionGroup" items="${careerOptionsMixed}">
      <%--  Must use iteration to find out if this is a Collection or not: https://stackoverflow.com/a/1490171/1005607 --%>
      <c:set var="collection" value="false" />
      <c:forEach var="potentialOptionGroup" items="${optionOrOptionGroup.value}" varStatus="potentialOptionGroupStatus">
         <c:if test="${potentialOptionGroupStatus.index > 0}">
            <c:set var="collection" value="true" />
         </c:if>
      </c:forEach>
      <c:choose>
         <c:when test="${collection eq true}">
            <%--  Now we know this is a LinkedHashMap --%>
            <optgroup label="${optionOrOptionGroup.key}">
               <c:forEach var="optionGroup" items="${optionOrOptionGroup.value}">
                  <form:option label="${optionGroup.key}" value="${optionGroup.value}" />
               </c:forEach>
            </optgroup>
         </c:when>
         <c:otherwise>
            <%--  Now we know this is a flat String --%>
            <form:option label="${optionOrOptionGroup.key}" value="${optionOrOptionGroup.value}" />
         </c:otherwise>
      </c:choose>
   </c:forEach>
</form:select>