Codeigniter form with Ajax

codeigniterCodeIgniter (CI), the PHP framework, has evolved towards version 2.0. The main version feature is scripts are being rewritten in PHP5 (helpers in former verisons were still in PHP4). This framework is lightweight and helps developers work faster. This post will tackle :

  • the framework configuration
  • the building of a login form with an Ajax request

1. CI installation

First download CodeIgniter 2.0 source from http://codeigniter.com/ (follow the link ‘Get Source’). Unzip that file and place it in your local /www/ directory. Loading the page http://localhost:8888/codeigniter/ will display the following page (I’ve installed it on my local machine and the default port for MAMP (Mac Apache-Mysql-PHP solution) is 8888. If you’re working under windows with a WAMP solution, http://localhost/codeigniter/ will do the trick) :

Open CodeIgniter in your browser

The page which is displayed is /application/views/welcome_message.php which is loaded via /application/controllers/welcome.php. This controller contains the class Welcome which is defined as the default controller in /application/config/routes.php. If you want to reach that controller in the URL, you’ll have to use http://localhost:8888/codeigniter/index.php/welcome. In that URL, index.php is the CI front controller which is to be found in the root directory /codeigniter/. You will have to keep that index.php file but you can take it away from the URL :

  • open /config/config.php and change the index_page to $config['index_page'] = “”;
  • then add a .htaccess file to the root of your project /codeigniter/ :

SetEnv MAGIC_QUOTES 0
SetEnv PHP_VER 5
Options +FollowSymlinks -MultiViews
RewriteEngine On
DirectoryIndex index.php
RewriteCond %{REQUEST_URI} ^system.*
RewriteRule (.*) index.php?/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(index\.php|images|robots\.txt|css)
RewriteRule (.*) index.php?/$1 [L]

In doing so, you’ll activate Apache Mod_rewrite and be able to load http://localhost:8888/codeigniter/index.php/welcome via http://localhost:8888/codeigniter/welcome.

Now, we’ll open some CodeIgniter configuration files to setup database connection and other stuff :

1.1. Codeigniter file structure : the MVC framework

If you take a look at the /www/codeigniter/ directory, you’ll see the following structure :

Codeigniter file structure

As you can see, Codeigniter is an MVC framework. The /application/ directory is the directory of your project files :

  • the /controllers/ directory contains controller files (receive input and make requests to the models)
  • the /models/ directory contains model files (requests to the database)
  • the /views/ directory contains view files (Html, formulaires,…)

Another important directory is /system/ : it contains all the Codeigniter core files (libraries, helpers,…)

Codeigniter config files are stored in the /config/ directory. Let’s open /config/config.php and change the following lines :

  • Base site url : $config['base_url'] = “http://localhost:8888/codeigniter/”;
  • Index file : $config['index_page'] = “”;

Then open /config/database.php to set up the database connection information :

  • $db['default']['hostname'] = ‘localhost’;
  • $db['default']['username'] = ‘root’;
  • $db['default']['password'] = ‘root’;
  • $db['default']['database'] = ‘codeigniter’;

and change the values to suit your own configuration.

