Yii CGridView editable column

In this article I will show you how to make the Yii CGridView editable column. For that I will use the jQuery plugin Jeditable. I will use the example described here http://databytebank.com/2015/11/08/yii-cgridview-filter-date-range/ to make the grid inline editable. First download the Jeditable plugin and place it in ‘myapp\js\js-editable\jquery.jeditable.js’. Now we have to include the file in our application, for that open the file at ‘myapp\protected\views\layouts\main.php’ and insert the below code in the head tag.

<?php
Yii::app()->clientScript->registerScriptFile(Yii::app()->request->baseUrl.'/js/js-editable/jquery.jeditable.js',CClientScript::POS_END);
?>

Now create a class file at ‘myapp\protected\components\JEditableColumn’ and paste the below code in it.

<?php

class JEditableColumn extends CDataColumn
{

public $pk;
public $rel;

/**
* Renders a data cell.
* @param integer $row the row number (zero-based)
*/
public function renderDataCell($row)
{
$data=$this->grid->dataProvider->data[$row];
$options=$this->htmlOptions;
if($this->pk!==null)
{
$id=$this->evaluateExpression($this->pk,array('row'=>$row,'data'=>$data));
if(isset($options['id']))
$options['id'].=' '.$id;
else
$options['id']=$id;
}
if($this->rel!==null)
{
$rel=$this->evaluateExpression($this->rel,array('row'=>$row,'data'=>$data));
if(isset($options['rel']))
$options['rel'].=' '.$rel;
else
$options['rel']=$rel;
}
echo CHtml::openTag('td',$options);
$this->renderDataCellContent($row,$data);
echo '</td>';
}


}
?>

Now create the view file at ‘myapp\protected\views\site\project_editable.php’ and paste the below code in it.

<?php
Yii::app()->clientScript->registerScript("grid-inline-edit","function yiiEditable(){ $('.click').editable('".Yii::app()->createUrl('//site/projectupdate')."', {
onblur    :'submit',
submitdata: function() {return {rel: $(this).attr('rel')}},
},function(value, settings) {
});}
$(document).ready(function() {
yiiEditable();
$('body').live('ajaxUpdate.editable', yiiEditable);
});",CClientScript::POS_END);
?>



<?php

$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'project-grid',
'itemsCssClass'=>'table table-bordered table-condensed table-hover table-striped dataTable',
'dataProvider'=>$model->search(),
'afterAjaxUpdate'=>'js:function(id, data) {
$("#project-grid").trigger("ajaxUpdate.editable");
}',
'enablePagination' => true,
'enableHistory'=>true,
'pagerCssClass'=>'dataTables_paginate paging_bootstrap table-pagination',
'pager' => array('header'=>'','htmlOptions'=>array('class'=>'pagination')),
'columns' => array(
array('name'=>'project_name','value'=>'$data["name"]','header'=>'Name','htmlOptions'=>array('class'=>'click'),'class'=>'JEditableColumn','pk'=>'$data["id"]','rel'=>'item_code',),
),
'htmlOptions'=>array('class'=>'grid-view table-responsive hide-x-scroll'),
))
?>

Here we have given the ‘class’=>’JEditableColumn’ in CGridView column to get id in ‘td’ tag. Then we have written the script to make all elements with class ‘click’ to be editable. Next we will create the action in controller at ‘myapp\protected\controllers\SiteController.php’.

public function actionProjectUpdate()
{
$model=new Project;
if(isset($_POST))
{
$model->unsetAttributes();
$model->id = $_POST['id'];
$model->value = $_POST['value'];
$model->updateData();
echo $model->value;
}
}

Now in the model at ‘myapp\protected\models\Project.php’ write the function to update the table. Below is the complete code of the model file.

<?php


class Project extends CActiveRecord
{
public $project_name;
public $start_date;
public $end_date;
public $value;

/**
* Declares the validation rules.
*/
public function rules()
{
return array(
array('id,name,created_on,project_name,start_date,end_date,value', 'safe'),
);
}



public function tableName()
{
return 'project';
}



public function search()
{

if(empty($this->project_name))
$this->project_name=null;
if(empty($this->start_date))
$this->start_date=null;
if(empty($this->end_date))
$this->end_date=null;


$command =Yii::app()->db->createCommand("SELECT COUNT(*) FROM project where :start_date is null or :end_date is null or created_on between :start_date and :end_date");
$command->bindParam(":start_date",  $this->start_date,PDO::PARAM_STR);
$command->bindParam(":end_date",  $this->end_date,PDO::PARAM_STR);
$count=$command->queryScalar();

$sql="SELECT id,name FROM project where  :start_date is null or :end_date is null or created_on between :start_date and :end_date";

$dataProvider=new CSqlDataProvider($sql, array(
'params' => array(':start_date'=>$this->start_date,':end_date'=>$this->end_date),
'totalItemCount'=>$count,
'db'=>Yii::app()->db,
'sort'=>array(
'attributes'=>array(
'name'
),
),
'pagination'=>array(
'pageSize'=>10,
),
));
return $dataProvider;
}



public function updateData()
{
$command =Yii::app()->db->createCommand("update project set name=:value where id=:id");
$command->bindParam(":id",  $this->id,PDO::PARAM_STR);
$command->bindParam(":value",  $this->value,PDO::PARAM_STR);
$command->execute();
}


}

Now go to the URL ‘http://localhost/myapp/index.php?r=site/projecteditable’ and you can see the editable grid which will update the name using ajax.

yii cgridview editable column