Mentawai Web Framework

Ajax Integration

Ajax (Asynchronous Javascript and XML) leads the web applications to a very high interactive level. If you use GMail for example, you shaw see that the interaction level of the webmail is very powerfull. You don't have to keep reloading the page to see if new mails have arrived. Asynchronously (i.e, you don't have to do refresh), the webmail system sends a request to the GMail server asking the new mails. And that just one example.
For being a such powerfull technology, Mentawai could not just ignore Ajax.

Mentawai has many renderes for working with Ajax, a server-side API for generating a String response for Ajax request's based on the action's output.
Mentawai has two main classes for Ajax integration: the AjaxConsequence and the AjaxRenderer.

The AjaxRenderer get's the action's output and transforms it into a String that will be used to the Ajax request output. For a example, Mentawai comes with an AjaxRenderer that get's a bean collection from the action's output and creates a XML structure with the data of the beans. Other example, Mentawai has a AjaxRenderer that get a Map from the action's output and creates a XML structure based on the Map's data. (Obs.: Those AjaxRenderers uses a XML structure for data representation because normally a Ajax request has a XML response parsed by a brower built-in JavaScriptXML DOM parser)
The generated String from the AjaxRenderer will be used by the AjaxConsequence as the output of the Ajax request.
The sequence of the Ajax request in Mentawai is:

1 - The client (browser, normally) make a Ajax request to the web application, in a url mapped by a Mentawai action.
2 - The Controller servlet threat's the Ajax request as a normal HTTP request and forward it to a action, as always.
3 - The action process the Ajax request as a normal HTTP request, generating the Output, as always.
4 - The AjaxRenderer analizes the generated Output and create a String response based on that. The String response content's dependes on the AjaxRenderer implementation and the action's output.
5 - The AjaxConsequence gets the response String created by the AjaxRenderer and use it as the output of the Ajax request.

Actually, all you need to do in your Java application is to configure your action's consequence to use the AjaxConsequence and one implementation of the AjaxRenderer interface. Then, in the view tier, you'll have use JavaScript to create a Ajax request (XMLHttpRequest), requesting and URL mapped by an action that has a AjaxConsequence configurated and use JavaScript to process the response generated by the AjaxConsequence.

Mentawai comes with some AjaxRenderers, but if you need something that is not covered by this classes, you can easily develop your own (or request us to do this in the forum). Mentawai does not have a client-side library for Ajax (maybe in the next versions...), so you can use your favorite client-side ajax library.

Bellow, there is an example of how use Mentawai+Ajax to asyncronously feed a <select>:

The ApplicationManager

import org.mentawai.ajax.AjaxConsequence;
import org.mentawai.ajax.renders.MapAjaxRender;
import org.mentawai.core.ActionConfig;

public class ApplicationManager extends org.mentawai.core.ApplicationManager {
    public void loadActions() {
        ActionConfig actionConfig = new ActionConfig("/getNames",SomeAction.class);
        actionConfig.addConsequence(SomeAction.SUCCESS, new AjaxConsequence(new MapAjaxRender()));
        addActionConfig(actionConfig); 
    }
}
                

And example of action:

import java.util.HashMap;
import java.util.Map;

import org.mentawai.ajax.renders.MapAjaxRender;
import org.mentawai.core.BaseAction;

public class SomeAction extends BaseAction {

	public String execute() throws Exception {
        Map map = new HashMap();
        map.put("1","Rubem Azenha");
        map.put("2","Sérgio Oliveira");
        map.put("3","Fernando Boaglio");
        map.put("4","Davi Luan Carneiro");
        output.setValue(AjaxConsequence.KEY, map);
        return SUCCESS;
        
	}

}
                

And the page:

<html>
<head>
<title>Mentawai + AJAX - Asyncronous JavaScript and XML</title>
</head>
<body>
<script>
var req;
var comp;

function createAjaxRequest() {
    var ajaxReq;
    if (window.XMLHttpRequest) { // Non-IE browsers
       ajaxReq = new XMLHttpRequest();
   }
    else if (window.ActiveXObject) { // IE
            ajaxReq = new ActiveXObject("Microsoft.XMLHTTP");
        }
    return ajaxReq;
}

function getValues() {
   var url = "getNames.mtw";
   comp = document.getElementById("list");
   req = createAjaxRequest();
   if (window.XMLHttpRequest) { // Non-IE browsers
     req.onreadystatechange = processStateChange;
    try {
        
           req.open("GET", url, true);
       } catch (e) { 
           alert(e);
       }
       req.send(null);
    } 
    else if (window.ActiveXObject) { // IE
       if (req) {
           req.onreadystatechange = processStateChange;
            req.open("GET", url, true);
            req.send();
        }
    }  
    
}
    
function processStateChange() {
    if (req.readyState == 4) {
        if (req.status == 200) { // OK response
            var xml = req.responseXML;
            var entries = xml.getElementsByTagName("entry");
            for (var i = 0; i < entries.length; i++) {
                var entry = entries[i];
                 comp.options[comp.length] = new Option(entry.firstChild.nodeValue,entry.getAttribute("key"));
            } 
        }
        else {
           alert("Problem: " + req.statusText);
       } 
    }
}
</script>
<br>
Click here to asynchronously put some values on the select bellow: <input type="button" value="OK" onClick="getValues();" />
<br>
<select id="list">
</select>
</body>
</html>