AJAX even easier

The current HowTo document on AJAX doesn't yet mention an important pattern that can make your AJAX life much easier.

Your event handler can return a ForwardResolution in response to an ajax call. This lets you use jsp (or FreeMarker templates) to generate the resulting html fragments. So the same source that generates your initial page can be refactored to also handle ajax events. Without having to use JSON or XML, without having to hard-code html into a java class, without having to write custom javascript.

If you use Prototype, then you can use javascript like the methods below:

javascript
 
function formUpdater(container, formId, event, complete) { 
    form = $(formId); 
    ajaxUpdater(container, form.action, event, Form.serialize(form), complete); 
} 


function ajaxUpdater(container, url, event, params, complete) { 
    if (event != null) { 
        params = event + '=submit&' + params; 
        new Ajax.Updater(container, url, {method:'post', postBody:params, onComplete:complete}); 
    } 
} 

Ajax.Updater will make the request. Your ActionBean event handler forwards to some jsp/ftl, which renders a fragment of HTML. Ajax.Updater will update $(container) with the results.

AJAX with jQuery

Here is how you could write the invoke() function found on this page using jQuery.

jsp/test.jsp
 
<%@ page contentType="text/html;charset=UTF-8" language="java" %> 
<%@ taglib prefix="stripes" uri="http://stripes.sourceforge.net/stripes.tld" %> 

<html> 
<head><title>Simple jsp page</title> 
<script type="text/javascript" src='/jquery-1.2.3.min.js'></script> 
<script type="text/javascript"> 
function invoke(form, event, container) { 
    params = {}; 
    if (event != null) params = event + '&' + $(form).serialize();
    $.post(form.action, params,
        function (xml) { 
            $(container).html(xml); 
        }
    ); 
} 

$(function() { 
    $('input[type=text]').keyup(
        function() { 
            invoke($('form')[0], 'ajax', '#replaceWithAjax'); 
        }
    ); 
}
); 
</script> 
</head> 
<body> 

<stripes:form beanclass="com.example.web.actionbean.TestActionBean"> 
    <stripes:text name="text"/> 

    <div id="replaceWithAjax">The text you type will replace this text.</div> 

    <stripes:submit name="submit"/> 
</stripes:form> 

</body> 
</html> 

Here is the action bean this example uses:

 
... 

public class TestActionBean extends ActionBean { 

    private String text; 

    @DefaultHandler 
    public Resolution test() { 
        return new ForwardResolution("/jsp/test.jsp"); 
    } 

    public Resolution ajax() { 
        return new ForwardResolution("/jsp/test2.jsp"); 
    } 

    public Resolution submit() { 
        return new RedirectResolution(HomeActionBean.class); 
    } 

    public String getText() { 
        return text; 
    } 

    public void setText(String text) { 
        this.text = text; 
    } 
} 

And here is test2.jsp

/jsp/test2.jsp
 
<%@ page contentType="text/html;charset=UTF-8" language="java" %> 
${actionBean.text}