CodeIgniter and Ajax
Using jQuery to manipulate data returned by controller method
I’ve been asked to create a dashboard for many devices across our network. To display real-time information on each component, I’m thinking of using Web services, and AJAX. Like most aspects of coding, using a framework to do all the heavy lifting, rather than developing your own, is a sensible approach.
So today I took a look at jQuery, a JavaScript framework. I have to admit, I’m pretty impressed. It did not take me long to come up with some example code, that degrades well when JavaScript is disabled in the browser.
My example app lists continents. Clicking on a continent will return a list of countries in that continent.
Create a CodeIgniter controller and save as world.php:
<?php class World extends Controller { function World() { parent::Controller(); } function index($continent = NULL) { // Set continents data. In a real application we // would obtain this from a database via a model. $data['continents'] = array( 1 => 'Europe', 2 => 'Africa', 3 => 'North America', ); // If a non-Ajax continent selection is made, call the // list_countries method, and set countries data. if (isset($continent)) { $data['countries'] = $this->list_countries($continent); } // Load world view. $this->load->view('world_view', $data); } function list_countries($continent) { // Generated countries data. As before, this would be // obtained from a model. $continents = array( 1 => array('UK', 'France', 'Germany'), 2 => array('South Africa', 'Zimbabwe', 'Cameroon'), 3 => array('USA', 'Canada'), ); // Decide whether to return JSON data, or an array, // depending if $_POST['ajax'] is set. if (isset($_POST['ajax'])) { echo json_encode($continents[$continent]); } else { return $continents[$continent]; } } } ?>Create a view and save as world_view.php:
<html> <head> <title>World example</title> <script type="text/javascript" src="/jquery.js"></script> <script type="text/javascript"> function list_countries(id) { $('li > ul').slideUp('slow'); if ($('#id_' + id).children('ul').length == 0) { $.post('/world/list_countries/' + id, {ajax:'true'}, function(data){ unorderedlist = $('<ul/>').css('display', 'none'); $.each(data, function(i, country){ $('<li/>').text(country).appendTo(unorderedlist); }); unorderedlist.appendTo('#id_' + id); unorderedlist.slideDown('slow'); }, 'json'); } else { $('#id_' + id + ' > ul').slideDown('slow'); } return false; } </script> </head> <body> <ul> <?php foreach($continents as $id => $name):?> <li id="id_<?=$id;?>"><a onclick="return list_countries(<?=$id;?>);" href="<?=site_url("/world/index/$id");?>" title="Show countries in <?=$name;?>"><?=$name;?></a> <?php if ($id == $this->uri->segment(3)):?> <ul> <?php foreach($countries as $country):?> <li><?=$country;?></a></li> <?php endforeach;?> </ul></li> <?php endif;?> <?php endforeach;?> </ul> </body> </html>
Take a look here to see how this looks.
I just noticed that my ISP only has PHP4 installed. If this is the case for you, you will have to alter the controller to get this to work. Change the line:
echo json_encode($continents[$continent]);to:
echo '["' . implode('","', $continents[$continent]) . '"]';
Obviously this solution does not scale well for more complex data structures. I would advise using a JSON serializer library of some description. You could also create a view for the JSON structures, and pass data to that. This would actually be a sensible approach, as you would have complete control over the output.
Comments
Incredible, thanks a lot for this… it is exactly what I was looking for +invisible props.
Thank you for posting this. It was really simple to understand, and straight to the point.
Looks interesting, and easy to follow. Reading is a bit frustrating on a 22” monitor, given the code lumps are only showing about a 1/4 to a 1/3 of the width (much left & right scrolling required). Flippin’ pixel-based stylesheets!
wonderful application!
thanks for sharing this ajax!
You have to load the url helper in the controller constructor like so:
$this->load->helper(‘url’); or you will get an undefined function error site url();
Very nice post thanks
dear Very very thankxxxxxx
Please comment on this article. Constructive criticism, ideas, and corrections welcome. In fact, it does not even have to constructive. Feel free to take the p*ss.