如何使用Spring MVC将Java Map放入Optgroup选项中

How to put Java Map into Optgroup Options Using Spring MVC?

本文关键字:放入 Optgroup 选项 Map Java 何使用 Spring MVC      更新时间:2023-09-26

我使用的是Spring MVC。

我目前有一个Map通过request.setAttribute('userLocales',bluh-bluh-bluh)从Java传递到我的页面,这个变量名为"userLocales"

我需要以某种方式获取该变量中的字符串,以便在optgroup选择元素中构建选项元素列表。我最初的想法是以某种方式将这个Map变成一个Javascript对象,然后将字符串添加到新创建的选项元素中,放置在optgroup元素中。

optgroup元素是静态的并且已经创建。我只需要带字符串的选项。

我想我在发布这个问题后就找到了答案。奇妙的

来源:http://www.imrantariq.com/blog/option-group-capability-for-spring-mvc-form-taglib/

设置"optgroup"属性时,该属性将首先根据"optgroup"中定义的任何"表达式"进行排序,然后跟踪迭代的进展,并在选择列表中使用"optgroup(optgroup)"中的表达式作为标签,在适当的情况下插入"optgroup)html开始标记和结束标记。

不幸的是,目前springmvc并没有通过标签提供这样的功能。这可以通过下面给出的一个很好的逻辑来实现。您需要从控制器发送一个hashMap。

Map<String, ArrayList<String>>

在这个映射中,字符串是键,即组名,arraylist是位于这个组中的值的数量。Jsp代码可以用这种方式编写。

<form:select multiple="single" path="itemType" id="itemType">
    <form:option value="0" label="Select" />
    <c:forEach var="itemGroup" items="${itemTypeList}" varStatus="itemGroupIndex">
       <optgroup label="${itemGroup.key}">
           <form:options items="${itemGroup.value}"/>        
       </optgroup>
    </c:forEach>        
</form:select>

控制器

请注意,集合为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;
    }
}

另一种情况:有时Select项目是MIXED(与OptGroup混合的平面)

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

在这种情况下,Collection可以是Map,其中每个条目都将键控到对象(1)String或(2)HashMap,我们将从JSP中发现。

用于MIXED数据结构的控制器

@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;
}           

MIXED数据结构的JSP(确定Collection与否需要技巧,通过迭代和设置var来完成)在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>