Today someone asked me for help to integrate Jeditable with Yii CGridView. So I thought why not write a little tutorial that can help others as well.
In this article I assume that you are comfortable working with Yii; you are able to create Yii web applications and use Gii module to create models. Also, I assume that you have used JQuery and its plugins in your applications. If you are unfamiliar with any of these terms, check out the following links to learn more.
For this article, we’ll consider a very simple “user” table, with following structure.
In this table, “status” field shows whether a user is active (allowed to login) or not. It is not very user-friendly that admin has to move to some other page, only to make a user active or inactive. We’ll see how we can allow our admin to change user’s status on grid. Now open up your application’s Gii module in browser and create model class for this table
First we need to display users’ records in a grid. For that purpose, we’ll have to create an “action” in our controller class.
public function actionList() { $model=new User('search'); $model->unsetAttributes(); // clear any default values if(isset($_GET['User'])) $model->attributes=$_GET['User']; $this->render('list',array( 'model'=>$model, )); }
Now in our “list” view, we need to add code for displaying data in Yii’s grid.
$this->widget('zii.widgets.grid.CGridView', array( 'id'=>'user-grid', 'dataProvider'=>$model->search(), 'filter'=>$model, 'columns'=>array( 'id', 'firstname', 'lastname', 'email', 'createtime', 'status' array( 'class'=>'CButtonColumn', 'template' => '{update} {delete}', ), ), ));
The code that we have till now is the default code that can be created by Gii module. Now in order to add ability to edit in place, we’ll start customizing the grid. We’ll add a class to “status” fields so that we can later reference it from JavaScript. So, our grid code becomes
$this->widget('zii.widgets.grid.CGridView', array( 'id'=>'user-grid', 'dataProvider'=>$model->search(), 'filter'=>$model, 'columns'=>array( 'id', 'firstname', 'lastname', 'email', 'createtime', 'status' => array( 'type'=>'html', 'value' => '$data->status?"<a class='editable-".$data->id."'>Active</a>":"<a class='editable-".$data->id."'>Inactive</a>"', 'name' => 'status' ), array( 'class'=>'CButtonColumn', 'template' => '{update} {delete}', ), ), ));
Now we’ll add the JavaScript code to change word “Active” or “Inactive” to a drop down list so that admin can update that value.
First you’ll need to add the code to include necessary JavaScript Files to the view.
Yii::app()->clientScript->registerScriptFile(Yii::app()->request->baseUrl.'/js/jquery.jeditable.mini.js');
Next comes the actual code that will display drop down list in Yii’s grid.
Yii::app()->clientScript->registerScript('status',' $("a[class^=editable-]").editable("'.$this->createUrl('user/status').'", { submitdata : function (value,settings){ return {"User[id]":$(this).attr("class").substr("9"),}; }, indicator : "Saving...", tooltip : "Click to edit...", type : "select", data : "{'1':'Active','0':'Inactive'}", submit : "OK", name : "User[status]" }); ',CClientScript::POS_READY);
For the details of options specified with Jeditable, check out plug-in’s page
We now have a grid having status column as hyperlinks. Clicking these links display a drop down list and an “Ok” button. It may look it works perfectly fine, but there is small issue with it. Yii grid is Ajax-based. If you apply filters, click page number etc. grid performs an Ajax request to get fresh data. When this happens, the classes of new records are no longer bind to Jeditable and edit in place does not work. To fix this we’ll enclose the above piece of code in jQuery’s “live” function which binds events to current as well as future elements. So, our final piece of JavaScript code becomes
Yii::app()->clientScript->registerScript('status',' $("a[class^=editable-]").live("click", function () { $(this).editable("'.$this->createUrl('user/status').'", { submitdata : function (value,settings){ return {"User[id]":$(this).attr("class").substr("9"),}; }, indicator : "Saving...", tooltip : "Click to edit...", type : "select", data : "{'1':'Active','0':'Inactive'}", submit : "OK", name : "User[status]" }); }); ',CClientScript::POS_READY);
The last step is to code the action for our controller class which we have specified in Jeditable’s option “submitdata”. This is the function which will save the updated value back to database. A simple example of such a function is
public function actionStatus() { if(isset($_POST['User'])) { $model = User::model()->findByPk($_POST['User']['id']); if($model===null){ throw new CHttpException(404,'The requested page does not exist.'); } $model->attributes = $_POST['User']; if($model->save()){ echo $model->status?"Active":"Inactive"; } } }
24 Comments
Great tutorial. Im starting with Yii and I’ll try to use this today
Regards
Hi,
Ive been testing your code and works fine. Just wondering about the proper way to make all my grid elements editable (text, upload file, datepicker, checkbox and dropdowns) and get the controller to work optimized and return the correct value on each modification.
Any suggestion for my actionStatus function? If i always send post[User][id] and post[User][editablefield]
Regards
In that case you can do some thing like this
Hope this helps.
thx…. helping me very much….
I need this functionality in my web application … … You have given great code.. but when I applied this, its not working………….
on active text hyperlink is coming but the onclick Drop down open feature is not working….
can i edit textbox fields in this grid? if possible .. please help me
i have the same problem with Bright Star, when i implemented this code, editable dropdownlist’s not working.
Great tutorial it helped me a lot.
But am facing a small issue after using this.Default inline search provided by cgridview is not working.
it is totaly removing the search textfield.Can you please help me on this.
You can fix this easily. In step 4, instead of array key “header”, specify key “name” and its value should be the name of your field/model property.
Hope this helps.
Hi
Thanks a lot for this tutorial, helped me a lot to use jeditable in yii, my question is if is possible to use with CSRF validation, so far i tried to append a input hidden to the form with jquery but doesnt work, any idea how could I fix this?
Thanks,
Flo
Wow, that is an amazing yii grid view tutorial! Thank you very much for writing this!!!
Such a nice knowledge sharing, I’m appreciated !
Cheer,
pod2g
Great tutorial!!!
But I am wondering if we can save which edited in new record?
Please reply this….
Thank you
hi dear i use it .but on clicking the link in grid-view no drop-down of select list is displayed .
This has been very helpful, but I am still getting a 500 Internal Server Error with the reason being (anonymous function) in the /js/jquery.jeditable.mini.js. So far I have not been able to get the code to save my input.
In Step 5 the code changes from .attr(“class”).substr(“9”) to .attr(“id”).substr(“9”). Can you explain why there was a change. It doesn’t seem to work at all with the “id” attribute.
Thanks!
Hello Yajasi,
I do not think that Internal Server Error can be because of error in Javascript file but still, we used following script file with this code
https://github.com/tuupola/jquery_jeditable/blob/master/jquery.jeditable.js
This works fine for us. Try changing your minimized file with this one and check if its works or not.
About id instead of class in step 5, that’s a mistake.
Thanks for pointing that out.
if you are facing problem then reason is javascript you can use this javascript
http://www.appelsiini.net/projects/jeditable/jquery.jeditable.js
Used this code
Yii::app()->clientScript->registerScript(‘status’,’
$(“a[class^=editable-]”).live(“click”, function () {
$(this).editable(“‘.$this->createUrl(‘user/status’).'”, {
submitdata : function (value,settings){
return {“User[id]”:$(this).attr(“class”).substr(“9”),};
},
indicator : “Saving…”,
tooltip : “Click to edit…”,
type : “select”,
data : “{‘1′:’Active’,’0′:’Inactive’}”,
submit : “OK”,
name : “User[status]”
});
});
‘,CClientScript::POS_READY);
nice!! that’s work!!
My code
Yii::app()->clientScript->registerScript(‘expire_date’,’
$(“td[class^=change_date-]”).editable(“‘.$this->createUrl(‘users/expire_date’).'”, {
submitdata : function (value,settings){
return {“Users[contract_id]”:”SB00001_1″,};
},
tooltip : “Изменить дату…”,
type:”text”,
name : “Users[expire_date]”,
style : “display: inline”
}
);
‘,CClientScript::POS_READY);
And I have an Error
Request URL:
http://158315.planeta.web.hosting-test.net/index.php?r=users/expire_date
Request Method:
POST
Status Code:
403 Forbidden
r:
users/expire_date
Form Dataview sourceview URL encoded
Users[expire_date]:
2013-01-12
id:
Users[contract_id]:
SB00001_1
What is wrong?
And how can I do for more than one column?
Thanks a lot for sharing the code.. Im a beginner still , really appreciated it!
Thanks again!
Cheerz!
Great tutorial, got this up and running in a few minutes! I’m looking to do something very similar, and I’m having a hard time getting there: I have a dropdown already, and I’d like the row to updated onchange with the drop down. I can’t figure out how to submit onchange instead of showing an ‘ok’ button
Hi,
When I make the grid editable using the following line of code
‘value’ => ‘$data->loginpasswd?”<a class=’editable-“.$data->id.”‘>Active</a>”:”<a class=’editable-“.$data->id.”‘>Inactive</a>”‘
I get the following error:
include(DOMDocument.php): failed to open stream: No such file or directory
Can you please help me resolve this?
Thank you.
DANIEL