There is an awesome (imo) PHP class that is helpful in auto-generating forms with client side (jquery) and server side (php) validation. My words cannot do it justice, so an excerpt from the the author, Stefan Gabos:

Zebra_Form is a PHP class that simplifies the process of creating and validating HTML forms. Its object-oriented structure promotes rapid HTML forms development and encourages developers to write clean and easily maintainable code. It frees the developers from the repetitive task of writing the code for validating forms by offering powerful built-in client-side and server-side validation.

I was using Zebra_Form a lot recently, actually, you can see my bug fix accredits and comments under the pseudo-name ‘Jack Ryan’ (I had have a Tom Clancy fascination…). Even more recently, I’ve been hooked on phonics with CodeIgniter (and sometimes have an affair with Bonfire).

If you look at the built in form validation in CodeIgniter 2.0, it is actually well put together. Unfortunately, it does not offer anything near the capabilities of Zebra_Form, which out of the box, is far more aesthetically pleasing. What I’m going to share is how I incorporated Zebra_Form in CodeIgniter while best preserving the MVC framework. Let’s get started.

1. Download the latest version of Zebra_Form (I’m using 2.7)
– Note: Stefan rolls out updates constantly! It’s almost hard to keep up as he is really quick to respond to bugs. These updates should not affect this tutorial but if you have a problem let me know.

2. Rename the folder to ‘zebra’ and put it in your root/application/libraries/ directory. So you should be able to reach your files at root/application/libraries/zebra/Zebra_Form.php.
– Note: I named the library class Zebra, but now that I think about it, it would have made sense to rename the folder ‘zebra_form’ instead but you can do as you please.

3. Create a new library called ‘Zebra.php’ and you can start out with the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
< ?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); 
 
// include the Zebra_Form class
require_once "application/libraries/zebra/Zebra_Form.php";
 
class Zebra {
 
	var $zebraForm;
 
    public function __construct()
    {
	log_message('debug', 'Initializing Zebra library');
 
	// get an instance of CodeIgniter
	$CI =& get_instance();
 
        // load the form helper class
        // This is your own class, but works just like the CI form helper except
        // instead of the functions to create a form, you created the form already.
        $CI->load->helper('zebra_form');    # application/helpers/zebra_form_helper.php
    }
 
    // Call by your controller to get which form to create
    // I do this because my website creates different types of forms (i.e., login, contact, etc)
    public function create_form($form_name)
    {
	log_message('info', 'Creating '.$form_name);
 
	// call a helper function to create the form
	return $this->zebraForm = $form_name();
 
        // above we dynamically called the function by $form_name
        // as you can tell naming is important so you have to make sure
        // you name the function 'funtion form_name' in your helper
        // and call this from your controller as '$this->zebra->create_form('form_name')'
        // I will go over this later too.
    }
}
 
/* End of file Zebra.php */
?>

That’s the Zebra library!! Now, onto the helper class!

4. Create a file in application/helpers/ called ‘zebra_form_helper.php’

5. Add the following code to make your form! If you are not familiar with creating forms with Zebra_Form, you should refer to the documentation. Right now, I’m going to make a simple Contact From.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
< ?php 	if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/*
 * Zebra_Form helper class
 *
 * Functions for creating individual forms
 */
 
 // Remember, this has to be the same name as what you call the form from the controller
 // $this->{zebra_library}->create_form('form_name');
 
