如何在Spring中使用JSTL在下拉列表中显示数据?

时间:2014-09-05 19:32:38

标签: javascript jquery spring jsp jstl

我有PersonDTO对象,其中包含:

String name;
List<String> skills;//getter setter

当jsp第一次加载时,我从@ModelAttribute获取下拉值,如下所示:

List<PersonDTO> personInfo= personService.getInfomation(id);    
model.addAttribute("personInfo",personDTO);  

并在jsp中显示:

<div>
<form:select  name="name" path="name">
<c:forEach items="${personInfo}" var="var">
<form:option value="${var.name}">"${var.name}" /></form:option>
</c:forEach>
</form:select>
<div>
<div>
<form:select  name="skills" path="skills">
<c:forEach items="${personInfo.skills}" var="skill">
<form:option value="${skill}">"${skill}" /></form:option>
</c:forEach>
</form:select>
<div>

所以现在我该怎么做:如果用户在第一个下拉列表中更改名称,那么第二个下拉值必须根据所选人员的技能自动更改。我使用的是Spring 4,maven,JSTL,jQuery, javascript和spring form标签。这是所有客户端。这里我们没有使用name参数进行任何ajax调用来获取技能值并在dropdown中显示它。请帮助。感谢

2 个答案:

答案 0 :(得分:2)

你只需要一个具有所有名称和技能的javascript对象,所以当名称发生变化时,技能已经在客户端可用。通常,最好通过将列表序列化为控制器中的JSON字符串来做到这一点,但是为了避免告诉您在项目中添加像Gson这样的新依赖,可以通过在脚本标记中填充javascript对象来完成此操作。

<script type="text/javascript">
    var peopleSkills = {};  

    <c:forEach var="person" items="${personInfo}">
        peopleSkills['${person.name}'] = new Array();
        <c:forEach var="skill" items="${person.skills}">
            peopleSkills['${person.name}'].push('${skill}');
        </c:forEach>
    </c:forEach>

    function updateSkills(name) {
        var skillsArray = peopleSkills[name];
        var markup = ''
        for (var i = 0; i < skillsArray.length; i++)
            markup += '<option value="' + skillsArray[i] + '">' + skillsArray[i] + '</option>';
        $('#skillsselect').html(markup);            
    }   

    $(document).ready(function(){
        updateSkills($('#nameselect').val()); // for initial option on page load

        $('#nameselect').change(function(){
            var personName = $(this).val();
            updateSkills(personName);   
        });
    });
</script>

<div>
    <form:select name="name" id="nameselect" path="name">
        <c:forEach items="${personInfo}" var="var">
            <form:option value="${var.name}">"${var.name}" /></form:option>
        </c:forEach>
    </form:select>
<div>
<div>
    <form:select name="skills" id="skillsselect" path="skills"></form:select>
<div>

绝对考虑在控制器中创建JSON字符串,以避免在脚本标记中混合使用服务器端和客户端代码。并且还准备了两个不同的人具有相同名称的情况。

答案 1 :(得分:1)

不需要<c:foreach来迭代所有选项,而是使用spring <form:options标记,如:

我正在考虑您的PersonDTO类的属性 id name 然后,

<form:select id="name" path="name">
  <option value="0">--select--</option>
  <form:options items="${personInfo}" itemLabel="name" itemValue="id">
</form:select>

simillarly for skills:

<form:select id="skills" path="skills">
  <form:options items="${personInfo.skills}"> />
</form:select>

加载所选人员的技能,根据人员ID向控制器发出AJAX get请求,并从控制器返回人员技能:

控制器中的GET处理程序方法如下所示:

@RequestMapping(value="/{personId}/getSkills", method=RequestMethod.GET,
        consumes=MediaType.APPLICATION_JSON_VALUE,
        produces=MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody List<Skills> getSkills(@PathVariable("personId")Integer personId){

    List<Skills> personSkills = personService.getPersonSkills(personId);
    return personSkills;
}

Ajax调用将如下所示:

$('select#name').change(function(){
    $.getJSON('/'+$('select#name option:selected').val()+'/getSkills', function(skills) {
        $('select#skills').empty(); //first remove existing options then append new options
        $.each( skills, function( key, val ) {
            $('select#skills').append($("<option></option>")
                     .attr("value",key)
                     .text(val));
          });
    });         
 });

注意:要激活@ResponseBody,添加<mvc:annotation-driven/>以及Jackson mapper或任何其他映射器应该在buildpath上可用,以便进行JSON序列化和反序列化。

另见:

编辑:根据您的评论,解决方案将是

<script type="text/javascript">
    var peopleSkills = {};  

    <c:forEach var="person" items="${personInfo}">
        peopleSkills['${person.name}'] = new Array();
        <c:forEach var="skill" items="${person.skills}">
            peopleSkills['${person.name}'].push('${skill}');
        </c:forEach>
    </c:forEach>

    $('select#name').change(function(){
         var skills = peopleSkills[$(this).val()];
         console.log($(this).val()+' has: '+JSON.stringify(skills));
         $('select#skills').empty();
         $.each( skills, function( key, val ) {
             $('select#skills').append($("<option></option>")
                         .attr("value",val)
                         .text(val));
         });
    });
</script>