Pages

User friendly date with Codeigniter and MySQL

Tuesday, March 6, 2012
When we deal with the date in Codeigniter and MySQL, there is a little problem that MySQL accepts dates only in the ISO-recommended format YYYY-MM-DD. I want users to be able to enter and show dates in a more familiar format.

At here if you use a text box to enter the date, user can do many mistake. So the best way to handle the input of dates is with separate fields using HTML <select> elements or combo boxes. Let's start our project.

Requirement

CodeIgniter

Step 1: Configuration

Open application/config/database.php, and change the following database configuration to fit your mysql configuration.

$config['hostname'] = “localhost”;

$config['username'] = “myusername”;

$config['password'] = “mypassword”;

$config['database'] = “mydatabase”;

$config['dbdriver'] = “mysql”;

Then open application/config/config.php

$config['base_url'] = ‘http://localhost/ci_date’;

Open application/config/autoload.php

$autoload['libraries'] = array('database’);

and

$autoload['helper'] = array(‘url’,'form’);

Open application/config/routes.php, change default controller to user controller as we’ll create later on this tutorial.

$route['default_controller'] = ‘home’;

Creating Database table

We need to create a table in our database. Import following SQL statement via phpMyAdmin or any other MySQL tool.

CREATE TABLE `user` (
  `id` int(20) NOT NULL auto_increment,
  `name` varchar(50) NOT NULL,
  `dob` date NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

Designing our date input view files

Now let's create our design file. Create a blank document in the views folder (application -> views) and name it home_view.php, in the document add all the following code.

<!DOCTYPE html>
<html lang="en">
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 <title><?php echo (isset($title)) ? $title : "My CI Site" ?> </title>
 <link rel="stylesheet" type="text/css" href="<?php echo base_url();?>/css/style.css" />
</head>
<body>
 <div id="wrapper">
 <div id="content">
 <?php $this->load->helper('dob'); ?>
 <div class="reg_form">
 <?php echo validation_errors('<p class="error">'); ?>
 <?php echo form_open("home/add_data"); ?>
  <p>
   <label for="user_name">User Name:</label>
   <input type="text" id="user_name" name="user_name" value="" />
  </p>
  <p>
   <label>Birthday:</label>
   <select name="month"><option value="0">Month:</option><?php echo generate_options(1,12,'callback_month')?></select>
   <select name="day"><option value="0">Day:</option><?php echo generate_options(1,31)?></select>
   <select name="year"><option value="0">Year:</option><?php echo generate_options(2011,1900)?></select>
  </p>
  <p>
   <input type="submit" class="greenButton" value="Submit" />
  </p>
 <?php echo form_close(); ?>
</div><!--<div class="reg_form">-->
</div><!--<div id="content">-->
<div id="footer">
 &copy; 2011 <a href="http://tutsforweb.blogspot.com/">TutsforWeb</a> All Rights Reserved.
</div><!-- <div class="footer">-->
</div><!--<div id="wrapper">-->
</body>
</html>

In this file, you will notice that dob helper. It is not CI built in helper. This helper is created by learning this tutorial.

Our birthday field will be look like below:

Creating dob_helper

Following code is our dob_helper.php. Create a blank document in the helpers floder (application -> helpers) and name it dob_helper.php, in the document add all the following code.

<?php
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
if ( ! function_exists('generate_options'))
{
 function generate_options($from,$to,$callback=false)
 {
  $reverse=false;
  if($from>$to)
  {
   $tmp=$from;
   $from=$to;
   $to=$tmp;
   $reverse=true;
  }
  $return_string=array();
  for($i=$from;$i<=$to;$i++)
  {
   $return_string[]='
   <option value="'.$i.'">'.($callback?$callback($i):$i).'</option>
   ';
  }
  if($reverse)
  {
   $return_string=array_reverse($return_string);
  }
  return join('',$return_string);
 }
}
if ( ! function_exists('callback_month'))
{
 function callback_month($month)
 {
  return date('F',mktime(0,0,0,$month,1));
 }
}
if ( ! function_exists('format_date'))
{
 function format_date($date)
 {
  $parts = explode('-',$date);
  return date('F j, Y',mktime(0,0,0,$parts[1],$parts[2],$parts[0]));
 }
}
?>

In our helper, it has three functions generate_options(), callback_month() and format_date(). We used the generate_options() and callback_month() in our html select element to fill the data. The format_date() function will be used when we display the date to the user.

Check the input date in the Controller

Create a blank document in the controllers folder (application -> controllers) and name it home.php, in the document add all the following code.

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Home extends CI_Controller{
 public function __construct(){
  parent::__construct();
  $this->load->model('home_model');
 }
 public function index()
 {
  $this->load->view('home_view');
 }
 public function add_data()
 {
  $_POST['dob'] = $_POST['year'].'-'.$_POST['month'].'-'.$_POST['day'];
  $this->load->library('form_validation');
  // field name, error message, validation rules
  $this->form_validation->set_rules('user_name', 'User Name', 'trim|required|min_length[4]|xss_clean');
  $this->form_validation->set_rules('dob', 'Date of Birth', 'callback_date_check');
  if ($this->form_validation->run() == FALSE)
  {
   $this->load->view('home_view');
  }
  else
  {
   $this->home_model->save_data();
   $this->show();
  }
 }
 public function date_check()
 {
  if(checkdate($_POST['month'],$_POST['day'],$_POST['year']))
  {
   return TRUE;
  }
  else
  {
   $this->form_validation->set_message('date_check', 'Correct you Date of Birth.');
   return FALSE;
  }
 }
 public function show()
 {
  $this->load->model('home_model');
  $data['query']=$this->home_model->get_all();
  $this->load->view('dateshow_view',$data);
 }
}
?>

In our add_data() function, firstly we set the $_POST['dob'] from our three html select boxes by concatenating '-' between them. Now our dob post data is ready to add to the MySQL database. There's just one problem with this: someone might enter an invalid date, such as February 31 or September 31. So, it's a good idea to use the PHP checkdate() function to make sure the date is valid.

So when we set the form validation rule for our dob (Date of Birth) field, we use the callback function as date_check(). You can easily follow our date_check() function I think.

Showing our user friendly date

Let's create our dateshow_view.php to test the format_date() function from our dob_helper. Create a blank document in the views folder (application -> views) and name it dateshow_view.php, in the document add all the following code.

<!DOCTYPE html>
<html lang="en">
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 <title><?php echo (isset($title)) ? $title : "My CI Site" ?> </title>
 <link rel="stylesheet" type="text/css" href="<?php echo base_url();?>/css/style.css" />
</head>
<body>
<div id="wrapper">
<div id="content">
 <?php $this->load->helper('dob'); ?>
 <?php    foreach($query as $row){?>
  <p>
  <?php
   echo format_date($row->dob);
  ?>
  </p>
 <?php }?>
</div>
</div>
</body>
</html>

It will display our date as below picture.


Creating Model

Our model is very simple. Create a blank document in the models folder (application -> models) and name it home_model.php, in the document add all the following code.

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Home_model extends CI_Model {
 public function __construct()
 {
  parent::__construct();
 }
 public function save_data()
 {
  $data=array(
   'name'=>$this->input->post('user_name'),
   'dob'=>$this->input->post('dob')
  );
  $this->db->insert('user',$data);
 }
 function get_all()
 {
  $query=$this->db->get('user');
  return $query->result();
 }
}

Designing with CSS

Create a folder named css in your root directory and save following code as a sytle.css.

@charset "utf-8";
/* CSS Document */
body{
 background-color:#FFF;
 font-family:Monaco,Consolas,'Lucida Grande','Lucida Console';
 font-size:16px;
 text-shadow:rgba(0,0,0,0.01) 0 0 0;
}
#wrapper{
 width:960px;
 margin:0 auto;
}
#content{
 width:960px;
 margin:5px;
 float:left;
}
/************************************************/
.reg_form{
 width:460px;
 padding:20px;
 margin:0 auto;
 border:3px solid #DFDFDF;
 background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#cbd4e5));
 background: -moz-linear-gradient(top,  #fff,  #cbd4e5);
 filter:  progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff', endColorstr='#cbd4e5');
}
.reg_form p{
 width: 300px;
 clear: left;
 margin: 0;
 padding: 5px 0 8px 0;
 padding-left: 155px;
 border-top: 1px dashed gray;
 height: 1%;
}
.reg_form label{
 font-weight: bold;
 float: left;
 margin-left: -155px;
 width: 150px;
}
input,select{
 padding:3px;
 color:#333333;
 border:1px solid #96A6C5;
 margin-top:2px;
 width:180px;
 font-size:11px;
}
select{
 width:auto;
 padding:2px;
}
.greenButton{
 width:auto;
 margin:10px 0 0 2px;
 padding:3px 4px 3px 4px;
 color:white;
 background-color:#589d39;
 outline:none;
 border:1px solid #006600;
 font-weight:bold;
}
.greenButton:active{
 background-color:#006600;
 padding:4px 3px 2px 5px;
}

Download Source Code

6 comments:

  1. Hi,

    Thanks for the time saved.

    I've just added the translation for the month in french.

    ----------------------------------------
    function callback_month($month){
    $mois_fr = Array("", "janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre");
    return $mois_fr[$month];
    }
    ----------------------------------------

    ReplyDelete
  2. Would you please tell me how to place code in blogspot.com. As like you added code in your blog.

    ReplyDelete
  3. Here you can learn a lot. Cool that I hit this blog.

    Ariel

    ReplyDelete
  4. Superb blog I visit this blog it's extremely marvelous. Interestingly, in this blog content composed plainly and justifiable. The substance of data is exceptionally instructive.
    oracle fusion financials classroom training
    Workday HCM Online Training
    Oracle Fusion Financials Online Training
    Oracle Fusion HCM Online Training
    Oracle Fusion SCM Online Training
    Oracle Fusion HCM Classroom Training

    ReplyDelete