Multi-Purpose CodeIgniter Forms

One aspect of CodeIgniter that I don’t like is the amount of view files that I have to create. Although I create folders to group relevant views, I’m always searching through files to find the view that I need. To reduce the amount of files that I need for a project, I usually create a single view file to handle both inserts and updates to a table. But I had to create a CodeIgniter Helper function in order to make it work.

The Model

First I create the model. For brevity, I’m only showing the relevant methods (select, insert and update).

class mTours extends Model {
    	function mTours() {
    		parent::Model();
	}
 
       function getTour($id) {
		$data = array();
		$options = array('tour_id' => $id);
		$Q = $this->db->getwhere('tours', $options, 1);
		if ($Q->num_rows() > 0) {
			$data = $Q->row_array();	
		}	
 
		$Q->free_result();
		return $data;
	}
 
        function addTour(){
		$d = date('Y-m-d H:i:s');
	        $data = array('tour_date' => db_clean($_POST['tour_date'],30),
				  'tour_type' => db_clean($_POST['tour_type'],20),
				  'locations' => $_POST['locations'],
		                  'tour_cost' => db_clean($_POST['tour_cost'],10),
		                  'tour_deposit' => db_clean($_POST['tour_deposit'],10),
				  'tour_includes' => $_POST['tour_includes'],
				  'mod_date' => $d
	         );
 
		$this->db->insert('tours',$data);
	}
 
	function updateTour(){
		$d = date('Y-m-d H:i:s');
	        $data = array('tour_date' => db_clean($_POST['tour_date'],30),
				  'tour_type' => db_clean($_POST['tour_type'],20),
				  'locations' => $_POST['locations'],
		                  'tour_cost' => db_clean($_POST['tour_cost'],10),
		                  'tour_deposit' => db_clean($_POST['tour_deposit'],10),
				  'tour_includes' => $_POST['tour_includes'],
				  'mod_date' => $d
		 );
		$this->db->where('tour_id',id_clean($_POST['id']));
		$this->db->update('tours',$data);	
	}
}

The Helper

Next, I’m going to update a custom CodeIgniter Helper that I created. The helper is used to retrieve table columns from any MySQL database table. I’m updating it so that it will return an array of column names with empty values.

function getTableColumns($tName, $empty=false) {
	$data = array();
	$CI=& get_instance();
	$sql = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = '$tName'";
	$Q = $CI->db->query($sql);
	if ($Q->num_rows() > 0) {
		foreach ($Q->result_array() as $row){
                       // if $empty is true, return associative array with empty values
                       // else return array containing column names
			if ($empty) {
	         	        $data[$row['COLUMN_NAME']] = '';
			} else {
				$data[] = $row['COLUMN_NAME'];
			} 	
                }
	}	
	$Q->free_result();
	return $data;	
}

I named the helper ‘mysql_table_helper’ and placed it in application/helpers. I am also auto loading the helper so that I don’t have to load it every time I need it (application/config/autoload.php).

The Controller

Next I create a create method and an edit method in my controller. In both of these methods, I create a variable that stores the type of update (create or edit). This variable is sent to the view with the other variables.

