unchanged
Title
CGridView: Update/create records in a CJuiDialog
>Note: This code is now part of the extension [quickdlgs](http://www.yiiframework.com/extension/quickdlgs/ "quickdlgs") ---------------------------------------------------------------------------------------------------------------- My article [Display the full record in a CJuiDialog](http://www.yiiframework.com/wiki/262/cgridview-display-the-full-record-actionview-in-a-cjuidialog/ "cgridview-display-the-full-record-actionview-in-a-cjuidialog") uses ajax to view a record in dialog on clicking the 'view-icon'. Other authors use ajax too for update/insert: - [update-delete-model-with-cjuidialog-works-in-cgridview](http://www.yiiframework.com/wiki/216/update-delete-model-with-cjuidialog-works-in-cgridview/ "") - [cjuidialog-for-create-new-model](http://www.yiiframework.com/wiki/145/cjuidialog-for-create-new-model/ "") Here is a solution that **uses an iframe** within the dialog. It's easy to implement in a few steps. I use the 'Address' example like the one in my last article, but you can **copy/paste the new code** of views/admin.php and actionUpdate/Create **unchanged for usage with any other model**. ### Step 1 You have to generate an iframe-layout (**layouts/iframe.php**) that includes at least the css-files for the form. You can copy your main-layout and remove unnecessary code. **Tip:** You can use this layout to display other content from your site within a dialog too. ~~~ [php] <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="language" content="de" /> <!-- blueprint CSS framework --> <link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/css/screen.css" media="screen, projection" /> <link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/css/print.css" media="print" /> <!--[if lt IE 8]> <link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/css/ie.css" media="screen, projection" /> <![endif]--> <link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/css/main.css" /> <link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/css/form.css" /> <link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/css/custom.css" /> </head> <body> <div id="page"> <?php echo $content; ?> </body> </html> ~~~ ### Step 2 Alter the code of **views/admin.php**. You have to add the code for the CJuiDialog and change the behavior of the CButtonColumn update-icon. **The click function sets the source for the iframe and opens the dialog.** It's important to 'return false' onclick. The 'gridId' is submitted to make the code reusable for other models too. ~~~ [php] .... <?php $this->widget('zii.widgets.grid.CGridView', array( 'id'=>'address-grid', 'dataProvider'=>$model->search(), 'filter'=>$model, 'columns'=>array( 'ID', 'FIRSTNAME', 'LASTNAME', ... array( 'class'=>'CButtonColumn', //--------------------- begin new code -------------------------- 'buttons'=>array( 'update'=> array( 'url'=>'$this->grid->controller->createUrl("update", array("id"=>$data->primaryKey,"asDialog"=>1,"gridId"=>$this->grid->id))', 'click'=>'function(){$("#cru-frame").attr("src",$(this).attr("href")); $("#cru-dialog").dialog("open"); return false;}', ), ), //--------------------- end new code -------------------------- ), ), ));?> <?php //--------------------- begin new code -------------------------- // add the (closed) dialog for the iframe $this->beginWidget('zii.widgets.jui.CJuiDialog', array( 'id'=>'cru-dialog', 'options'=>array( 'title'=>'Detail view', 'autoOpen'=>false, 'modal'=>false, 'width'=>750, 'height'=>800, ), )); ?> <iframe id="cru-frame" width="100%" height="100%"></iframe> <?php $this->endWidget(); //--------------------- end new code -------------------------- ?> ~~~ ### Step 3 Change the code of the **actionUpdate of the controller** like below. If the get-param 'asDialog' is not set, the method works as usual. Otherwise: - The layout is set to '//layouts/iframe' - After saving the model: - Close the dialog - Reset the iframe source. Otherwise the last opened record is shown until the current is loaded. - Refresh the gridview ~~~ [php] public function actionUpdate($id) { $model=$this->loadModel($id); // Uncomment the following line if AJAX validation is needed // $this->performAjaxValidation($model); if(isset($_POST['Address'])) { $model->attributes=$_POST['Address']; if($model->save()) //----- begin new code -------------------- if (!empty($_GET['asDialog'])) { //Close the dialog, reset the iframe and update the grid echo CHtml::script("window.parent.$('#cru-dialog').dialog('close');window.parent.$('#cru-frame').attr('src','');window.parent.$.fn.yiiGridView.update('{$_GET['gridId']}');"); Yii::app()->end(); } else //----- end new code -------------------- $this->redirect(array('view','id'=>$model->ADDRESS)); } //----- begin new code -------------------- if (!empty($_GET['asDialog'])) $this->layout = '//layouts/iframe'; //----- end new code -------------------- $this->render('update',array( 'model'=>$model, )); } ~~~ That's all about updating. ### And what's about the action create? You can add a link below the caption of the admin-view. ~~~ [php] <h1>Manage Addresses</h1> <?php $createUrl = $this->createUrl('create',array("asDialog"=>1,"gridId"=>'address-grid')); echo CHtml::link('Create Address','#',array('onclick'=>"$('#cru-frame').attr('src','$createUrl '); $('#cru-dialog').dialog('open');")); ?> ~~~ Or you set the 'createUrl' and 'onclick' like above in the operations menu if you use the default columns2 layout. The code-snippets from the actionUpdate work unchanged in the actionCreate too. **Alter the code of actionCreate exactly the same as the code from actionUpdate** above. ### Tip Add a **cancel-button** in your **_form.php** in the button row. ~~~ [php] <div class="row buttons"> <?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?> <?php echo CHtml::button('Cancel',array('onclick'=>"window.parent.$('#cru-dialog').dialog('close');window.parent.$('#cru-frame').attr('src','');")); ?> </div> ~~~ But if you use the update/insert form in single page mode too, you have to check if the form is shown in the dialog or not, maybe by submitting the variable 'asDialog' to the _form.php.