Spring动态(可扩展)列表表单 [英] Spring Dynamic (Expandable) List form

查看:126
本文介绍了Spring动态(可扩展)列表表单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在春季遇到一些动态形式的问题.在我们的表单中,我们想指定一个标题, 并添加一些问题.我们有一个添加"按钮,用于使用添加问题输入表单 jQuery.

I am having problems with dynamic forms in spring. In our form we want to specify a title, and add a number of questions. We have an "add" button to add question input form using jquery.

我们的表格在被要求时有一个问题字段.每次都会添加额外的字段 按下添加"按钮.提交时似乎没有多余的字段 提交(第一个被控制器接收).为什么没有发送额外的字段接收到?

Our form has one question field when it is requested. Extra fields are added every time the "add" button is pressed. When submitting it seems that the extra fields are not being submitted (the first one is received by the controller). Why are the extra fields not received being sent?

我的代码大致基于此动态绑定列表示例.

我的模型包含一个报告"类,该类具有一个 标题"和研究问题"列表.
下面是这两个模型类的简短版本. Roo负责所有的吸气剂和 二传手

My model consists of a class "Report" which has a "title" and a list of "Researchquestion"s.
A short version of the two model classes is below. Roo takes care of all the getters and setters

@Entity
@RooJavaBean
@RooEntity
public class Report{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

    @NotEmpty
    private String title;

    @OneToMany(mappedBy="report")
    private List<Researchquestion> researchquestions;
}



@Entity
@RooJavaBean
@RooEntity
public class Researchquestion {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;    
    @NotEmpty
    private String question;
}

这是表格的jspx

<div xmlns:c="http://java.sun.com/jsp/jstl/core"
    xmlns:form="http://www.springframework.org/tags/form"
    xmlns:jsp="http://java.sun.com/JSP/Page"
    xmlns:fn="http://java.sun.com/jsp/jstl/functions"
    xmlns:spring="http://www.springframework.org/tags"
    version="2.0">
    <jsp:output omit-xml-declaration="yes"/>

    <spring:url value="/admin/report/appendquestion" var="insert_url"/>

    <script type="text/javascript">
    $(document).ready(function() {
        var questionPosition = 0;
        $("#addQuestionButton").click(function() {
            questionPosition++;

            $.get("${insert_url}", { fieldId: questionPosition},
                function(data){
                    $("#insertAbove").before($(data));
            });
        });
    });
    </script>

    <div class="list_overview_box span-19">
        <spring:url value="/admin/report/" var="form_url"/>
        <div class="list_overview_content">
            <table>
                <form:form action="${form_url}" method="post" modelAttribute="report">
                    <tr>
                        <th class="span-3">Veld</th>
                        <th>Waarde</th>
                        <th class="span-5">Errors</th>
                    </tr>

        <!-- Title -->
                    <tr class="row">
                        <td class="vmiddle aleft">Title</td>
                        <td><form:input path="title" /></td>
                        <td></td>                           
                    </tr>

           <!-- the "add" button -->
                    <tr class="row">
                        <td class="vmiddle aleft">Researchquestions</td>
                        <td colspan="2"><input type="button" id="addQuestionButton" value="Add question" /></td>
                    </tr>
           <!-- First Researchquestion -->
                    <spring:bind path="researchquestions[0].question">
                        <tr class="row">
                            <td class="vmiddle aleft">Question 1</td>
                            <td><form:input path="${status.expression}" /></td>
                            <td></td>                           
                        </tr>
                    </spring:bind>

        <!--  Save button, extra question's are added here -->
                    <tr id="insertAbove" class="row">
                        <spring:message code="button.save" var="form_submit"/>
                        <td colspan="3"><input id="proceed" type="submit" value="${form_submit}" /></td>
                    </tr>   
                </form:form> 
            </table>
        </div>
    </div>
</div>

下面是控制器在jquery .get请求之后返回的页面 我有一个想法,就是需要像上面的表格一样使用<spring:bind>. 但是,当我这样做时,我得到一个错误:

Below is the page the controller returns after the jquery .get request I have the idea that I need to use <spring:bind> just like in the form above. When I do this however I get an error:

java.lang.IllegalStateException:既不绑定结果也不简单 可作为请求提供bean名称"researchquestions [1]"的目标对象 属性

java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'researchquestions[1]' available as request attribute

appendquestion.jspx

appendquestion.jspx

<jsp:root version="2.0"
    xmlns:jsp="http://java.sun.com/JSP/Page"
    xmlns:c="http://java.sun.com/jsp/jstl/core"
    xmlns:tiles="http://tiles.apache.org/tags-tiles"
    xmlns:form="http://www.springframework.org/tags/form"
    xmlns:spring="http://www.springframework.org/tags"
    xmlns:roo="urn:jsptagdir:/WEB-INF/tags" >

    <tr class="row">
        <jsp:directive.page contentType="text/html;charset=UTF-8" />   

        <td class="vmiddle aleft">Question ${questionNumber +1}</td>
        <td>
            <form:input path="report.researchquestions[${questionNumber}].question" size="40" />
        </td>
        <td></td>
    </tr>

</jsp:root>

在我们的控制器中,这里有相关的@ModelAttribute和@requestmapping方法 @ModelAttribute方法确保List实例中的List AutoPopulatingList,但我不确定是否需要.
如果我将@RequestParam Map formdata添加到create()(POST)方法中,则formdata会执行 包含researchquestions[0].question但不包含researchquestions\[1\].question或任何其他问题字段 按下添加"按钮后添加的内容

