2012-08-08 40 views
2

考虑以下情形:处理相同类型的多种形式 - 不可能?

  1. 我的表单模型

    public class PersonForm { 
        @NotNull 
        private String name; 
    
        /*usual getters and setters*/ 
    } 
    
  2. 我的控制器:

    @Controller 
    @SessionAttribute(types={ PersonForm.class }) 
    public class MyController { 
    
        @RequestAttribute(...) 
        public String render(final ModelMap map) { 
         /* get list of info and for each info 
         * create a PersonForm and put it in the modelmap 
         * under key p0, p1, p2, ..., pn 
         */ 
        } 
    
        public String submit(final ModelMap map, 
             @Valid final PersonForm form, 
             final BindingResult result) { 
    
         if (result.hasErrors()) { 
          // return to page 
         } else { 
          // do necessary logic and proceed to next page 
         } 
        } 
    } 
    
  3. 最后我的JSP视图

    ... 
    <c:forEach ...> 
        <form:form commandName="p${counter}"> 
         ... other form:elements and submit button goes here 
        </form:form> 
    </c:forEach> 
    ... 
    

正如你所看到的,我正在尝试处理同一类类型的多种形式。提交作品 - 它使我得到提交(...)方法很好,验证也是如此。但是,重新渲染页面并不会显示预期的错误消息!

更糟糕的是 - 我检查了提交标题中传递的内容,并且没有任何提示表单提交的任何迹象,因此无法区分一种表单提交。这使我相信同一类的多种形式是不可能的...

是否有任何其他方式可以做到这一点(除了Ajax)?

非常感谢。

+0

“form:form'标签的'path'属性的用途是什么?我认为在这个春天的标签中没有定义:[spring-form definition](http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/spring-form.tld.html #弹簧form.tld.form)。 – jelies 2012-08-08 10:10:27

+1

我的歉意 - 我的意思是commandName。原始线程已被编辑。 – 2012-08-08 11:00:47

回答

2

我设法让这个'黑客'工作。正如 jelies所建议的那样,信誉归功于他。

简而言之,其概念是使用传统的<c:forEach>构造预填充您的视图。棘手的部分是每当按下相应行的“提交”按钮时,所有信息都必须注入隐藏表单并强制提交给控制器。如果屏幕再次出现一些错误,则该脚本必须负责将值注回到相应的行,包括的错误。


1)我的模型

public class PersonForm { 

     private String id; 

     @NotNull 
     private String name; 

     /*usual getters and setters*/ 
    } 

2)我的控制器

@Controller 
    @SessionAttribute(/* the hidden form name, the person list */) 
    public class MyController { 

     @RequestAttribute(...) 
     public String render(final ModelMap map) { 
      /* get list of info and for each info 
      * create a PersonForm and put it in the modelmap 
      * under key p0, p1, p2, ..., pn 
      */ 
     } 

     public String submit(final ModelMap map, 
          @Valid final PersonForm form, 
          final BindingResult result) { 

      if (result.hasErrors()) { 
       // return to page 
      } else { 
       // do necessary logic and proceed to next page 
      } 
     } 
    } 

3)我的观点

... 

    <form:form commandName="personForm" cssStyle="display: none;"> 
     <form:hidden path="id"/> 
     <form:hidden path="name" /> 
     <form:errors path="name" cssStyle="display: none;" /> 
    </form:form> 

    ... 

    <c:forEach var="p" items="${pList}"> 
     <input type="text" id="${ p.id }Name" value="${ p.name }" /> 
     <!-- to be filled in IF the hidden form returns an error for 'name' --> 
     <span id="${ p.id }nameErrorSpan"></span> 
     <button type="button" value="Submit" onclick="injectValuesAndForceSubmit('${ p.id }');" /> 
    </c:forEach> 

    ... 

    <script type="text/javascript"> 

    injectValuesAndForceSubmit = function(id) { 

     $('#id').val(id); // fill in the hidden form's id 
     $('#name').val($('#'+id+'name').val()); //fill in the hidden form's name 

     $('#personForm').submit(); //submit! 
    } 



    $(document).ready(function() { 

     var id = $('#id').val();  
     if (id.trim().length == 0) { 
      //Empty. Nothing to do here as this is a simple render. 
     } else { 

      //The page seems to be returning from some sort of error ... pre-fill the respective row! 
      $('#'+id+'name').val($('#name').val()); 
      var hiddenNameErrorSpan = $('#name.errors'); 
      if (hiddenNameErrorSpan) { 
       $('#'+id+'nameErrorSpan').text(hiddenNameErrorSpan.html()); 
      } 
     } //else 
    } 
    </script> 

正如你可发即观点有最毛茸茸的部分 - 希望它仍然证明对于(不幸)遇到与我一样的情况的任何人都是有用的。干杯!

0

恕我直言,有多种形式使事情复杂(或至少与春天)。此外,您正在使用多个表单,但只有一个将被提交。

所以,我建议管理这个最简单的方法是使用一个独特的隐藏的外部形式与人物特性。当其中一个按钮被按下时,相应地填写表格的人物属性并提交。有了这个,你正在实现典型的弹簧表单提交/验证。

也许这个解决方案需要JavaScript的一些工作,但我不知道如何处理多种形式的spring-mvc,我总是试图避免它,因为以前尝试失败。

+0

非常感谢您的回复!恐怕我仍然会在分配表单时遇到问题:错误。 – 2012-08-08 11:15:15

+0

不客气:)好吧,如果你只有一种形式,你总是会知道错误在哪里......但是,再次需要一些额外的JS将它们移动到正确的位置。 – jelies 2012-08-08 11:18:39

+0

其实我没有想到...我可以用一些JS提取错误信息。它比涉及AJAX更清洁。谢谢! – 2012-08-08 14:20:28

相关问题