function tour_create() {
	if ($this->input->post('tour_date')){
  		$this->mTours->addTour();
  		$this->session->set_flashdata('message','Tour added');
  		redirect('admin/dashboard','refresh');
  	} else {
		$data['title'] = "Add Tour";
		$data['page'] = 'admin/tour_create_edit';
		$data['updType'] = 'create';
                // get the column names from the tours table using the helper
		$data['tour'] = getTableColumns('tours, true);
		$data['navList'] = $this->mainMenu;
		$data['tIncludes'] = $this->mTours->getTourInclude();
		$this->load->vars($data);
		$this->load->view('main');    
	}
}
 
function tour_edit($id=0) {
	if ($this->input->post('tour_date')){
  		$this->mTours->updateTour();
  		$this->session->set_flashdata('message','Tour updated');
  		redirect('admin/dashboard','refresh');
  	} else {
		$data['title'] = "Update Tour";
		$data['page'] = 'admin/tour_create_edit';
		$data['navList'] = $this->mainMenu;
		$data['updType'] = 'edit';
		$data['tour'] = $this->mTours->getTour($id);
		$data['tIncludes'] = $this->mTours->getTourInclude();
		$this->load->vars($data);
		$this->load->view('main');    
	}
}

Both the tour_create and tour_edit methods use the same view file.

$data['page'] = 'admin/tour_create_edit';

There are three primary differences between the tour_create and tour_edit methods:

  1. The tour_create method uses the getTableColumns helper function. The tour_edit method does not need to use the function because it is querying actual data.
  2. The tour_edit method is passed an argument, the value of which is the tour_id. The tour_id is required for the updateTour method in the mTours model.
    //mTours - updateTour methodd
    $this->db->where('tour_id',id_clean($_POST['id']));
  3. The updType variable tells the view which controller method to call.
    // tour_create
    $data['updType'] = 'create';
    // tour_edit
    $data['updType'] = 'edit';

The View

Our view, tour_create_edit.php, displays the form and calls the relevant controller method based upon the value of the updType variable.

<?php echo $this->tinyMce;?>
<h3><?php echo $title;?></h3>
 
<?php
// if the updType is equal to 'create', call the <strong>tour_create</strong> method, else call the <strong>tour_edit</strong> method
echo ($updType == 'create') ? form_open('admin/tour_create') : form_open('admin/tour_edit');
echo "<p><label for='tour_date'>Tour Date</label><br/>";
$data = array('name'=>'tour_date','id'=>'tour_date','size'=>20, 'value' => $tour['tour_date']);
echo form_input($data) ."</p>";
 
echo "<p><label for='tour_type'>Tour Type</label><br/>";
$data = array('arrow' => 'arrow', 'sponsored' => 'Sponsored');
echo form_dropdown('tour_type', $data) . "</p>";
 
echo "<p><label for='tour_cost'>Tour Cost</label><br/>";
$data = array('name'=>'tour_cost','id'=>'tour_cost','size'=>10, 'value' => $tour['tour_cost']);
echo form_input($data) ."</p>";
 
echo "<p><label for='tour_deposit'>Tour Deposit</label><br/>";
$data = array('name'=>'tour_deposit','id'=>'tour_deposit','size'=>10, 'value' => $tour['tour_deposit']);
echo form_input($data) ."</p>";
 
echo "<p><label for='locations'>Locations</label><br/>";
$data = array('name'=>'locations','id'=>'locations','rows'=>5, 'cols'=>'40', 'value' => $tour['locations']);
echo form_textarea($data) ."</p>";
 
echo "<p><label for='tour_includes'>Trip Includes</label><br/>";
$data = array('name'=>'tour_includes','id'=>'tour_includes','rows'=>5, 'cols'=>'40', 'value' => $tour['tour_includes']);
echo form_textarea($data) ."</p>";
 
// if updType equals edit, create hidden field that contains the tour_id
if ($updType == 'edit') {
	echo form_hidden('id',$tour['tour_id']);
}
$cap = ($updType == 'create') ? 'add tour' : 'update tour';
echo form_submit('submit',$cap);
echo form_close();
 
echo anchor('admin/dashboard', 'Back To Dashboard');
?>

Note: If I did not use the helper function to create an empty array, the application would receive an error:
A PHP Error was encountered
Severity: Notice
Message: Undefined variable: tour

Note: To view information on using TinyMCE with CodeIgniter see my post: CodeIgniter and TinyMCE.

In the tour_create_edit view, I tell CodeIgniter to create a form action based upon the value of updType.

echo ($updType == 'create') ? form_open('admin/tour_create') : form_open('admin/tour_edit');

The form action calls the relevant controller method. The updateTourmethod in the mTours model requires the tour_id in order to update an existing record. The view passes the tour_id as a hidden field.

if ($updType == 'edit') {
	echo form_hidden('id',$tour['tour_id']);
}

The tour_edit method in the controller calls the getTour method in the mTours model. This data is passed to the view.

$data['tour'] = $this->mTours->getTour($id);

The view can now use this data to display the relevant values for each field in the form. If value does not exist, then nothing is displayed in the field

$data = array('name'=>'tour_date','id'=>'tour_date','size'=>20, <strong>'value' => $tour['tour_date']</strong>);

That’s it. With the use of a simple helper function, I now only need one CodeIgniter view file to insert and update a record.

Be Sociable, Share!

Checkout My New Site - T-shirts For Geeks