function zf_contact() 
{
	// instantiate a Zebra_Form object
	$form = new Zebra_Form('contact_form');
 
	// necessary for CodeIgnition's CSRF!
	$CI = get_instance();    // if you make the $CI in Zebra.php global, you do not need a new instance
	$obj = $form->add('hidden', $CI->security->get_csrf_token_name(), $CI->security->get_csrf_hash());
	$obj->lock();
 
	// the label for the "first name"
	$form->add('label', 'label_contact_name', 'contact_name', 'Name:');
 
	// add the "first name" field
	// the "&" symbol is there so that $obj will be a reference to the object in PHP 4
	// for PHP 5+ there is no need for it
	$obj = $form->add('text', 'contact_name');
 
	// set rules
	$obj->set_rule(array(
 
		// error messages will be sent to a variable called "error", usable in custom templates
		'required'  =>  array('error', 'A name is required!'),
 
	));
 
	// "contact_email"
	$form->add('label', 'label_contact_email', 'contact_email', 'Email address:');
 
	$obj = $form->add('text', 'contact_email');
 
	$obj->set_rule(array(
 
		'required'  => array('error', 'Email is required!'),
		'email'     => array('error', 'Email address seems to be invalid!')
 
	));
 
	// attach a note to the email element
	$form->add('note', 'note_contact_email', 'contact_email', 'Please enter a valid email address.', array('style'=>'width:200px'));
 
	// "message"
	$form->add('label', 'label_message', 'message', 'Message:');
 
	$obj = $form->add('textarea', 'message');
 
	$obj->set_rule(array(
		'required' => array('error', 'Message is required!')
	));
 
	// "captcha"
	$form->add('captcha', 'captcha_image', 'captcha_code');
 
	$obj = $form->add('text', 'captcha_code');
 
	$form->add('note', 'note_captcha', 'captcha_code', 'You must enter the characters in black that stand
	out from the other characters. Not case sensitive.', array('style'=>'width: 200px'));
 
	$obj->set_rule(array(
		'captcha' => array('error', 'Characters from image entered incorrectly!')
	));
 
	// "ip"
	$obj = $form->add('hidden', 'ip', $_SERVER["REMOTE_ADDR"]);
	$obj->lock();
 
	// "submit"
	$form->add('submit', 'btnsubmit', 'Submit');
 
	#
	# we must return the form object so we can use it later to validate the form
	#
	
	return $form;
}
?>

Okay, so let’s review.
– We have our Zebra library
– We have our zebra_form_helper

Now let’s go to the controller!

6. I create a controller as such: application/controllers/site.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
< ?php
/**
 * Site Controller Class
 *
 * @package 	Default
 * @author  	Josh Tomaino
 */
class Site extends CI_Controller {
/**
	 *  Array containing all the error messages generated by the controller
	 *
	 *  @var    array
	 */
	var $error;		// It is no coincidence that THIS is the SAME name 
				// As the error variable that Zebra_Form creates.
 
	// ------------------------------------------------------------------------
 
	/**
	 * Constructor
	 *
	 * @access	public
	 */
	public function __construct()
	{
		log_message('info', 'Initialized Site controller');
 
		parent::__construct();
 
	}
 
	public function index()
	{
 
		$this->contact();		// since I have not set my default page to contact()
	}
 
	// ------------------------------------------------------------------------
 
	/**
	 * Contact
	 * 
	 * Load the 'contact us' page
	 *
	 * @access	public
	 */
	public function contact()
	{
		// define function global
 
		$email_sent = false;
 
		// load the Zebra library for the Zebra_Form framework
 
		$this->load->library('zebra');			# libraries/Zebra.php
		
		// create the contact from the helper class
		// gets the $form object that was returned from the helper
 
		$contact_form = $this->zebra->create_form('zf_contact');  # your form name!
		
		// if the form was submitted
 
		if($contact_form->validate())
		{
			// and the form was valid
 
			log_message('info', 'Contact form validated, sending results');
 
			// load the email library from CodeIgniter
 
			$this->load->library('email');
 
			// define mail parameters
 
			$this->email->from('sender@mail.com', 'Sender');	# from: Sender
			$this->email->to('recipient@mail.com');			# to: 	Customer Service Email 
			
			$this->email->subject('Contact Form);			# subj:	Contact Form
			$this->email->message(					# message
				"
					Email delivered by Contact Form.			\n\n
					From: 	".$this->input->post('contact_name')."		\n\n
					Email: 	".$this->input->post('contact_email')."		\n\n
					IP: 	".$this->input->post('ip')."			\n\n
					Message: 						\n\n
 
					".$this->input->post('message')
				);
 
			// if
			if( $this->email->send() )
			{
				// form submission sent
 
				log_message('info', 'Contact form submission was emailed to recipient@email.com');
 
				// let's remember the email was sent so we can tell the view
 
				$email_sent = true;
 
			} else {
 
				// could not send form submission
 
				log_message('info', 'Failed to send the form submission');
 
				// report the error to the user
 
				$this->error['mail_form'] = 'We failed to receive your inquiry! Please try again later.';
 
				$email_sent = false;	// unnecessary but good visual
			}
 
			// print email debugger to the logs, which I think is pretty useful.
 
			log_message('debug', $this->email->print_debugger());
 
		}
 
		// define data we want in our view
 
		$data = array(					# view data
			'page_title' 	=> 'Contact',		# head>title
			'contact_form'	=> $contact_form,	# pass contact form to view
			'error'		=> $this->error,	# errors that may have been recorded
			'email_sent'	=> $email_sent,		# tell view if email was sent or not
		);
 
		// show the view to the user
 
		$this->load->view('contact', $data);		# views/contact.php
	}
}
 
?>

Please note, btw that unless you are running a local mailserver you cannot successfully perform this function on your local machine. Try uploaded it to a web server or replace ($this->mail->send()) with ($email_sent = true) to see what would happen if it worked correctly (or false if it didn’t).

Now that we have our Controller, all that is left is our view.

7. I create a view as such: application/views/contact.php.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
< !DOCTYPE html>
<html lang="en">
	<head>
		<base href="<?php echo base_url(); 	# this is a habit i've been getting into ?>"> 
		<title>< ?php echo $page_title; ?></title>
	</base></head>
 
	<body>
 
		<div class="content">
 
			<h2>< ?php echo $page_title; ?></h2>
 
			<p>
				Your feedback and concerns are of the utmost importance to us.
			</p>
			<p>
				An asterisk (<span style="color:red">*</span>) indicates a required entry.
			</p>
			<br />
 
< ?php
			// if
			if($email_sent):
 
				// email was sent
?>
				<p style='font-weight:bold'>Thank you for your inquiry! We will get back to you as soon as possible.</p>
< ?php
			else:
 
				// email was not sent
 
				// maybe there were errors
 
				// if
				if( isset($error) ):
 
					// there were errors present
 
					foreach($error as $e): 		# show the errors
 
						// Server Side error messages in this form look really good! 
						// If you haven't used Zebra_Form before you'll be impressed
 
						// You can add your own error like we did 
						// $error['something'] = 'Error message text user sees!';
 
						// 'error' has to be 'error', that's for Zebra
						$contact_form->add_error('error', $e);
 
					endforeach;
 
				endif;
?>
 
				<div id="zebra_form">
< ?php
					// auto generate output, labels to the left of form elements
 
					$contact_form->render('*horizontal');	# this renders the form auto-magically!!
 
					// If you want to make your own template, you can!
					// Follow the instructions for making your own template
					// at the Zebra Form website. If you have problems though, 
					// let me know and I will add instructions for templates.
?>			
				</div> <!-- /ZebraForm -->	
< ?php
			endif;
?>
		</div> <!-- /Content -->
 
                <!-- load Zebra_Form's stylesheet file --> 
		<link rel="stylesheet" href="zebra/public/css/zebra_form.css" type="text/css"> 
		<!-- load jQuery --> 
		<script src="zebra/public/javascript/jquery.js" type="text/javascript"></script> 
		<!-- load Zebra_Form's JavaScript file --> 
		<script src="zebra/public/javascript/zebra_form.js" type="text/javascript"></script>
 
	</link></body>
</html>

There’s one more thing you have to do!

The captcha in Zebra_Form is generated by the process.php file. However, since we put the zebra library in our libraries folder, we do not have access to that file. If your captcha image appears to be broken, you need to put the following lines of code in a .htaccess file and put it in ‘zebra’ folder with ‘process.php’. This will give your code access to that one file:


Order Deny,Allow
Deny from All


Order Deny,Allow
Allow from All

— edit: the author of ZF actually advises putting the process.php near the root. Read here.

There you have it! A fully functional Zebra Form nearly seamlessly integrated into CodeIgniter. If you want the code, you can find all the files listed separately along with a zip file here:

http://public.newrandom.com/examples/codeigniter/zebra_form/

And the compressed zip file: