JQuery event trigger result in WebWork 2.2.x and Struts2

Suppose you are writing a web application in Java and use the Struts2 web framework. Suppose you have a list of detail records and you want to allow the user to edit the records via a dialog box that opens on top of the list. Suppose JQuery is your javascript library du jour. Suppose you need to validate the input and keep the dialog open if the user enters one or more invalid field values, but the dialog needs to close when the form is submitted successfully.

Suppose you are writing a web application in Java and use the Struts2 web framework. Suppose you have a list of detail records and you want to allow the user to edit the records via a dialog box that opens on top of the list. Suppose JQuery is your javascript library du jour. Suppose you need to validate the input and keep the dialog open if the user enters one or more invalid field values, but the dialog needs to close when the form is submitted successfully. Finally, you need to refresh the list to display records added/edited in the dialog.Suppose you are writing a web application in Java and use the Struts2 web framework.

Suppose you have a list of detail records and you want to allow the user to edit the records via a dialog box that opens on top of the list. Suppose JQuery is your javascript library du jour. Suppose you need to validate the input and keep the dialog open if the user enters one or more invalid field values, but the dialog needs to close when the form is submitted successfully.

Finally, you need to refresh the list to display records added/edited in the dialog. To make all of this happen, in particular the different behavior when the form is submitted with valid data errors vs. invalid data, you need to tie the list update and the dialog close to a JQuery event.

You also need to make this event the “success” result of the save action, so a successful save fires the event. So, how do you do that? The first step is to create a result class. There is a small but critical difference between WebWork 2.2.x and Struts2. This class will work for Struts2:

 package com.agileapproach;<br>import com.opensymphony.xwork2.ActionInvocation; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.dispatcher.StrutsResultSupport;<br>/*<br><strong><br></strong> Struts 2 result type that interprets the location provided via configuration<br>* as the name of a JQuery event that should be published, and generates a<br>* response containing the JavaScript necessary to trigger this event.<br>*/ public class JQueryEventTriggerResult extends StrutsResultSupport {<br>private static final String PRE_TOPIC_TEXT = "<script type="text/javascript">$(document).trigger("";<br> private static final String POST_TOPIC_TEXT = "");</script>";<br> protected void doExecute(String finalLocation, ActionInvocation invocation)<br> throws Exception {<br><br> ActionContext context = invocation.getInvocationContext();<br> HttpServletResponse response = (HttpServletResponse)context.get(HTTP_RESPONSE);<br> response.getWriter().append(PRE_TOPIC_TEXT).append(getLastFinalLocation()).append(POST_<br>TOPIC_TEXT);<br> response.flushBuffer();<br> } }

The key is the call to getLastFinalLocation() that is embedded between PRE_TOPIC_TEXT and POST_TOPIC_TEXT, allowing the browser to stay on the current page rather than the having the Struts dispatcher take the browser somewhere else.

This is important to know if you are using WebWork 2.2.x, because things are a little different:

 package com.agileapproach;<br>import com.opensymphony.xwork.ActionInvocation; import com.opensymphony.webwork.dispatcher.WebWorkResultSupport; import javax.servlet.http.HttpServletResponse;<br>/*<br><strong><br></strong> WebWork 2.2.x result type that interprets the location provided via<br>* configuration as the name of a JQuery event that should be published, and<br>* generates a response containing the JavaScript necessary to trigger this<br>* event.<br>*/ public class JQueryEventTriggerResult extends WebWorkResultSupport {<br>private static final String PRE_TOPIC_TEXT = "<script type="text/javascript">$(document).trigger("";<br> private static final String POST_TOPIC_TEXT = "");</script>";<br><br> protected void doExecute(String finalLocation, ActionInvocation invocation) throws Exception<br> {<br><br> String lastFinalLocation = conditionalParse(location, invocation);<br> ActionContext context = invocation.getInvocationContext();<br> HttpServletResponse response = (HttpServletResponse)context.get(HTTP_RESPONSE);<br> response.getWriter().append(PRE_TOPIC_TEXT).append(lastFinalLocation).append(POST_<br>TOPIC_TEXT);<br> response.flushBuffer();<br> } }

Pretty similar, right?

The important difference is that WebWorkResultSupport does not expose lastFinalAction like Struts2, so we have to derive it by calling conditionalParse() before we write to the response.

This is exactly how Struts2 does it, it just does it for you in StrutsResultSupport.execute() prior to calling the overridden doExecute() method. Now that you have the result class, the rest is the same regardless of whether you are using WebWork 2.2.x or Struts, the only differences are in the names of the config files and tags.

From now on, we’ll assume you’re using Struts2.

Next you need to define a custom result class by adding the following to struts.xml:

 <result-types><br> <result-type class="com.agileapproach.JQueryEventTriggerResult" name="jQueryEvent"></result-type><br> </result-types>

Assume your editor form is defined in a page called editor.jsp.

Define an action that will handle the form submission by firing an event to refresh a list upon success or redisplaying the form if there is a validation error:

<action class="com.agileapproach.SaveAction" name="save"><br> <result type="jQueryEvent">refreshList</result><br> <result name="input">editor.jsp</result> </action>

Now you’re all set. You can then call $(document).bind("refreshList") to refresh the list when the save occurs. I’ll address the javascript required to make this work in my next post.

Jed Prentice