ajaxjsfbootsfaces

Execute two AJAX calls in commandButton onclick bootsfaces jsf


I have a modal with a form, and what I want is first to close the modal from bean (method "cerrarModal") and after execute the AJAX that makes the insert in database (method "crearUsuario"). I saw this question but it didn't work for me.
this is my button:

<b:commandButton value="Guardar" ajax="true" 
                 update="formTblUsuarios:growlMsg formTblUsuarios:tblUsuarios rowModal" 
                 id="btnGuardarUsuario" look="primary" 
                 onclick="ajax:admUsuariosBean.cerrarModal();admUsuariosBean.crearUsuario()" />


And these are my bean methods:

public void cerrarModal() {
    RequestContext.getCurrentInstance().execute("$('#usuarioModal').modal('hide');");
}

public void crearUsuario() {
    try {
        if (this.fachada.crearUsuario(getUsr())) {
            this.reestablecerClave();FacesMessages.info("User created.");
        } else {
            FacesMessages.warning("The user was not created.");
        }
    } catch (Exception e) {
        FacesMessages.error("The user was not created.");
}

But server throws this error:

abr 04, 2018 11:02:14 AM com.sun.faces.lifecycle.InvokeApplicationPhase execute ADVERTENCIA: Failed to parse the expression [#{admUsuariosBean.cerrarModal();admUsuariosBean.crearUsuario()}] javax.el.ELException: Failed to parse the expression [#{admUsuariosBean.cerrarModal();admUsuariosBean.crearUsuario()}] at org.apache.el.lang.ExpressionBuilder.createNodeInternal(ExpressionBuilder.java:145) at org.apache.el.lang.ExpressionBuilder.build(ExpressionBuilder.java:171) at org.apache.el.lang.ExpressionBuilder.createValueExpression(ExpressionBuilder.java:216) at org.apache.el.ExpressionFactoryImpl.createValueExpression(ExpressionFactoryImpl.java:66) at net.bootsfaces.component.ajax.AJAXBroadcastComponent.evalAsValueExpression(AJAXBroadcastComponent.java:74) at net.bootsfaces.component.ajax.AJAXBroadcastComponent.executeAjaxCalls(AJAXBroadcastComponent.java:123) at net.bootsfaces.component.ajax.AJAXBroadcastComponent.broadcast(AJAXBroadcastComponent.java:52) 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:303) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at com.abcpagos.otis.beans.Filtro.doFilter(Filtro.java:44) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:748) Caused by: org.apache.el.parser.ParseException: Encountered " "; "" at line 1, column 32. Was expecting one of: "}" ... "." ... "[" ... ">" ... "gt" ... "=" ... "ge" ... "


I'm using BootsFaces 1.2.0, with PrimeFaces 6.1, JSF 2.2, (XAMPP) Apache Tomcat 7.0.56.
Thanks.


Solution

  • First of all, the answer of @Holger is (mostly) right: your particular use case doesn't require an AJAX call. However, there are use cases requiring two successive AJAX calls, so I'll ask your original question nonetheless.

    I've implemented the parser of BootsFaces in a very simple way. The onclick handler may consist of three parts: a JavaScript part that's executed before the AJAX call, the AJAX call, and a second JavaScript part that's executed after sending the AJAX request to the server. Note that the second JavaScript bit is almost certainly executed before the Java code.

    In theory, I could have implemented the AJAX engine with multiple AJAX calls in mind. However, I didn't see the point to do so: It's easier to call a Java method calling two methods instead of triggering two AJAX calls, each calling a Java method and each updating the DOM.

    But then... never say never. If you really need two consecutive AJAX calls, you can implement this using <b:remoteCommand>. Such a <b:remoteCommand> is a JavaScript function calling a Java method via AJAX and updating the DOM. So you can call the <b:remoteCommand> in the onComplete handler to trigger the second AJAX request.

    There's that. However, you simply want to close the modal, so I recommend to implement it like so:

    <b:commandButton value="Guardar"
             update="..." 
             onclick="$('#usuarioModal').modal('hide');ajax:admUsuariosBean.crearUsuario()" />