Basic AJAX and JSON Requests Using MooTools' Request.HTML and Request.JSON
By Ryan Florence, published 2010-01-02
Part of the issue MooTools for Beginners (1.2).
The best designs aren’t noticed. When you walk through an airport and get exactly where you intend to go, you don’t realize and attribute it to an excellent way-finding design. Such is the case with the web. Ajax and JSON requests can subtly enhance the usability of a site, where the user doesn’t notice the site “thinking” as much as all the page loads of yesteryear.
MooTools ajax couldn’t be easier. In this tutorial we’ll explore the various ways to make a request with the excellent MooTools javascript framework with php as the server language (simply for demonstration).
And for the last time, ajax does not mean fancy effects–those are simply called fancy effects. Also I have something against the term ajax, I think it has to do with the old TV show Full House. I’ll be calling it xhr
(xmlHTTPRequest).
Setting up
- Latest copy of mootools
- A web server with php, can’t make xhr requests without a web server.
- Two files, an
index.html
file and_page.php
file.
Download this demo and put it in your htdocs
, public_html
or wherever you’ve got php running to follow along, if you’d like.
index.php
<body>
<p>
<a href="#page" id="link">Load a new page</a>
</p>
<div id="page_container">
<!-- requests will be placed here -->
</div>
</body>
_page.php
<!-- _page.php -->
<h2>I was requested</h2>
The simplest xhr request ever, Element.load
$('page_container').load('_page.php');
That syntax is about as self-explanatory as it gets.
Note: In MooTools we wrap most of our application code inside of a domready event as shown below, but I’m going to leave that out of all the code snippets as shown above.
window.addEvent('domready',function(){
// code goes here
$('link').addEvent('click',function(){
$('page_container').load('_page.php');
});
});
So if all you need to do is simply load the response into an element, just use the Element.load shortcut and you’re done.
Multiple Links with load
Let’s say we’re requesting some record in a database or array. Your index.php
and _page.php
may look something like:
index.php
<ul id="roomates">
<li><a href="_page.php?id=0">Dane Hansen</a></li>
<li><a href="_page.php?id=1">Will Fisher</a></li>
<li><a href="_page.php?id=2">Riley Florence</a></li>
<li><a href="_page.php?id=3">Neil Aboshamaa</a></li>
</ul>
<div id="roomate_info"></div>
_page.php
<?php
$college_roomates = Array(
'dane' => Array('Dane','Hansen','Attorney'),
'will' => Array('Will','Fisher','Attorney'),
'neil' => Array('Neil','Aboshamaa','Looking for investors cause he knows this guy...'),
'riley' => Array('Riley','Florence','Designer')
);
$roomate = $college_roomates[$_GET['id']];
?>
<h3><?php echo $roomate[0] ?> <?php echo $roomate[1] ?> - <?php echo $roomate[2] ?></h3>
Okay, so we’ve got a list of anchor tags all requesting _page.php
but with different IDs. Here’s how we could do this with load
:
$$('#roomates a').each(function(element,index){
element.addEvent('click',function(event){
event.stop();
$('roomate_info').load(element.get('href'));
});
});
Line 1 we select the a
tags inside of the roomates
list and then get an array of elements, each
iterates over the array, and the function passes in the anchor element and it’s index. Then we add the click event listener and update roomate_info
when clicked. Normally, the browser would change locations to the link, but we grabbed the event and stopped it.
This is actually decent looking code. But we can’t do much else with it. Maybe we want to send along &ajax=1
in our url query, or fade a loading indicator into view while the request is being made so the user gets some positive feedback (again, try the search on this site.) Let’s look at using a request object instead to give us more control.
The Request Class
MooTools is not really about shortcuts, it’s about object oriented tools to create really modular code. So instead of load
let’s actually create an instance of the Request class that does exactly what our last bit of code did. First we’ll just instantiate a new Request.HTML object.
var req = new Request.HTML({
url: '_page.php',
method: 'get',
update: 'page_container'
});
This won’t do anything yet. It just sets it up and stores it in a variable called req
. You can see the options we’ve passed into it (url
, method
, update
). Request has tons of options, we won’t go over all of them but you can check them out at the MooTools docs here. You’ll also notice we’re using Request.HTML
instead of just Request
, that’s because it’s got some handy features to deal with the response when you’re requesting HTML pages (and gives us the update
option.)
Let’s add an event to our link and then send the request using the appropriately named send
method:
$('link').addEvent('click',function(event){
event.stop();
req.send();
});
Wait a sec, that’s just for our single link. Let’s make this work for multiple links and at the same time put a loading indicator in there.
Multiple links with Request.HTML
var updateMe = $('roomate_info');
var req = new Request.HTML({
method: 'get',
update: updateMe,
onRequest: function(){
updateMe.set('html','<h3>Loading ...</h3>');
}
});
$$('#roomates a').each(function(element, index){
element.addEvent('click',function(event){
event.stop();
req.options.url = element.get('href');
req.send();
});
});
This is great because:
- The user gets some feedback after clicking the link that the browser is thinking.
- We have just one request object, rather than creating a new request each time a link is clicked (like before.)
Tracking requests already made
We actually have the ability to make the browser work even less, how you ask? Easy, store if the page has been requested yet. If it has, simply use what the browser already got a while ago. More on element storage here.
var updateMe = $('roomate_info');
var clickedAnchor = false; // going to track the last clicked link element
var req = new Request.HTML({
method: 'get',
update: updateMe,
onRequest: function(){
updateMe.set('html','<h3>Loading ...</h3>');
},
onSuccess: function(tree, elements, html){
// after the request is made, store the responseHTML with the anchor
clickedAnchor.store('response', html);
}
});
$$('#roomates a').each(function(element, index){
element.addEvent('click',function(event){
event.stop();
var storedResponse = element.retrieve('response');
if(storedResponse){
// we've already requested this, so we can just
// retrieve the content from the element
updateMe.set('html', storedResponse);
} else {
// haven't sent the request yet, so send it
clickedAnchor = element;
req.options.url = element.get('href');
req.send();
}
});
});
JSON Requests
I have to keep myself from using JSON for everything, it’s that useful. Request.JSON
handles the response and decodes it into a native javascript object. Let’s change our _page.php
.
page.php
<?php
$college_roomates = Array(
'dane' => Array('Dane','Hansen','Attorney'),
'will' => Array('Will','Fisher','Attorney'),
'neil' => Array('Neil','Aboshamaa','Looking for investors cause he knows this guy...'),
'riley' => Array('Riley','Florence','Designer')
);
if(isset($_POST['json'])){
echo json_encode($college_roomates);
exit;
}
$roomate = $college_roomates[$_GET['id']];
?>
<h3><?php echo $roomate[0] ?> <?php echo $roomate[1] ?> - <?php echo $roomate[2] ?></h3>
Then the javascript isn’t much different than before, except we’re going to be using the data
option to tell the page we’re asking for the JSON. You can store pretty much anything you want in the data
option that, in this case, will all be in $_POST
.
var jsonReq = new Request.JSON({
url: '_page.php',
method: 'post',
data: {
json: 'yes'
},
onComplete: function(response){
console.log(response);
}
});
$('get_json').addEvent('click',function(){
jsonReq.send();
});
And we need to add the button to the index page:
<button id="get_json">Get JSON and log to console</button>
Check out the console when you click the button. It’s a native javascript object that you can do all sorts of stuff with. Some of the things I’ve used it for:
- Checking the database for valid user names, etc. If the response is
1
then it’s available, if not, do something else. - Updating database information
- Keeping users logged in to the site (resetting tokens, cookies, etc)
- XHR form submissions
- Server-side form validation that feels client-side
- Retrieving database information for use in javascript
- Auto complete data
- Any interaction with the server that doesn’t warrant html to be returned and rendered.
There are unlimited uses. Really, any interaction with the server can be done via JSON Requests. It’s so handy at times I worry I use it too much!