MCMS, XML Web Service and AJAX Data Collection
Recently I found myself having to create a system by which I could capture some user data from a web application using some unobtrusive javascript. I settled on a system using jQuery, jQueryUI and an XML Web Service. The basic idea is quite simple: the user clicks a hyperlink, this triggers a form to pop up dialog (using jQueryUI) and when the data is submitted, a call is made by AJAX to the XML Web Service.
An added complication for me was that the site I needed this functionality on was running in MCMS 2002, which means that I needed to use C# 1.1 - which doesn't have the in-built AJAX capability of later versions. The site uses a number of templates that I was loath to go in and edit individually to load each the javascript frameworks I needed. I might have been tempted if this wasn't just a pilot system with no guarantee that the system would eventually find wide scale adoption. I therefore opted for a system of 'lazy loading'. That is, the javascript frameworks are loaded only on those pages where they are needed, and only when required. All the templates on the site already referenced a 'main.js' file so I wrote my lazy-load scripts into this file. Firstly, I worked out how I wanted to implement this from the consumer perspective. I didn't want the content editors to have to do anything more complicated that modifying a simple HTML hyperlink. Therefore the link in the HTML is to be implemented as one of the two links below depending on whether other javascript needed to be executed in addition to my jQueryUI dialog. Non-javascript users will not get the onclick event fired and the link continues to function as a normal hyperlink.
click here
click here
The lazy loading function for the jQuery framework file is shown below. Note how the last line in the DoStuff method returns false. This ensures that a hyperlink does not 'activate' and allows the javascript to execute. I also built in a 'timeout' loop so that multiple attempts can be made to load the scripts needed. In the example below the script tries to initialise jQuery (JQueryScriptInit) 4 times a second up to a pre-set maximum attempts. If it fails it just runs ContinueWithOtherStuff which could be an alternative to the popup dialog system.
//DoStuff: function to kick off the initialisation and load of the popup dialog
function DoStuff(file, func)
{
if(func!=null) func(); //execute the other functions
clearTimeout(FormTimeout);
var scriptsInitialised = JQueryScriptInit();
if(scriptsInitialised)
{
//implement the functionality here
}
else
{
if(FormLoadAttempts<=MaxDownloadFormLoadAttempts)
{
FormTimeout = setTimeout(function() { DoStuff(file); }, 250);
}
else
ContinueWithOtherStuff(file,null);
}
return false; //prevent the href of the download link from running
}
//JQueryScriptInit: functions to load the jQuery and jQueryUI framework file
function JQueryScriptInit()
{
//initialise jQuery
if(JQueryInit())
{
//we have jQuery!
//alert($('#accessHelp').text());
//use jQuery to get the ui file
if(JQueryUIInit()) {
JQueryCookie();
JQueryUICss();
return true;
}
else
return false;
}
else
return false;
}
function JQueryInit()
{
if(!self.jQuery)
{
var head = document.getElementsByTagName("head")[0];
//get the script
var scriptitem = document.createElement("script");
scriptitem.id = "jquery";
scriptitem.src = "/htaweb/scripts/jquery-1.3.2.js";
scriptitem.type = "text/javascript";
head.appendChild(scriptitem);
var maxcheckattempts = 100;
var checks = 1;
var jqueryloaded = true;
while (!self.jQuery)
{
if(checks>maxcheckattempts)
{
jqueryloaded = false;
//alert('Timed out');
break;
}
setTimeout(function(){}, 100);
checks++;
}
return jqueryloaded;
}
else
{
//alert('jQuery already loaded');
return true;
}
}
Once jQuery is loaded, I could easily use it to load the other scripts and files. I load the jQueryUI and the required CSS as follows:
function JQueryUIInit()
{
if(!$.ui)
{
var uiscript = '