Skip to content

Categories:

Customising CGridView – CJuiDatepicker

Yii Framework comes with a nice table widget named CGridView for displaying model data. When generating CRUD with Yii the view files for each model will have an admin.php file. This will display selected database table columns that are both searchable and sortable using Ajax.  Developers will quickly find however that the standard text inputs for searching are less than appropriate in many cases, one of these being date columns.

This example will show how to use one of Yii’s standard jQuery widgets, CJuiDatepicker, for searching date columns. The example is from an Orders class from an eCommerce system I developed and we will be looking at the 'date_purchased' column which is a standard MySQL datetime column.

The standard code generated by CRUD in admin.php will look something similar to the following:


<?php $this->widget('zii.widgets.grid.CGridView', array(
    'id'=>'orders-grid',
    'dataProvider'=>$model->search(),
    'filter'=>$model,
    'columns'=>array(
        'id',
        'user_name',
        'user_email_address',
        'date_purchased',
        'payment_method',
        'orders_status',
        array(
            'class'=>'CButtonColumn',
        ),
    ),
)); ?>

The first step is to call the datepicker widget in the 'columns' array by changing the  'date_purchased' column to explicitly set the 'filter' property: (use your mouse and arrow keys if you can’t see the scrollbar for the code):


array('name' => 'date_purchased', 'type' => 'raw', 'filter'=>$this->widget('zii.widgets.jui.CJuiDatepicker', array('model'=>$model, 'attribute'=>'date_purchased', 'htmlOptions' => array('id' => 'date_purchased_search'), 'options' => array('dateFormat' => 'yy-mm-dd')), true)),

It is important to include 'dateformat' in the 'options' array to match your column format.  While MySQL datetime columns include hours, minutes and seconds these are not required.

Also important is to assign an ID, otherwise Yii will auto generate an ID that will be a duplicate of the one used in Advanced Search.

If you test the above you will find that it works, but only for the first request.  Because the search content is loaded via Ajax, we need something more to load the datepicker again after the Ajax request.  CGridView has the 'afterAjaxUpdate' property just for this purpose, which we can use like this:

'afterAjaxUpdate'=>"function(){jQuery('#date_purchased_search').datepicker({'dateFormat': 'yy-mm-dd'})}",

Thus our completed code looks as follows:


<?php $this->widget('zii.widgets.grid.CGridView', array(
    'id'=>'orders-grid',
    'dataProvider'=>$model->search(),
    'filter'=>$model,
    'afterAjaxUpdate'=>"function(){jQuery('#date_purchased_search').datepicker({'dateFormat': 'yy-mm-dd'})}",
    'columns'=>array(
        'id',
        'user_name',
        'user_email_address',
        array('name' => 'date_purchased', 'type' => 'raw', 'filter'=>$this->widget('zii.widgets.jui.CJuiDatepicker', array('model'=>$model, 'attribute'=>'date_purchased', 'htmlOptions' => array('id' => 'date_purchased_search'), 'options' => array('dateFormat' => 'yy-mm-dd')), true)),
        'payment_method',
        'orders_status',
        array(
            'class'=>'CButtonColumn',
        ),
    ),
)); ?>

Here is how it looks:

datepicker

Happy coding!

Posted in Yii Framework.

Tagged with , , , , .


8 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. karmraj says

    Hello matti ressler,

    I have use this in my CGridview. This work awesome but i want to change format of data to in search line dd-mm-yy. Right now when i change date format for filter, searching not working.

    Thanks.

  2. Matti says

    Hello Karmraj,

    This is easily handled in your model like this:

        protected function afterFind()
        {
            $this->date = date('Y-m-d', $this->date); // or whatever your preferred date format is
    
            return parent::afterFind();
        }
    
        protected function beforeValidate()
        {
            $this->date = strtotime($this->date);
    
            return parent::beforeValidate();
        }
    
    • Matti says

      The above assumes you are storing your date as TIMESTAMP. If however you are storing as DATE and just want to change the format, do the conversion like this:

          $this->date = date ('d-m-y', strtotime($this->date));
      
          // and
      
          $this->date = date ('Y-m-d', strtotime($this->date));
      
  3. Igor says

    Hello!
    I have problem with setting language – after loading everything is ok, but after ajax update it always becomes Chineese. I have no idea what I’m doing wrong.
    It seems that line
    datepicker({‘language’: ‘ru’,'dateFormat’: ‘yy-mm-dd’}); in
    function reinstallDatePicker(id, data) {
    $(‘#datepicker_createTime’).datepicker({‘language’: ‘ru’,'dateFormat’: ‘yy-mm-dd’});
    }
    not working

  4. Igor says

    Forget my question. I should have use
    $(‘#datepicker_createTime’).datepicker( $.datepicker.regional[ 'ru' ])
    instead of
    datepicker({‘language’: ‘ru’})

  5. Lynette says

    Is there a way add to the data filter?

  6. Lynette says

    Is there a way to add greater than or less than to the filter? E.G. everything with a date greater than the datepicker date…

    • Matti says

      You could add a condition in your model, something like this:

       if(!empty($this->my_date)) {
          $criteria->addCondition("my_date > " . $this->my_date);
      }
      



Some HTML is OK

or, reply to this post via trackback.


seven − one =