Ajax Custom Form Submission Mechanism
Consider the following basic html code snippet:
<form name="detailform" method="post"
action="../someURL?Action=ProcessSubmit">
<input type="submit" value="Start">
</form>
Clicking on the "Start" button will cause the browser to collect all the form controls <name,value> pairs between the form opening and closing tags surrounding the <input...> submit button tag and post them to the server at the URL indicated in the action property of the opening form tag. So far, so good. The only thing to notice here is that the data to submit collection mechanism is completely transparent for us and that this approach of submitting data inevitably reloads the window's content in the browser, replacing whatever it currently holds with the new html response from the server.
<form name="detailform" method="post"
action="../someURL?Action=ProcessSubmit">
<input type="submit" value="Start"
onclick="ajaxSubmit(this, 'DefaultAction')">
</form>
function ajaxSubmit(obj, urlAction) {
if(formSubmitValidation()) {
//some working variables -- cosmetics
var baseURL;
var formNode = getFormObj(obj);
var idx1Trim = formNode.action.indexOf("..");
var idx2Trim = formNode.action.indexOf("ProcessSubmit");
if (idx1Trim!=-1) { //IE7
baseURL = formNode.action.substring(2, idx2Trim) + urlAction;
} else { //FF
baseURL = formNode.action.substring(0, idx2Trim) + urlAction;
}
//adding custom calculated parameters: timestamp, ajax tag
params = (new Date()).getTime() + "&KindRequest=Ajax";
//the actual form parsing
baseURL = baseURL + "&" + parseDOMSubTree(formNode) + params
//posting the form
ajaxRequest(baseURL);
} else {
alert("Validation Problem");
}
}
function parseDOMSubTree(obj) {
var url = "";
for ( var i = 0; i < obj.childNodes.length; i++) {
// we know the root has a child. does it have a tagName?
if (obj.childNodes[i].tagName != null) {
// if no - never mind, just loop further. otherwise check it
switch (obj.childNodes[i].tagName.toUpperCase()) {
/*for form elements other than the ones below, you will have to
write the url append instruction youself :) */
case "TEXTAREA":
url = url + obj.childNodes[i].name + "="
+ escape(obj.childNodes[i].value) + "&";
break;
case "INPUT":
switch (obj.childNodes[i].type.toUpperCase()) {
case "HIDDEN":
case "TEXT":
url = url + obj.childNodes[i].name + "="
+ escape(obj.childNodes[i].value) + "&";
break;
default:
}
break;
default:
// we are checking some other kind of tag. just dive into it
url = url + parseDOMSubTree(obj.childNodes[i]);
}
}
}
return url;
}
And of course, last but not least, the ajax request call responsible for managing the client-server connection. Let's take a look at the code:
function ajaxRequest(url) {
var html = "";
/*
* important flag. we are loosing the asyn aspect but still are keeping the
* neat refresh part of the ajax tehcnology
*/
var asyn = false;
// Ignore cross-browser issues for the moment being
xmlhttp = false;
if ((window.XMLHttpRequest) && !(window.ActiveXObject)) {
// asyn = true;
xmlhttp = new XMLHttpRequest();
if (xmlhttp.overrideMimeType) {
xmlhttp.overrideMimeType('text/xml');
}
} else if (window.ActiveXObject) { // IE
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
}
}
}
if (!xmlhttp) {
alert('Cannot create XMLHTTP instance');
return false;
}
xmlhttp.open("GET", url, asyn);
// Set the callback function -- needed in case of asynchronic work :-)
// xmlhttp.onreadystatechange = function() {callbackAjaxRequest(xmlhttp); };
xmlhttp.send(null);
/*
* we are operating in synchrounous mode if this ever changes - just comment
* this line and uncomment the one above
*/
callbackAjaxRequest(xmlhttp);
}
The callback method looks like this:
function callbackAjaxRequest(xmlhttp) {
if (xmlhttp.readyState == 4) {
if (xmlhttp.status == 200) {
var xmldoc = xmlhttp.responseXML;
//from here on you can manage the resulting XML as you wish
var rootNode = xmldoc.getElementsByTagName('ajax.updates')
.item(0);
var responseStatus = rootNode.getAttribute("status");
var id;
if (responseStatus == "OK") {
for (i = 0; i <>
if (rootNode.childNodes.item(i).nodeName == "item") {
id = rootNode.childNodes.item(i).getAttribute("id");
document.getElementById(id).innerHTML = rootNode.childNodes
.item(i).firstChild.nodeValue;
}
}
} else {
// for FF/IE compatibility reasons -- the objects re
for (i = 0; i <>
if (rootNode.childNodes.item(i).nodeName == "item") {
html = rootNode.childNodes.item(i).firstChild.nodeValue;
}
}
/*this document.write doesn't work in IE if asyn mode above*/
document.write(html);
}
} else {
alert("Ajax Request Problem");
}
}
}
No comments:
Post a Comment