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

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.

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.

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:

  1. The user gets some feedback after clicking the link that the browser is thinking.
  2. 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:

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!

MooTools used in this article

Hi, I'm Ryan!

Location:
South Jordan, UT
Github:
rpflorence
Twitter:
ryanflorence
Freenode:
rpflo

About Me

I'm a front-end web developer from Salt Lake City, Utah and have been creating websites since the early 90's. I like making awesome user experiences and leaving behind maintainable code. I'm active in the JavaScript community writing plugins, contributing to popular JavaScript libraries, speaking at conferences & meet-ups, and writing about it on the web. I work as the JavaScript guy at Instructure.