Spring mvc 3 dynamic list binding + jquery + AJAX

I ran into the problem of dynamically linking lists in Spring. I am trying to create an Add Contact page that looks like this:

Contact Form

When the "Add Phone" button is clicked, I want the "Phone Type" and "Phone Number" buttons to appear below so that the user can enter several phone numbers. Here I run into problems.

Below is my code:

Domain Class - Contact:

In my form, First Name, Last Name, Email and Birthday are the instance variable of the Contact domain class, as well as the Phone and Phone Type of the Phones List part.

@Entity @Table(name = "CONTACTS_JPA2") public class Contact { @Id @Column(name = "CONTACT_ID") @GeneratedValue private int Id; @Column(name = "FIRST_NAME") private String firstname; @Column(name = "LAST_NAME") private String lastname; @SuppressWarnings("unchecked") @OneToMany(mappedBy = "contact", cascade = CascadeType.ALL) private List<Phone> phones = LazyList.decorate(new ArrayList<Phone>(),FactoryUtils.instantiateFactory(Phone.class)); @Column(name = "EMAIL_ID") private String emailid; @Column(name = "BIRTHDAY") private Date birthday; /*Getters and Setters*/ } 

Cool phone:

  @Entity @Table(name = "PHONE") public class Phone { @Id @Column(name = "ID") private int Id; @Column(name = "PHONE_NBR") private String phonenumber; @Column(name = "PHONE_TYPE") private String phonetype; @ManyToOne() @JoinColumn(name = "CONTACT_ID") private Contact contact; /*Getters and Setter*/ } 

HTML form (JSP):

  <form:form id = "addcontactform" name="addcontact" method="POST" commandName="contact"> <table> <tr> <td>First Name:</td> <td><form:input name = "firstname" id = "firstname" path="firstname" value=''/></td> <td>Last Name:</td> <td><form:input name = "lastname" id = "lastname" path="lastname" value=''/></td> </tr> <tr> <td>Email:</td> <td><form:input name = "emailid" id = "emailid" path="emailid"/></td> </tr> <tr> <td>Phone Type:</td> <td> <spring:bind path = "contact.phones[0].phonetype"> <form:select id ="phonetype" name="phonetype" path="${status.expression}"> <option value="-- Select Phone Type --">-- Select Phone Type --</option> <option value="Home">Home</option> <option value="Cell">Cell</option> <option value="Work">Work</option> </form:select> </spring:bind> </td> <td>Phone Number:</td> <td> <spring:bind path = "contact.phones[0].phonenumber"> <form:input name = "phonenumber" id = "phonenumber" path="${status.expression}" value=''/> </spring:bind> </td> <td><form:button type = "button" id = "addphone">Add Phone</form:button> </tr> <tr> <td>Birthday:</td> <td><form:input id = "birthday" path="birthday" value=''/></td> </tr> </table> </div> <input type="submit" id = "mysubmit" name="mysubmit" value="Add Contact" /> </div> </form:form> 

Javascript in the above form:

Here I try to do the following: when I click the Add Phone button, I send an AJAX request to the server indicating the number of lines that need to be inserted.

  <script type="text/javascript" src="${pageContext.request.contextPath}/resources/scripts/jquery.min.js"></script> <script type="text/javascript"> $(document).ready(function(){ $('#addphone').click(function(){ phonecount++; alert('Addinh phone '+phonecount); $.get("displayaddphone", {count : phonecount},callback); function callback(data){ alert('in Callback'); $("#addphone").before(data); }; return false; }); </script> 

The controller method is called upon an AJAX request: It adds the number of rows to the model and returns jsp - addnewphone.jsp

 @RequestMapping(value = "/displayaddphone") public String appendaddphone(@RequestParam(value="count") int addphonecount,ModelMap model){ model.addAttribute("addphonecount", addphonecount); return "addnewphone"; } 

JSP addnewphone: contains an HTML snippet for a new line.

  <%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%> <%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %> <tr> <td>Phone Type:</td> <td> <form:select id ="phonetype" name="phonetype" path="contact.phones[${addphnbr}].phonetype"> <option value="-- Select Phone Type --">-- Select Phone Type --</option> <option value="Home">Home</option> <option value="Cell">Cell</option> <option value="Work">Work</option> </form:select> </td> <td>Phone Number:</td> <td> <form:input name = "phonenumber" id = "phonenumber" path="contact.phones[${addphnbr}].phonenumber" value=''/> </td> </tr> 

I am trying to pass this view (contained in the 'data' variable) to my AJAX callback function in the above javascript and add it to my original "Add Contact" form using - $ ("# addphone"). (data);

When you click the "Add Phone" button, the following error appears:

  SEVERE: Servlet.service() for servlet [appServlet] in context with path [/ContactList-JPA2] threw exception [java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'contact' available as request attribute] with root cause java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'contact' available as request attribute at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:141) at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(Abs tractDataBoundFormElementTag.java:178) at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(AbstractDataBoundFormElementTag.java:198) at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getName(AbstractDataBoundFormElementTag.java:164) at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.writeDefaultAttributes(AbstractDataBoundFormElementTag.java:127) at org.springframework.web.servlet.tags.form.AbstractHtmlElementTag.writeDefaultAttributes(AbstractHtmlElementTag.java:421) at org.springframework.web.servlet.tags.form.SelectTag.writeTagContent(SelectTag.java:199) at org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:102) at org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:79) at org.apache.jsp.WEB_002dINF.views.addnewphone_jsp._jspx_meth_form_005fselect_005f0(addnewphone_jsp.java:117) at org.apache.jsp.WEB_002dINF.views.addnewphone_jsp._jspService(addnewphone_jsp.java:76) at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432) at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334) at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:690) at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:477) at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:402) at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:329) at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:238) at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:262) at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1157) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:927) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:827) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778) at javax.servlet.http.HttpServlet.service(HttpServlet.java:621) at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:311) at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:116) at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:101) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:182) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:173) at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at com.springsource.insight.collection.tcserver.request.HttpRequestOperationCollectionValve.invoke(HttpRequestOperationCollectionValve.java:88) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1001) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) at java.lang.Thread.run(Thread.java:722) 

Essentially, I'm trying to create the HTML that I want to add on my main page in a separate jsp, and trying to add it to my form dynamically. This is the right approach in general for my scenario. Please advise.

+6
source share
1 answer

You accept something like contact.phones [$ {addphnbr}]. phonetype in its jsp. And your controller did not send this information along with jsp. That is why this error.

Your controller should provide the contact attribute for your jsp. Now you send "addphonecount" to jsp and you don't seem to use it in jsp. You may need to send a β€œcontact”.

 @RequestMapping(value = "/displayaddphone") public String appendaddphone(@RequestParam(value="count") int addphonecount,ModelMap model){ // define "contact" object, suppose for example Contact contact = populateContact(); model.addAttribute("contact", contact); return "addnewphone"; } 
+3
source

All Articles