Hi all.
First of all, the credits:
- Thanks to Angus Turnbull, from TwinHelix Designs, for creating the HTMLHttpRequest v1.0beta3 script that let us use AJAX and calmly sleep at night knowing it degrades to normal links and our sites are still usable even with JS off. Thanks Angus, for the help too.
- Thanks to PaulGregory, who pointed me to the right direction when I reached a dead end in my thoughts, avoiding me to reinvent the wheel when appropiate tools where available. Without your advice I’d never ended this thing. This leads to the next credit...
- Thanks to Susan Ottwell for the TemplateSwitcher plugin. I’ve to say you’re a factory of useful code. This plugin is exactly what I need to put the pieces all together. Thanks, thanks, thanks: it would took months for me to write a similar piece of code (mmm... not so english, I think).
- No credit but shame on my provider who restored a 3-days-old backup on my domain where I was 1 line of code away from the goal, forcing me to do the test from the start (and restoring 3 days of work in a morning, by the way). >:(
- ADDED: Thanks to heliotrope who pointed out (and corrected) the way you add the alternative template to the link: he added the ability to use the REL attribute.
- Thanks to MODx and to all who work in-with-after-under-around-etc it. I don’t think MODx is a CMS, nor a Framework.
MODx is a magic wand.
Ok. Let’s start the explanation.
Goals
This tutorial explain how to implement AJAX Dinamic Content in MODx.
Those who are deeply in the AJAX world will recognize this tecnique to be
Hijax,
progressive enhancement.
For those more distant from AJAX this means that first of all your site works as it is expected to do
without AJAX and JavaScript, and AJAX is an enhancement that adds something to your page. Your site will work perfectly even if the user browser has JS turned off, because it beautifully degrades to a normal page-by-page navigation.
You can use my last work like a
demo. Sorry it’s in Italian. The AJAXified links are the six box containing a link. Try it with JS on, then turn it off and restart from
prodottiajax.html.
So the goal is to create a page with links that load content from other pages in a target area (a div) if the JS is on, and if JS is off act like a normal (non-AJAX) site.
Requirements
You’ll need:
- The script HTMLHttpRequest v1.0beta3 from TwinHelix. To preserve credit I link only the page: you can simply download it from there, and watch some demo, too (in fact this script can do even more complicated things). From the .zip file (which is comprensive of demo files) you can delete all but htmlhttprequest.js and htmlhttprequest.html (well, you don’t need this because I’ll write the code you find in it so you can copy and paste from here, but better keep it, you can check differences with your template).
- The Template Switcher plugin from Susan Ottwell.
It’s important you remember we have to create a navigational structure like a normal site, and AJAX is only an enhancing.
Let’s assume, for the tutorial, that you’re going to upload the script to
manager/media/script/ajax/htmlhttprequest.js.
When you’ve gathered all you need, time to start working.
1. Understand how htmlhttprequest 1.0beta3 works.
From the comments in the code:
Any link with a class="loadinto-IdOfTarget" attribute will load into an element with an id="IdOfTarget" attribute. It’s that easy!
So if we have:
<ul>
<li><a class="loadinto-thisIsMyTarget" href="content/introduction.html">Introduction</a></li>
<li><a class="loadinto-thisIsMyTarget" href="content/usage.html">Usage Notes</a></li>
<li><a class="loadinto-thisIsMyTarget" href="content/advantages.html">Advantages</a></li>
</ul>
<div id="thisIsMyTarget">
<p>When one of the above link is clicked this paragraph will be replaced by the content of the target page</p>
</div>
The strenght of this script is (when JS is on) that it thinks about catching the links and updating the content, so we can write simple links that work when JavaScript is off.
I thinks is so easy we don’t need to stay here more time.
2. Modify and upload htmlhttprequest.js and create TemplateSwitcher plugin.
Open htmlhttprequest.js and search for this string:
RemoteFileLoader.prototype.loadInto=function(uri,destId){
Right after "{" add:
document.getElementById(destId).innerHTML='<img src="manager/media/script/ajax/waiting.gif" />';
This will add a fancy "waiting.gif" animating icon while the browser load the content of the external file. You can find plenty on
http://www.ajaxload.info/. Upload the image to the path indicated, or change the path. You can add html code there, like "Loading" with a span or what you want. Play with it.
When you’ve done, save and upload htmlhttprequest.js.
Then install
TemplateSwitcher (you’ll find more info about installing it on its page in the repository).
3. Create 2 templates
To do the trick we need 2 templates.
Create a normal template, it will be the template we assign to the pages so include all you need to present your page to the visitor.
In the <head></head> section, add:
<script src="manager/media/script/ajax/htmlhttprequest.js" type="text/javascript"></script>
<script type="text/javascript">//<![CDATA[
var docClickLoader = new RemoteFileLoader('docClickLoader');
function loadInto(src, destId, evt) // Function modified by Heliotrope to accept REL attr - kudo
{
template = 'template='+ src.rel;
url = src.href;
src.href = (url.indexOf('?')>0)? url + '&' + template: url + '?' + template ;
var ok = docClickLoader.loadInto(src.href || src.getAttribute('href'), destId);
if (ok) cancelEvent(evt);
}; // End of the modified by Heliotrope function - kudo
function toggleInto(src, destId, evt)
{
var dest = document.getElementById(destId);
if (!dest.contentLoaded)
{
var ok = docClickLoader.loadInto(src.href || src.getAttribute('href'), destId);
if (ok) dest.contentLoaded = true;
}
cancelEvent(evt);
if (!dest.toggleState)
{
src.innerHTML = 'Close: ' + src.innerHTML;
dest.style.display = 'block';
dest.toggleState = 1;
}
else
{
src.innerHTML = src.innerHTML.replace(/^Close: /, '');
dest.style.display = 'none';
dest.toggleState = 0;
}
};
addEvent(document, 'click', function(evt)
{
evt = evt || window.event;
if (evt.which > 1 || evt.button > 1) return;
var src = evt.target || evt.srcElement;
if (src.nodeType && src.nodeType != 1) src = src.parentNode;
while (src)
{
var srcName = (src.nodeName||src.tagName||'').toLowerCase();
if (srcName == 'a' && src.className && src.className.match(/^(load|toggle)into-(.+)$/))
{
if (RegExp.$1 == 'load') return loadInto(src, RegExp.$2, evt);
if (RegExp.$1 == 'toggle') return toggleInto(src, RegExp.$2, evt);
}
src = src.parentNode;
}
}, 1);
//]]></script>
This is the uncommented code from the header of the htmlhttprequest.html file,
plus a line (search for "kudo") which adds "?template=OnlyContent" to the link with the LoadInto function corrected by Heliotrope which gives us the ability to select the template for the loaded content by adding a REL attribute to the link in the shape of "
rel="NameOfTemplate"". This will trigger TemplateSwitcher and change the template.
Why I need to change the template?
Well, remember that if the user is surfing by AJAX we have a full page yet, with header, menus, footer. We need to change only the content, so we need a template with only the things we whant to change (let’s say pagetitle, etc).
Note 1: I’ve not done so much tests, but it seems to execute cached snippets only if they’re in a chunk. Because of the restore I didn’t deeper tests so make some try if it doesn’t seem to work.
You can name the secondary template like you want, but if it’s named other than OnlyContent you’ve to change the code. Search for "kudo".
Your links will have to look like this:
<a class="loadinto-thisIsMyTarget" rel="nameOfTemplateForContentOnly" href="my_link.html">
Make some try to find what you want in the dinamic loaded page, if you want chunks, tvs, snippets... you’re free

.
4. Remember to add the target div
Ok. Now, depending how you want to use AJAX, create a target div and give it a id. Put it in the first template, or in a specific page content, or where you want. It relies on the effect you want to achieve. You can have different target of different links on the same page, so you’ve nothing to stop you.
5. Fill with pages
Fill your pages. Remember that your structure of links have to work without JS and AJAX.
Ok, now you’re ready and you can start adding "
loadinto-idOfTarget" class to the links you want to load in the target div. Have fun here too, use it as DropMenu class, create a list of links, have fun I’ve told it.
Advice: start with 1 page cointaining the target div and a list of links to other pages to test. Then stop smiling like a child with a new toy (I know, I smiled in this way too) and start thinking what you can do with it.
Done

You’re site is AJAXified at no cost. Play with it, have fun. Remember to say thanks to the credited ones!
Bye
Info on compatibility (great) and other things on the htmlhttprequest page.
Correction n. 1: corrected the way to choose the template by adding the Heliotrope piece of script to use REL.