2012-11-02 23 views
6

Mam do czynienia z problemem z dynamicznym wiązaniem list na wiosnę. Próbuję stworzyć stronę „Dodaj kontakt”, który zasadniczo wygląda następująco:Spring mvc 3 dynamiczna lista wiążąca + jquery + AJAX

Contact Form http://i47.tinypic.com/345g50h.png

Gdy przycisk „Add Phone” kliknięciu chcę kolejny „Phone Type” i „numer telefonu”, aby pojawić się przycisk poniżej, aby użytkownik mógł wprowadzić wiele numerów telefonów. Właśnie tam napotykam problemy.

Poniżej jest mój kod:

Domain Class - Kontakt:

W moim formularzu, imię, nazwisko, e-mail i urodziny są instancja zmiennej klasy domeny „Kontakt” i typ telefonu i Numer telefonu części List Telefony.

@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*/ 

    } 

Klasa Telefon:

@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 w powyższym formularzu:

Co usiłuję zrobić tutaj jest, kiedy kliknij przycisk "Dodaj telefon", wysyłam żądanie AJAX do serwera z liczbą wierszy do wstawienia.

<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> 

metoda zwana Controller na żądanie AJAX: Dodaje wiersz policzyć do modelu i zwraca JSP - addnewphone.jsp

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

addnewphone JSP: zawiera fragment HTML dla nowego wiersza .

<%@ 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> 

Próbuję przekazać ten pogląd (zawarty w zmiennej „dane”) do mojej funkcji wywołania zwrotnego AJAX w wyżej javascript i dodać go do mojego oryginalnego „Dodaj kontakt” formie, używając - $ ("# addphone ") .przed (dane);

otrzymuję następujący błąd po kliknięciu „Dodaj przycisk Telefon”:

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) 

Zasadniczo próbuję contruct HTML, który chcę dodać na mojej stronie głównej w oddzielnym JSP i próbując dodać to dynamicznie do mojej postaci. Czy w moim scenariuszu jest to poprawne podejście? Proszę o poradę.

Odpowiedz

3

Akceptujesz coś takiego jak contact.phones [$ {addphnbr}] .phonype w twoim jsp. Twój kontroler nie wysłał tych informacji razem z jsp. Właśnie dlatego ten błąd.

Twój kontroler powinien dostarczyć do twojego jsp atrybutu "kontakt". Teraz wysyłasz "addphonecount" do jsp i nie używasz go na jsp. Może zaistnieć potrzeba wysłania "kontaktu".

@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"; 
} 
+0

@ Jeevan - To działało. Dziękuję bardzo za odpowiedź. –

Powiązane problemy