You are viewing revision #5 of this wiki article.
This is the latest version of this article.
You may want to see the changes made in this revision.
- Scenario
- Demo
- Fetch listing from model:
- Add TextField, checkbox, buttons in CGridView:
- Save all grid data into database:
This is a tutorial for how to add input text-Field, check-box, buttons in CGridView.
Scenario ¶
This is CRUD pages for admin menu management. So, Menu model have following things:
- menuId : INT
- menuName : VARCHAR
- sortOrder : INT (Admin may change menu order, based on that front side menu will render)
- isActive : BOOL (only values with '1' will be shown in front side)
- isDelete : BOOL (only values with '0' will be shown, whenever admin deletes any menu value will be changed to '1')
Demo ¶
Below is how GRID will look like:
Fetch listing from model: ¶
Let's start with model file. There is only one change, I want default listing by sortOrder field.
public function search()
{
.....
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
'sort'=>array(
'defaultOrder'=>'sortOrder ASC',
),
));
}
Add TextField, checkbox, buttons in CGridView: ¶
Now we will see view file.
We need to add CGridView inside form so that we can save grid data after submission. We will use ajax to operate all things.
We need to use CCheckBoxColumn which will generate checkbox first column as shown in image.
We need some ajax button at bottom of the page using ajaxSubmitButton which will handle all events. Button names are self-explainable. Here i am going to use 4 buttons
- To change status to 'Active'
- To change status to 'In Active'
- To delete multiple row.
- To update sort order.
<?php $form=$this->beginWidget('CActiveForm', array(
'enableAjaxValidation'=>true,
)); ?>
<?php
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'menu-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
array(
'id'=>'autoId',
'class'=>'CCheckBoxColumn',
'selectableRows' => '50',
),
'menuId',
'menuName',
array(
'name'=>'sortOrder',
'type'=>'raw',
'value'=>'CHtml::textField("sortOrder[$data->menuId]",$data->sortOrder,array("style"=>"width:50px;"))',
'htmlOptions'=>array("width"=>"50px"),
),
array(
'name'=>'isActive',
'header'=>'Active',
'filter'=>array('1'=>'Yes','0'=>'No'),
'value'=>'($data->isActive=="1")?("Yes"):("No")'
),
array(
'class'=>'CButtonColumn',
),
),
)); ?>
<script>
function reloadGrid(data) {
$.fn.yiiGridView.update('menu-grid');
}
</script>
<?php echo CHtml::ajaxSubmitButton('Filter',array('menu/ajaxupdate'), array(),array("style"=>"display:none;")); ?>
<?php echo CHtml::ajaxSubmitButton('Activate',array('menu/ajaxupdate','act'=>'doActive'), array('success'=>'reloadGrid')); ?>
<?php echo CHtml::ajaxSubmitButton('In Activate',array('menu/ajaxupdate','act'=>'doInactive'), array('success'=>'reloadGrid')); ?>
<?php echo CHtml::ajaxSubmitButton('Delete',array('menu/ajaxupdate','act'=>'doDelete'), array('success'=>'reloadGrid')); ?>
<?php echo CHtml::ajaxSubmitButton('Update sort order',array('menu/ajaxupdate','act'=>'doSortOrder'), array('success'=>'reloadGrid')); ?>
<?php $this->endWidget(); ?>
From above code you may wonder why i have taken Filter invisible button, reason is if you don't put it and type something in filter boxed and press enter it will invoke 'Active' button, as it the first submit button in form, you may also try some other options.
Save all grid data into database: ¶
Looking into controller file.
public function actionAjaxupdate()
{
$act = $_GET['act'];
if($act=='doSortOrder')
{
$sortOrderAll = $_POST['sortOrder'];
if(count($sortOrderAll)>0)
{
foreach($sortOrderAll as $menuId=>$sortOrder)
{
$model=$this->loadModel($menuId);
$model->sortOrder = $sortOrder;
$model->save();
}
}
}
else
{
$autoIdAll = $_POST['autoId'];
if(count($autoIdAll)>0)
{
foreach($autoIdAll as $autoId)
{
$model=$this->loadModel($autoId);
if($act=='doDelete')
$model->isDeleted = '1';
if($act=='doActive')
$model->isActive = '1';
if($act=='doInactive')
$model->isActive = '0';
if($model->save())
echo 'ok';
else
throw new Exception("Sorry",500);
}
}
}
}
Friends, hope this may help to newbies like me :)
Share your comments for any bug or issue, Also if you have any new thing in GRID which can be helpful in admin CRUD please share your thoughts.
I am using MasterAdmin class for auto set model values, you can check it HERE
Happy Coding!
Thanks
Just copy and run well. Save my time. Thanks a lot.
Thanks
Welcome @vothanhy.
One question
First of all, thanx for this nice tutorial, but I have one question:
what is the meaning of
$model->isDeleted = '1';
It is clear for'isActive', but for deleting, shouldn't there be something like
@Freeflow
@Freeflow,
isDeleted is database field which is set to '1' on doDelete action.
so that db field is set to '1' by,
$model->isDeleted = '1';
and then model is saved by,
@Freeflow
e.g. you have user database for a big applications. There are lots of data associated with that user_id, Now when admin delete that user using code $model->delete(); then user records will permanently deleted from database. And you loose important data from database, so by setting flag isDeleted=1, you still have all data of that user in database. In front side if user have isDeleted=0 then only he can login.
@vibhaJadwani
YesItIs, the better way to use in system...
where's action
Hi,
Where's the action code that renders the first view before calling the action for ajaxUpdate! not working with me :(
@basem
Hi basem,
as you can see in tutorial - the author had specified that she use CRUD generator for generating model and crud pages...
so, you just had to create crud and then follow above specified steps.
Happy Coding! :)
Adding a confirm box
Even if the data is not deleted from the database when you hit the delete-button, but only flagged to 'is_deleted' I think it might be helpful to add a confirm box to confirm the delete action. I did it like this:
<?php echo CHtml::ajaxSubmitButton('Delete',array('controller/action','act'=>'doDelete'), array('beforeSend'=>'function() { if(confirm("Are You Sure ...")) return true; return false; }', 'success'=>'reloadGrid')); ?>
Thanks
How would you save your textfield if you want to use two models in the gcridview?
Nice Work
Your Admin panel is very useful for the yii beginners like me.
You have to update accessRules() aswell
It is important to update accessRules() and give access to those actions
public function accessRules() { return array( array('allow', // allow authenticated user to perform 'create' and 'update' actions 'actions'=>array('ajaxupdate'), // ALLOW AJAXUPDATE TO REGISTERED USERS 'users'=>array('@'), ), array('deny', // deny all users 'users'=>array('*'), ), ); }
@darioo
Yes It Is.
but here we shown view and function like important part only.
@kiran sharma
I as beginner didn't know that and I had trouble making it work, so it was for all other beginners
@darioo
Its very kind to help others from posting/comment, and share your experience.
Thanks
:)
Thanks
Thank u very much it help me a lot ;)
beter query
Hi
Tanks for this wiki
I think,it is beter remove database query execute from foreach change this code:(to update one field such as status)
secound code make only 1 request to DB,but your code make several request to db. :)
foreach($autoIdAll as $autoId) { $model=$this->loadModel($autoId); if($act=='doDelete') $model->isDeleted = '1'; if($act=='doActive') $model->isActive = '1'; if($act=='doInactive') $model->isActive = '0'; if($model->save()) echo 'ok'; else throw new Exception("Sorry",500); }
replace with
$autoIdAll = $_POST['autoId']; if (count($_POST['autoId']) > 0) { //change to int for security and prevent sql injection foreach ($_POST['autoId'] as $key) { $autoIdAll[] = (int) $key; } $update = Yii::app()->db->createCommand()->update('tbl_test', array('param' => $param), "id IN (" . implode(',', $autoIdAll) . ")"); }
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.