If you show a model (with a lot of attributes) partially in a CGridView, it can be helpful when the user can take a quick look at the full record with all attributes without displaying the view as a page and afterwards returning back to the gridview.
It needs only a few steps/changes to change the behavior of the 'view' icon in the CButtonColumn so that 'actionView' is rendered into a CJuiDialog. Now the user can open one - or even more - dialog(s) with all record details.
You can implement this in two ways:
Step 1
Add code to the zii.widgets.grid.CGridView to change the behavior of the 'view' icon. A click on the icon now will result in an ajax call to /address/view
.... <?php $this->widget('zii.widgets.grid.CGridView', array( 'id'=>'address-grid', 'dataProvider'=>$model->search(), 'filter'=>$model, 'columns'=>array( 'ID', 'FIRSTNAME', 'LASTNAME', 'STREET', 'COUNTRYCODE', 'CITY', /* 'ZIPCODE', 'PROVINCE', 'EMAIL', 'PHONE1', 'PHONE2', 'FAX', 'REGION', 'NOTE', ... */ array( 'class'=>'CButtonColumn', //--------------------- begin added -------------------------- 'buttons'=>array('view'=> array( 'url'=>'Yii::app()->createUrl("address/view", array("id"=>$data->ID,"asDialog"=>1))', 'options'=>array( 'ajax'=>array( 'type'=>'POST', // ajax post will use 'url' specified above 'url'=>"js:$(this).attr('href')", 'update'=>'#id_view', ), ), ), ), //--------------------- end added -------------------------- ), ), )); //----------- add the div below as container for the dialog ----------------------- <div id="id_view"></div>
Step 2
Change the code of actionView in the AddressController. If you want to display the output in a dialog (or maybe other ajax area) you have to use 'renderPartial' instead of 'render'. You have to set $processOutput=true to render the CJuiDialog js-script too.
Coded this way, it's possible to display the record in a single page or in the dialog.
public function actionView($id) { if (Yii::app()->request->isAjaxRequest) { $this->renderPartial('view', array( 'model'=>$this->loadModel($id), 'asDialog'=>!empty($_GET['asDialog']), ), false,true); Yii::app()->end(); } else $this->render('view', array( 'model'=>$this->loadModel($id), )); }
Step 3
Change the view-code of the file address/view.php to display the CJuiDialog widget if $asDialog=true.
//------------ add the CJuiDialog widget ----------------- if (!empty($asDialog)): $this->beginWidget('zii.widgets.jui.CJuiDialog', array( // the dialog 'id'=>'dlg-address-view-'. $model->ID, 'options'=>array( 'title'=>'View Address #'. $model->ID, 'autoOpen'=>true, 'modal'=>false, 'width'=>550, 'height'=>470, ), )); else: //-------- default code starts here ------------------ <?php $this->breadcrumbs=array( 'Addresses'=>array('index'), $model->NAME, ); $this->menu=array( array('label'=>'List Address', 'url'=>array('index')), // ... more operations portlet code generated by gii ); <h1>View Address #<?php echo $model->ID; </h1> //--------------------- begin added -------------------------- <?php endif; //--------------------- end added -------------------------- <?php $this->widget('zii.widgets.CDetailView', array( 'data'=>$model, 'attributes'=>array( 'ID', 'CODE', 'FIRSTNAME', 'LASTNAME', 'STREET', 'ZIPCODE', 'CITY', 'COUNTRY', 'COUNTRYCODE', 'PROVINCE', 'EMAIL', 'PHONE1', 'PHONE2', 'FAX', 'REGION', 'NOTE', //... all record attributes ), )); //-------- end of default code ------------------ <?php //----------------------- close the CJuiDialog widget ------------ if (!empty($asDialog)) $this->endWidget();
The user can drag the dialog to a postion he likes. Update the content of the dialog on every 'view-icon' click. This solutions has a better performance and no need to change the view.php code
Differences compared to Part I:
Step 1
The admin.php code.
.... <?php $this->widget('zii.widgets.grid.CGridView', array( ... CGridview the same as above ... )); //the dialog $this->beginWidget('zii.widgets.jui.CJuiDialog', array( 'id'=>'dlg-address-view', 'options'=>array( 'title'=>'Detail view', 'autoOpen'=>false, //important! 'modal'=>false, 'width'=>550, 'height'=>470, ), )); <div id="id_view"></div> <?php $this->endWidget();
Step 2 The viewAction code from AddressController.
public function actionView($id) { if (Yii::app()->request->isAjaxRequest) { //outputProcessing = true because including css-files ... $this->renderPartial('view', array( 'model'=>$this->loadModel($id), ),false,true); //js-code to open the dialog if (!empty($_GET['asDialog'])) echo CHtml::script('$("#dlg-address-view").dialog("open")'); Yii::app()->end(); } else $this->render('view', array( 'model'=>$this->loadModel($id), )); }
Similar and other useful articles
Total 7 comments
hi ,
i need to help this same as for update action .. please help me
Very cool:
Just, remember to change "ID" to your own primary key in Part 1:
Step 1 -> CGridView view button -> 'url'
and
Step 3 -> beginWidget -> 'id' and 'title'
Thanks for this tutorial but have few issues as am trying to use a normal chtml::link to achieve this feature in my app. Here is the code am trying to modify
The above link when clicked on does not go anywhere I understand this feature was done with CButtonColumn but in my app am using normal links because I have my own gridview different from what yii uses by default. Help please.
I have read topic and did the same. But when i click on {view} icon ,nothing displays. Help me :(
Re part 1, In FF 11, think u need to add this to the div:
to stop the div flickering, Chrome seems ok though.
Thanks, works perfect. The only problems I had was the uppercase ID in the admin.php:
This lead to a total cofused page admin.php, where an error is on the left.
Now it works!
thank you, joblo...
nice and helpful article... very useful in office application that have too many fields..
Leave a comment
Please login to leave your comment.