This article demonstrates how to create, with relative ease, an unobtrusive AJAX application with CodeIgniter and Mootools; it consists of two major parts: server-side (arranging views and setting up a controller) and client-side (writing a small script to handle AJAX calls and DOM manipulations).

For demonstration, I’ve created a simple application that will store user submitted messages in a session and display them in a list, as user enters them (could be used as a shout box if messages were stored in a database). You can view the application here.

Server-side

First of all we have to set up the views. There are going to be 2 views all in all: one serves as container having all of the elements necessary to render the complete page (served by default), and the other is a view of the message box alone (served as a part of main container, or separately if requested by AJAX script).

Here is the default view, message.php:

<!-- header -->

<div id="container">

	<div id="message-form-container">
		<!-- message form -->
	</div>

	<div id="message-box">
		<?php require_once('message_list.php'); ?>
	</div>

</div>

<!-- footer -->


Here is the view for message list only, message_list.php:

<?php if($messages) : ?>
	<ol>
	<?php foreach($messages as $key => $message) : ?>
		<li><p><?php echo $message; ?></p></li>
	<?php endforeach; ?>
	</ol>
<?php else : ?>
	<p>You havent's submitted a message yet.</p>
<?php endif; ?>

As you can see, the idea is really simple – render the complete view by default and if there is an AJAX call we’ll only render a part of that view (the part of the page that requires updates), in our case message_list.php.

Take a look at the related controller method:

public function message($transport = null){
	//load session library
	if(!$this->session) $this->load->library('session');

	//check if user posted any messages during session
	//messages array has more than 5 messages, destroy it
	if($this->session->userdata('messages') && count($this->session->userdata('messages')) < 5) {
		$messages = $this->session->userdata('messages');
	} else {
		$messages = array();
	}

	if($_POST){
		//check for message and strip any html
		if(isset($_POST['message']) && !empty($_POST['message'])){
			$message = strip_tags($_POST['message']);
		} else {
			$message = 'Message was not entered.';
		}

		//append current message to messages array
		$messages[] = $message;

		//save the array in session
		$this->session->set_userdata('messages', $messages);
	}

	//assign template data
	$this->data['messages'] = $messages;

	//output the template based on transport type
	if($transport == 'ajax') {
		$this->render('message_list');
	} else {
		$this->render('message');
	}

}

Client Side

Now that we have everything working without JavaScript, it’s time to introduce AJAX to the application. As you have probably inferred from the article’s title, I’m going to use Mootools in this application. The approach shown above, however, allows you to use just about any JS framework with AJAX capability, such as jQuery or Prototype, for example.

Here is what the script looks like:

var Site = {

	start: function(){
		if($('message-box') && $('message-form')) Site.messageBox();
	},

	messageBox: function(){

		//attach onSubmit event to the message form
		$('message-form').onsubmit = function(){

			//init key variables
			var url = '<?php echo site_url('messagebox/message'); ?>' + '/ajax';
			var messageBox = $('message-box');

			//disable submit button until the message is posted
			$('submit').setProperty('disabled', 'true');
			//signal the transition
			new Fx.Style(messageBox, 'opacity').set(0.2);

			//AJAX request, note what happens onComplete
			new Ajax(url, {
				method: 'post',
				onComplete: function(request){
					new Fx.Style(messageBox, 'opacity').start(0.2,1);
					$('message').setProperty('value', '');
					$('submit').removeProperty('disabled');
				},
				update: messageBox,
				postBody: $('message-form')
			}).request();

			return false;
		}

	}

};
window.addEvent('domready', Site.start);

As you can see the script is pretty straight forward: if user submits form, collect the data and pass it to messagebox controller with an additional parameter (‘ajax’), so that the controller knows that we only want message_list.php template and not the whole page. Upon response, replace message-list element with freshly rendered one.

Some notable steps include disabling submit button to prevent flood, as well as signaling user when work is being done and when it has been completed, by changing opacity. The later one can be achieved with the use of other techniques, but since the page is not reloading, it is essential to notify a user of the events taking place on the page.


3 Responses to “Unobtrusive AJAX with CodeIgniter and Mootools”