Reputation: 137
I'm trying to implement an autosave feature on a very long form.
I have this form in JSF with a lot of <h:inputText/>
s that can't be null or empty because of the @NotNull javax validation annotation. Also, I have some <h:selectOneMenu>
s that have
<f:ajax event="change" render="form-blueform-pnl_team" execute="form-blueform-pnl_team" listener="${improvementView.onTeamChange()}" />
that update some other <h:inputText/>
s values dynamically.
The submit is like:
<h:commandButton action="${improvementView.save()}" styleClass="btn btn-primary ink-reaction marginleft5 hidden" id="save-blueform-btn">
<f:ajax execute="@all" render="@all"/>
</h:commandButton>
<a href="#" id="form-blueform-save-blueform-btn-ui" class="btn btn-primary ink-reaction marginleft5">
<i class="fa fa-save"></i> Save
</a>
jQuery receives the click event of the #form-blueform-save-blueform-btn-ui and validates some stuff. After everything it is alright, it clicks the #form-blueform-save-blueform-btn. Everything works great until this points.
The trouble starts happening when I dynamically want to change the value of the JSF inputs with $(#someinput).val("new value"). The value DOES change perfectly but the ajax onchange event of the dropdown - for example - doesn't get executed. Also, if I try to submit the form, jQuery validations turn up ok but then the JSF validations fail saying that everything is null. Essentially, the JSF components are not recognizing the jQuery value changes.
I've been struggling with this for some time now and can't find anything helpful. I'd really appreciate if somebody could guide me here.
Here you can find more snippets of my code:
This is how my <h:inputText>
s look like
<h:inputText id="name" value="${improvementView.item.name}" styleClass="form-control" pt:required="required" />
This is how my jQuery handles the #form-blueform-save-blueform-btn-ui click:
$("#form-blueform-save-blueform-btn-ui").click(function(e) {
var valid = $(".form-blueform")[0].checkValidity();
if(valid) {
$(".card-actionbar-row .btn").hide();
$("#form-blueform-loading-submit").css({"display":"inline-block"});
$("#form-blueform-save-blueform-btn").click();
} else {
$(".form-blueform")[0].reportValidity();
}
e.preventDefault();
});
This is the log that it is returned by Tomcat:
WARNING: ${improvementView.save()}: java.lang.IllegalArgumentException: can't parse argument number: interpolatedMessage='may not be null' javax.faces.FacesException: ${improvementView.save()}: java.lang.IllegalArgumentException: can't parse argument number: interpolatedMessage='may not be null' at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118) at javax.faces.component.UICommand.broadcast(UICommand.java:315) at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790) at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282) at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81) at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at com.madatait.ci.security.filters.AuthenticationFilter.doFilter(AuthenticationFilter.java:46) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:217) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:745)
and that repeats for every input that can't be null.
Upvotes: 0
Views: 630
Reputation: 137
Okay, so I finally figured it out. I have to trigger the onchange event manually of each input with jQuery's .change() so the ajax gets executed and JSF recognizes the dynamic change of the values.
$(".form-control").each(function() {
$(this).change();
});
I'm sure this will save at least someone a few good hours.
Upvotes: 2