Executing spring web flow transitions using javascript form submit
-
28-10-2019 - |
Question
We are using a combination of facelets and spring web flow in our web project. There are some variables declared in the web flow. I would like to access these variables outside the flow. The reason I am trying to access these variable is, we are submitting a form using javaScript. We cannot submit a form as part of webflow using javaScript.
Can anybody give directions to submit a form using javaScript and still be part of web flow (as if a commandButton or commandLink was clicked)?
OR
How can I access flow variables outside the we flow?
Solution
I was able to find the solution after doing some more search on google. I was able to submit a form from javascript and still be part of the web flow. I followed the below steps:
Javascript - form submit on change of combo-box value:
jQ161("#comboBoxId").change(function(e) { var formAction = document.myform.action; document.myform.action = formAction + '&_eventId=showDetails¶m1=value1'; document.myform.submit(); });
The eventId is set to value of the transition in the web flow.
We need to have a JSF Phase listener. This listener intercepts in the JSF flow and divert the flow to web flow executor. I needed the flow to be intercepted after the Update Model Values JSF phase is completed. Following is the code for the same:
import javax.el.ELContext; import javax.el.MethodExpression; import javax.faces.component.UICommand; import javax.faces.context.FacesContext; import javax.faces.event.ActionEvent; import javax.faces.event.PhaseEvent; import javax.faces.event.PhaseId; import javax.faces.event.PhaseListener; import org.springframework.faces.webflow.JsfUtils; public class EventIdPhaseListener implements PhaseListener { public void afterPhase(PhaseEvent event) { if (JsfUtils.isFlowRequest()) { FacesContext context = event.getFacesContext(); if (context.getExternalContext().getRequestParameterMap().containsKey("_eventId")) { UICommand eventSource = new UICommand(); eventSource.setTransient(true); eventSource.setParent(context.getViewRoot()); eventSource.setId("_eventId"); String eventId = (String) context.getExternalContext().getRequestParameterMap().get("_eventId"); eventSource.setActionExpression(convertEventIdToMethodExpression(context, eventId)); context.getViewRoot().queueEvent(new ActionEvent(eventSource)); } } } public void beforePhase(PhaseEvent event) { // Do Nothing } public PhaseId getPhaseId() { return PhaseId.UPDATE_MODEL_VALUES; } private MethodExpression convertEventIdToMethodExpression(FacesContext facesContext, String eventId) { ELContext elContext = facesContext.getELContext(); return facesContext.getApplication().getExpressionFactory().createMethodExpression(elContext, eventId, String.class, new Class[0]); } }
For further details check JSF Phase Listener and Spring web flow and MVC integration.