Here the relevant @ModelAttribute and @requestmapping methods in our controller The @ModelAttribute method makes sure that the List in an instance of AutoPopulatingList, I am not really sure if this is required though.
If I add @RequestParam Map formdata to the create() (POST) method then the formdata does contain researchquestions[0].question but not researchquestions\[1\].question or any other question fields that have been added after pressing the "add" button

@ModelAttribute("report")
public Report getReport(Long id) {
    Report result;
    if(id != null){
        result = Report.findReport(id);
    } else{
        result = new Report();
    }

    //Make sure the List in result is an AutoPopulatingList
    List<Researchquestion> vragen = result.getResearchquestions();
    if(vragen == null){
        result.setResearchquestions(new AutoPopulatingList<Researchquestion>(Researchquestion.class));
    } else if(!(vragen instanceof AutoPopulatingList)){
        result.setResearchquestions(new AutoPopulatingList<Researchquestion>(
                vragen, Researchquestion.class));
    }

    return result;
}

/**
 * Aanmaken Report
 * @param report
 * @param result
 * @param modelMap
 * @return
 */
@RequestMapping(method = RequestMethod.POST)
public String create(@Valid @ModelAttribute("report") Report report,
        BindingResult result, ModelMap modelMap) {

    if (report == null) throw new InvalidBeanException("A report is required");

    if (result.hasErrors()) {
        modelMap.addAttribute("report", report);
        return "admin/report/create";
    }

    report.persist();

    //create questions
    for(Researchquestion question : report.getResearchquestions()){
        question.setProfielwerkstuk(report);
        question.persist();
    }

    report.merge();
    return "redirect:/admin/report";
}

@RequestMapping(value = "/appendquestion", method = RequestMethod.GET)
public String appendResearchquestionField(@RequestParam Integer fieldId, ModelMap modelMap){
    modelMap.addAttribute("questionNumber", fieldId);
    return "admin/report/appendquestion";
}

其他信息(根据Ralph的要求)

Additional info (as requested by Ralph)

在Spring生成的HTML下方,默认是researchquestions [0] .question的形式,在按下添加"按钮后添加了researchquestions [1] .question

Below the HTML that Spring generates, researchquestions[0].question is in the form by default, researchquestions[1].question is added after pressing the "add" button

 <tr class="row">
    <td class="vmiddle aleft">Question 1</td>
    <td>
        <input id="researchquestions0.question" type="text" value=""
             name="researchquestions[0].question">
    </td>

    <td></td>
</tr>

<tr class="row">
    <td class="vmiddle aleft">Question 2</td>
    <td>
        <input id="researchquestions1.question" type="text" size="40" value="" name="researchquestions[1].question">
    </td>
    <td></td>
</tr>

来自Live HTTP标头的相关信息以下
我在标题"字段中插入了这是标题",在问题1"字段中插入了这是第一个问题",在问题2"字段中插入了这是第二个问题"(已添加)按下添加"按钮.

Below the relevant info from Live HTTP Headers
I intered "This is the title" in the "title" field, "This is the first question" in the "Question 1" field, and "This is the second question" in the "Question 2" field (which has been added by pressing the "add" button.

很明显,正在提交researchquestions [0] .question,但是在POST请求中根本没有提交researchquestions [1] .question.

It is clear that researchquestions[0].question is being submitted, but researchquestions[1].question is not submitted at all in the POST request.

Content-Type: application/x-www-form-urlencoded
Content-Length: 73
   title=This+is+the+title&researchquestions%5B0%5D.question=This+is+the+first+question

我的怀疑 第一个问题(默认情况下为表单)和后续问题之间的区别在于,第一个问题使用<spring:bind>,而后一个问题不使用<spring:bind>.当我删除第一个问题的<spring:bind>标记时,也不会提交researchquestions [0].

My suspicions The difference between the first question (that is in the form by default) and the subsequent questions is that the first question uses <spring:bind> and the subsequent ones do not. When I remove the <spring:bind> tag for the first question, the researchquestions[0] is also not submitted.

如上所述,将<spring:bind>添加到appendquestion.jspx时,我收到IllegalStateException.似乎spring搜索对象researchquestions[1] 代替report.researchquestions[1]

As I explained above, I get an IllegalStateException when adding the <spring:bind> to the appendquestion.jspx. It seems that spring searches for the object researchquestions[1] instead of report.researchquestions[1]

java.lang.IllegalStateException:既不绑定结果也不简单 可作为请求提供bean名称"researchquestions [1]"的目标对象 属性

java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'researchquestions[1]' available as request attribute

推荐答案

我找到了未正确提交表单的原因.我在萤火虫中注意到以下HTML:

I found the reason why the form was not being submitted correctly. I noticed the following HTML in firebug:

<form id="researchquestion" method="post" action="/site/admin/researchquestion/"></form>

form标记立即关闭,因此spring生成的HTML不正确. 看来这是因为表单位于表内,切换了<table><form:form>标记可以解决此问题.

The form tag is closed immediately, so the HTML generated by spring was not correct. It appears that this was because the form was inside the table switching the <table> and <form:form> tags fixed the issue.

<table>
    <form:form action="${form_url}" method="post" modelAttribute="report">
         <!--  Code here -->  
    </form:form> 
</table>

工作版本

<form:form action="${form_url}" method="post" modelAttribute="report">
    <table>
         <!--  Code here -->  
    </table>
</form:form>

<table>中,仅允许使用与表相关的标签,例如<tr><th><td>.这可能是Spring立即关闭<form>标签的原因.

In a <table> it is only allowed to use table related tags such as <tr> <th> and <td>. Which is probably why Spring immediately closed the <form> tag.

这篇关于Spring动态(可扩展)列表表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