A simple AJAX tutorial for use with Codeigniter 2 with CSRF enabled.
The original tutorial was taken from Andrew Rowland’s website but I’ve updated it so that it works with Codeigniter 2 with csrf enabled.
I’m using Codeigniter 2.02, jQuery 1.6.2 and jQuery.cookie.js
Everything else is a normal install.
This simple demo app will show you how to create an AJAX request to add an unordered list to an list item, with fallback if javascript has been disabled.
Create a controller called world.php. Also autoload (or mannually)
$autoload['helper'] = array('url', 'html');
in the config/autoload.php
and set the csrf to TRUE in the config/config.php
$config['csrf_protection'] = TRUE;
also (which I always do) set the encryption key. You can get auto generated keys from http://randomkeygen.com/
$config['encryption_key'] = 'c83d2mQ2N43P11BoyziaJY5o99gWi7Xo';
Naturally this data would be stored in a database but to keep it simple I'm using hard coded arrays
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); class World extends CI_Controller { private $data = array(); function __construct() { parent::__construct(); } function index($continent = null) { $this->data['continents'] = array( 1 => 'Europe', 2 => 'Africa', 3 => 'North America', 4 => 'The moon', ); if(isset($continent)) { $this->data['countries'] = $this->list_countries($continent); } $this->load->view('template',$this->data); } function list_countries($continent) { $continents = array( 1 => array('UK', 'France', 'Spain', 'Germany'), 2 => array('South Africa', 'Zimbabwe', 'Cameroon'), 3 => array('USA', 'Canada'), 4 => array(), ); if(isset($_POST['ajax'])) { echo json_encode($continents[$continent]); } else { return $continents[$continent]; } } }
Next create the html page template.php
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"/> <title>World</title> </head> <body> <?php print heading('The World Goes Here',1) ?> <ul id="continents"> <?php foreach($continents as $id => $continent) : ?> <li id="id_<?php print $id?>"><a href="/world/index/<?php print $id ?>" title="<?php print $continent ?>"><?php print $continent ?></a></li> <?php if($id == $this->uri->segment(3)) : ?> <?php print ul($countries); ?> <?php endif; ?> <?php endforeach; ?> </ul> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.js" ></script> <script src="/js/jquery.cookie.js" ></script> <script src="/js/main.js" ></script> </body> </html>
You’ll notice that I’m using the helper url and html. I just love them and they can save so much time particularly if you’re getting arrays back from the database.
Now for the js
$(function() { $('#continents li').click(function(){ This splits out the id number from the id var cont_id = this.id.split('_'); Important - This gets the cookie value which is passed through to the controller. Codeigniter 2 checks this value automatically so you don't need to do anything else var cct = $.cookie('ci_csrf_token') ? $.cookie('ci_csrf_token') : null; Simple fall back to a normal page reload if the user has cookies switched off, otherwise the page will not display the countries and you'll get a 500 error if(!cct) { return true; } $('#continents > ul').slideUp('slow'); if($('#id_' + cont_id[1]).children('ul').length == 0) { $.post('/world/list_countries/' + cont_id[1], {ajax:'true', 'ci_csrf_token':cct}, function(data) { unorderedlist = $('<ul/>').css({display : 'none'}); $.each(data, function(i, country){ $('<li/>').text(country).appendTo(unorderedlist); }); unorderedlist.appendTo('#id_'+cont_id[1]); unorderedlist.slideDown('slow'); }, 'json'); } else { if($('#id_' + cont_id[1]).children('ul').length > 0) { $('#id_' + cont_id[1] + ' ul').slideDown('slow'); } } return false; }); });