Transparent DatePicker with jquery

by agusti
We will create an extended Helper FormHelper, without Difficulty to add a calendar date picker style in jquery (http://www.kelvinluck.com/assets/jquery/datePicker/v2/demo/).
We want to get the dates to continue to have the current format, with the addition of an icon that allows us to more quickly select a date.

For this I use the date picker from http://www.kelvinluck.com/assets/jquery/datePicker/v2/demo/ and create a Helper.

Recipe:

1. Download date picker:
$ wget http://www.kelvinluck.com/assets/jquery/datePicker/v2/demo/scripts/jquery.datePicker.js
$ mv jquery.datePicker.js $CAKE_PROJECT/app/webroot/js/
$ wget http://www.kelvinluck.com/assets/jquery/datePicker/v2/demo/styles/datePicker.css
$ mv datePicker.css $CAKE_PROJECT/app/webroot/css/
$ wget http://github.com/vitch/jquery-methods/raw/master/date.js
$ mv date.js $CAKE_PROJECT/app/webroot/js

2. Save two small images in $CAKE_PROJECT/app/webroot/img (over 20x20), a calendar and a cros to put NULL, for example:
$ wget http://www.elibrary.dep.state.pa.us/images/small/calendar.png
$ mv calendar.png $CAKE_PROJECT/app/webroot/img/
$ wget http://www.ameibo.com/image/comment_cancel_icon.png
$ mv comment_cancel_icon.png $CAKE_PROJECT/app/webroot/img/drop.png

3. Create this file into $CAKE_PROJECT/app/webroot/js/cake.datePicker.js

function datepick(field_id,date_start,date_end){
    $('#'+field_id)
        .datePicker(
            {
                createButton:false,
                startDate:date_start,
                endDate:date_end

            }
        ).bind(
            'click',
            function()
            {
                updateSelects($(this).dpGetSelected()[0],$(this).attr("id"));
                $(this).dpDisplay();
                return false;
            }
        ).bind(
            'dateSelected',
            function(e, selectedDate, $td, state)
            {
                updateSelects(selectedDate,$(this).attr("id"));
            }
        ).bind(
            'dpClosed',
            function(e, selected)
            {
                updateSelects(selected[0],$(this).attr("id"));
            }
        );
    var updateSelects = function (selectedDate)
    {
        var selectedDate = new Date(selectedDate);
                if (selectedDate.getDate()<10){
                    $('#'+field_id+'Day option[value=0' + selectedDate.getDate() + ']').attr('selected', 'selected');
                } else {
                    $('#'+field_id+'Day option[value=' + selectedDate.getDate() + ']').attr('selected', 'selected');
                }
                if (selectedDate.getMonth()<9){
                    $('#'+field_id+'Month option[value=0' + (selectedDate.getMonth()+1) + ']').attr('selected', 'selected');
                } else {
                    $('#'+field_id+'Month option[value=' + (selectedDate.getMonth()+1) + ']').attr('selected', 'selected');
                }
        $('#'+field_id+'Year option[value=' + (selectedDate.getFullYear()) + ']').attr('selected', 'selected');
    }

    $('#'+field_id+'Day, #'+field_id+'Month, #'+field_id+'Year')
        .bind(
            'change',
            function()
            {
                var d = new Date(
                            $('#'+field_id+'Year').val(),
                            $('#'+field_id+'Month').val()-1,
                            $('#'+field_id+'Day').val()
                        );
                $('#'+field_id).dpSetSelected(d.asString());
            }
        );
    
    $('#'+field_id+'Day').trigger('change');

    // Can i use drop?
    $('#'+field_id+'_drop').bind(
        'click',
        function()
        {
            $('#'+field_id+'Year').val("");
            $('#'+field_id+'Month').val("");
            $('#'+field_id+'Day').val("");
        }
    );
}
4. Create this Helper in $CAKE_PROJECT/app/views/helpers/date_picker.php

Helper Class:

<?php 

class DatePickerHelper extends FormHelper {
   
    var 
$helpers = array('Html','Javascript'); 
    var 
$format '%Y-%m-%d';
   
    function 
_setup(){
        
$format Configure::read('DatePicker.format');
        if(
$format != null){
            
$this->format $format;
        }
    }

    function 
picker($fieldName$options = array()) {
        
$this->_setup();
        
$this->setEntity($fieldName);
        
$htmlAttributes $this->domId($options);        
        
$divOptions['class'] = 'date';
        
$options['type'] = 'date';
        
$options['div']['class'] = 'date';
    
$options['dateFormat'] = 'DMY';
        
$options['minYear'] = isset($options['minYear']) ? $options['minYear'] : (date('Y') - 20);
        
$options['maxYear'] = isset($options['maxYear']) ? $options['maxYear'] : (date('Y') + 20);

        
$options['after'] = $this->Html->image('calendar.png', array('id'=> $htmlAttributes['id'],'style'=>'cursor:pointer'));

    if (isset(
$options['empty'])) {
        
$options['after'] .= $this->Html->image('b_drop.png', array('id'=> $htmlAttributes['id']."_drop",'style'=>'cursor:pointer'));
    }
        
$output $this->input($fieldName$options);
        
$output .= $this->Javascript->codeBlock("datepick('" $htmlAttributes['id'] . "','01/01/" $options['minYear'] . "','31/12/" $options['maxYear'] . "');");
        return 
$output;
    }
   
}

?>

5. Add .js and .css in templates, maybe in $CAKE_PROJECT/app/views/layouts/default.ctp

<?php
   
echo $javascript->link(array('jquery.js',
            
'date.js',
            
'jquery.datePicker.js',
            
'cake.datePicker.js'
            
));

   echo 
$html->css(array(...'datePicker.css'...));
?>

6. Add helper in controller:

Controller Class:

<?php 
  
var $helpers = array(...'DatePicker'...);
?>

7. Then we can replace in the viewers:

   echo $form->input('start_date');
for:

   echo $datePicker->picker('start_date');


Bonus Track

You can add the parameter "empty" if we are to leave the date to null.

   echo $datePicker->picker('end_date',array('empty'=>true));

Report

More on Helpers

Advertising

Comments

  • srinivas posted on 08/05/11 09:40:04 AM
    hi,
    i placed datepicker in my website , but it is displaying 3 dropdown boxes and icon. i need only textbox to date picker. please advice what are the steps need to modify.
  • holdenru posted on 11/30/10 06:46:51 AM
  • pmic posted on 09/07/10 03:26:17 AM
    It does not validate as a date, is it the same for you?
  • icc97 posted on 08/14/10 03:48:19 AM
    A lovely, well explained article. Installation was as smooth as can be. I even didn't follow your guide exactly (I put your css and js code in a webroot/datePicker sub-directory) and it still worked first time.
  • noelferreira posted on 08/03/10 10:50:27 AM
    I confirm it is working with CakePHP 1.3.2.
    I made a mistake importing date.js (i mistype it in 'default'ctp').

    Nice work.

    Thanks
  • noelferreira posted on 08/03/10 10:05:53 AM
    Hi.

    Nice tutorial.
    Can you confirm that it is working with cakephp 1.3 version?
    I tried it without success.
    I also tried to add the 'option' escape => false to the array image attributes in the helper.

    Thanks,

    noel
  • butterlamb posted on 06/04/10 02:11:56 PM
    This worked exactly as I expected it to. Thanks so much.
  • floflo posted on 05/21/10 01:18:15 AM
    Congratulation for this article which is very useful.
    However, I had the following error: "Fatal error: Class 'FormHelper' not found in C:\wamp\www\cakephp\app\views\helpers\date_picker.php on line 5"
    Then I added the following line in the helper file date_picker.php :


    App::import('Helper', 'Form');

    Thank you and goodbye.
    Floflo
  • floflo posted on 05/20/10 05:09:48 AM
    Congratulation for this article which is very useful.
    However, I had the following error: "Fatal error: Class 'FormHelper' not found in C:\wamp\www\cakephp\app\views\helpers\date_picker.php on line 5"
    Then I added the following line in the helper file date_picker.php :

    App::import('Helper', 'Form');

    Thank you and goodbye.
    Floflo
login to post a comment.