We also need to autoload CI core libraries and helpers that will automatically load at each request and make our work much easier. Open /config/autoload.php and change the following lines :

  • $autoload['libraries'] = array(‘database’); //to automatically load CI’s database library (class for database connection)
  • $autoload['helper'] = array(‘url’,'form’); //to automatically load CI’s url and form helpers (classes for url handling and form building)

1.2. Setting up the database

Now, turn to your browser and load PhpMyAdmin : http://localhost:8888/phpmyadmin/ and execute the following queries :
CREATE DATABASE codeigniter;
CREATE TABLE users ( user_ID int unsigned not null auto_increment primary key, username varchar(20), password varchar(32) );

2. Creating the login form

The Html form we will create is rather easy. Codeigniter is made of core libraries and helpers that you’ll find in the /system/ directory. We’ve autoloaded the form helper to help us build our form.

So, create the file in /application/views/v_login.php (I use the ‘v_’ prefix to make the difference between views (‘v_’), models (‘m_’) and controller (‘c_’) files) :
<!DOCTYPE html>
<html lang="fr">
<head>
<title>Login</title>
<meta name="robots" content="index,follow" />
<meta name="description" content="Login" />
<meta http-equiv="Content-type" content="text/html; charset=iso8859-1" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<style type="text/css">
p { margin: 0; padding: 0; }
input.textbox { width: 120px;color: #777;height: 18px;padding: 2px;border: 1px solid #E5E5E5;vertical-align: top; }
input.button { width: auto;height: 22px;padding: 2px 5px;vertical-align: top; }
</style>
</head>
<body>
<?php
echo form_open('login');
?>
<div id="message">
</div>
<p>
<label for'username'>username</label>
<?=form_input(array('name'=>'email','value'=>'','class'=>'username textbox','style'=>'width:150px;'))?><br />
</p>
<p>
<label for'password'>password</label>
<?=form_password(array('name'=>'password','value'=>'','class'=>'password textbox'))?><br />
</p>
<p>
<?='<br />'.form_submit('submit','Login','id="submit"')?>
</p>
<?=form_close("\n")?>
</body>
</html>

As you can see, the form helper is here at work with methods like ‘form_open()’, ‘form_close()’ that will automatically generate <form> and </form> tags.

The <head> of this view already contains the link to the Jquery.js file we will need to have our Ajax script work properly : <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>

The “Message” div will be used to display the Ajax Response.

The Html form is now ready but we still need to build the controller class that will load that view.

3. Creating the login controller

Create the file /application/controllers/c_login.php.
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class C_login extends CI_Controller {
function __construct() {
parent::__construct();
$this->load->library('form_validation');
}
function index() {
$this->load->view('v_login');
}
}
/* End of file c_login.php */
/* Location: ./application/controllers/c_login.php */

The constructor of this controller loads the form_validation library which we will use to check the content of the posted fields. We’ll also use the url helper to build the url of the form action attribute.

In order to load this controller in a browser, you’ll simply have to call http://localhost:8888/codeigniter/c_login

The default method that will be called is the index() method that simply loads the form view (v_login.php)

To make this controller your default controller and be able to reach it via http://localhost:8888/codeigniter/, you’ll have to change /application/config/routes.php and set the default controller to c_login:

$route['default_controller'] = “c_login”;

If you want that controller to be reached via http://localhost:8888/codeigniter/login, simply edit /application/config/routes.php and add :

$route['login'] = ‘c_login’;

4. Creating the Ajax request

Let’s go back to our /views/v_login.php.

We’ll write a short javascript that will :

  • bypass the form submit to the login controller via http
  • get the values of the necessary fields in javascript
  • pass these values to the controller via an Ajax request

Just add the following code just before the </head> tag :

<script type="application/javascript">
$(document).ready(function() {
$('#submit').click(function() {
var form_data = {
username : $('.username').val(),
password : $('.password').val(),
ajax : '1'
};
$.ajax({
url: "<?php echo site_url('login/ajax_check'); ?>",
type: 'POST',
async : false,
data: form_data,
success: function(msg) {
$('#message').html(msg);
}
});
return false;
});
});
</script>

Jquery allows us to execute a function once the DOM document has been loaded : $(document).ready

The script will be triggered once the submit button is hit : $(‘#submit’).click : the # sign identifies the “id” attribute of an element of the page (the submit button in this case).

Then we store the posted variables (username and password) in the form_data array. This array also contains the “ajax” key with value “1″. This value will be checked in the controller.

Then comes the $.ajax request which contains an array :

  • url : the url the request must be sent to
  • type : variables are posted to the controller
  • data : the array of variables passed to the controller
  • success : what the script must do if the request is successful : the controller will return a piece of text that will be displayed in the $(‘#message’) div.

return : false; is used to prevent the script from actually reaching the form action url through http when the submit button is clicked.

In this example, the url “login/ajax_check” will only be reachable if you add the following to the /config/routes.php :

$route['login/ajax_check'] = 'c_login/ajax_check';

5. Creating the ajax_check controller method

We will then create a second controller method called ajax_check() to check the variables posted through Ajax.

function ajax_check() {
if($this->input->post('ajax') == '1') {
$this->form_validation->set_rules('username', 'username', 'trim|required|xss_clean');
$this->form_validation->set_rules('password', 'password', 'trim|required|xss_clean');
$this->form_validation->set_message('required', 'Please fill in the fields');
if($this->form_validation->run() == FALSE) {
echo validation_errors();
} else {
echo 'login successful';
}
}
}

The script checks if the ajax variable posted equals to “1″. If so, we use the Codeigniter form_validation library to check the required fields and echo the validation errors if necessary.

6. Playing the script

Open Firefox and install Firebug addon if not yet installed : https://addons.mozilla.org/fr/firefox/addon/firebug/

This addon will let you check the different steps of the ajax request. Launch Firebug via Menu Tools / Firebug. Then activate the console to be able to check what’s happening in your page :

Firebug - console

Open the login page : http://localhost:8888/codeigniter/login and click “submit”. You’ll see the following Ajax response :

Ajax response

7. Checking the database : using models

We’ll change c_login controller method ajax_check and load a model to check if the user exists in the database :
function ajax_check() {
if($this->input->post('ajax') == '1') {
$this->form_validation->set_rules('username', 'username', 'trim|required|xss_clean');
$this->form_validation->set_rules('password', 'password', 'trim|required|xss_clean');
$this->form_validation->set_message('required', 'Please fill in the fields');
if($this->form_validation->run() == FALSE) {
echo validation_errors();
} else {
$this->load->model('m_access');
$user = $this->m_access->check_user($this->input->post('username'),$this->input->post('password'));
if($user == '1') {
echo 'login successful';
} else {
echo 'unknown user';
}
}
}
}

We’ve loaded a model called m_access, then we call the method check_user and send it the username and password variables.

You’ll then create the model itself in /application/models/m_access.php :
<?
class M_access extends CI_Model {
public function check_user($username,$password) {
$this->query = $this->db->select('COUNT(*)')->from('users')->where(array('username'=>$username,'password'=>$password))->limit(1)->get();
return $this->query->row_array();
}
}

You can download the necessary files : codeigniter

JQuery to show or hide form fields

JQueryJQuery is a javascript library that has revolutionized the way we can trigger client-side events. Having Javascript interact with HTML has become much easier and also more standard thanks to that framework.

In this post, I’ll tackle displaying form elements thanks to JQuery.

The key to JQuery lies in the <head> of your document. JQuery.js is a javascript file that contains the main functions. I’ve downloaded the minified version (72 Ko) from JQuery.com

<script type=”text/javascript” src=”./js/jquery-1.4.2.min.js”></script>

Display form fields on change select box value :

My first exercise is to let JQuery identify the select box value which is selected to display or hide extra form fields.

So, here’s my HTML form with 3 elements : 2 select boxes (id = type and id = choice) and a textarea (id = text) :

<form>
<select id=”type”><option>choose a type</option><option value=”1″>type 1</option><option value=”2″>type 2</option><option value=”3″>type 3</option></select><br />
<select id=”choice”><option>choice</option><option value=”1″>choice 1</option><option value=”2″>choice 2</option><option value=”3″>choice 3</option></select><br />
<textarea id=”text”></textarea>
</form>

Displaying such a form in a browser will display the 3 elements (2 select boxes and the textarea).

My objective is to show the first select box only (id = type) and to only display the second select box and the textarea if the third item of the first select box is selected.

So, in the <head> of my document, I’ll add a script that starts with the $(document).ready() function. This allows you to load as many functions as necessary as soon as the DOM is loaded and before the loading of the contents of your page. You could store this function inside a separate .js file and the power of JQuery is you won’t have to add anything to your HTML content :

<script language=”javascript”>//<![CDATA[

$(document).ready(function() {

$("#choice").hide();

$("#text").hide();

$("#type").change(function() {

if ( $("#type").val() == "3"){

$("#choice").show();

$("#text").show();

}

else{

$("#choice").hide();

$("#text").hide();

}

});

if ( $("#type").val() == "3"){

$("#choice").show();

$("#text").show();

}

$("#choice").change(function() {

var val = $("#choice").val();

$("#text").append(val + "\n");

});

});

//]]></script>

So you’ll easily guess what that script does : the “choice” select box and the textarea are set to hidden by default. JQuery here accesses the form element thanks to their id (#choice, for example). If the value of the “type” select box is set to 3, the other form elements are shown, if not, they’re hidden. Then if the value of the “choice” select box is changed, its value will be added to the textarea content.

 

Display form fields on change checkbox :

My second exercise is to let JQuery identify if a checkbox is ticked to display or hide form fields.

I’ll add a checkbox to my HTML form :

 

<form>
<input type=”checkbox” id=”check” />
<select id=”type”><option>choose a type</option><option value=”1″>type 1</option><option value=”2″>type 2</option><option value=”3″>type 3</option></select><br />
<select id=”choice”><option>choice</option><option value=”1″>choice 1</option><option value=”2″>choice 2</option><option value=”3″>choice 3</option></select><br />
<textarea id=”text”></textarea>
</form>

Next I’ll modify the script in my <head> tag to handle checkbox ticking (or not) :

<script language=”javascript”>//<![CDATA[

$(document).ready(function() {

$("#choice").hide();

$("#text").hide();

$("#type").change(function() {

if ( $("#type").val() == "3"){

$("#choice").show();

$("#text").show();

}

else{

$("#choice").hide();

$("#text").hide();

}

});

if ( $("#type").val() == "3"){

$("#choice").show();

$("#text").show();

}

$("#check").change(function() {

if($("#check").attr("checked")) {

$("#choice").show();

$("#text").show();

}

else{

$("#choice").hide();

$("#text").hide();

}

});

$("#choice").change(function() {

var val = $("#choice").val();

$("#text").append(val + "\n");

});

});

//]]></script>

With JQuery, you’ll also have some “scriptaculous” effects with show and hide actions :

$(“#choice”).show(“slow”);

will slowly display your form element.

You could also use a numeric value :

$(“#choice”).hide(200);

Webliography :

JQuery.com

JQuery event tracker for Google Analytics

Google Analytics is the ultimate tool if you want to get some trustworthy statistics about the hits on your website. It will easily give you statistics about your visitors, about the sources of traffic to your site and about pageviews.

This is fairly useful if you want general information about who comes to your site and what pages are viewed most.

Another useful tool is the event tracker which is accessible under Menu Content / Event Tracker.

Asynchronous Tracking

In order to finalize your Google Analytics Account, you need to copy-paste Google tracking code snippet to the bottom of your pages (just before the </body> tag).

Google Analytics suggests you erase that code at the end of your page and replace it by an asynchronous tracking code to be pasted in the <head> of your document :

<script type=”text/javascript”>
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXX-X']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement(‘script’); ga.type = ‘text/javascript’; ga.async = true;
ga.src = (‘https:’ == document.location.protocol ? ‘https://ssl’ : ‘http://www’) + ‘.google-analytics.com/ga.js’;
var s = document.getElementsByTagName(‘script’)[0]; s.parentNode.insertBefore(ga, s);
})();
</script>

You’ll have to replace the account ID (UA-XXXXX-X) by your own.

This code snippet will work as well as the old one and will not wait for the end of the script to be loaded since it’s in the <head> of the document.

In order to track events on your page, let’s say clicks on links, I’ll add a function to this script :

 

<script type=”text/javascript”>
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXX-X']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement(‘script’); ga.type = ‘text/javascript’; ga.async = true;
ga.src = (‘https:’ == document.location.protocol ? ‘https://ssl’ : ‘http://www’) + ‘.google-analytics.com/ga.js’;
var s = document.getElementsByTagName(‘script’)[0]; s.parentNode.insertBefore(ga, s);
})();

 

function trackClick(text,link,title) {
_gaq.push(['_trackEvent',text,link,title]);
};
</script>

That trackClick function will send information to Google Analytics’s event tracker. The attributes that I pass are :

  • a category : the text of the link
  • an action : the link address
  • label : the title attribute of the link

So, if my page contains a link like :

<a href=”./products.php” title=”Choose one of our products”>Our products</a>

the script will send the following pieces of information if the link is clicked :

  • a category : Our products
  • an action : ./products.php
  • label : Choose one of our products

In order to do so, I’ll invoke JQuery. So first, I’ll have to download jquery.js, upload it to my web server and add the following to the <head> of my document to have JQuery work :

<script type=”text/javascript” src=”jquery.js”></script>

Then I’ll add another script that will trigger my trackClick function when a link is clicked :
<script type=”text/javascript”>
$(document).ready(function(){
$(‘a’).click(function(){
var eventCategory = $(this).attr(‘title’);
var trackURL = $(this).attr(‘href’);
var text = $(this).text();
trackClick(text,trackURL,eventCategory);
});
});
</script>

You’ll have to wait a while for Google Analytics to display your events but once it’s done, it can give you the following results :

Event tracking Google Analytics

You can browse the data per categories, per actions or per labels.

Webliography

Google’s Event Tracking Guide

Asynchronous Tracking