- Note: This code is now part of the extension quickdlgs
- Part I: Allow to open multiple dialogs
- Part II: Allow only a single dialog
- Tips
Note: This code is now part of the extension quickdlgs ¶
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.
- Assume you have a model 'Address' with the attributes (id, firstname, lastname, ...)
- You have generated the default model and controller with gii.
- In the gridview you display the id, firstname, lastname, street, countrycode and city
You can implement this in two ways:
- Allow the user to open multiple dialogs to display different records at once
- Allow only one dialog and update the content when the user selects another record.
Part I: Allow to open multiple dialogs ¶
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.
<?php
//------------ 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();
?>
Part II: Allow only a single dialog ¶
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:
- Don't render the CJuiDialog in the views/address/view.php. You don't have to change the view.php generated by gii. Leave it untouched, no need for Step 3 from above.
- Render the CJuiDialog widged in views/address/admin.php below the CGridview and set 'autoOpen'=>false
- Open the dialog by rendering the js-code '$("#dlg-address-view").dialog("open")' in the actionView.
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.
- Code to open the dialog
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),
));
}
Tips ¶
- Without using the CJuiDialog you can show the records below the grid.
- You can use this techniqe to show master records in the grid and detail records below or in a dialog too. You only have to set the correct url / action in the CGridView.
Similar and other useful articles
User Contributed Notes 7
thank you
thank you, joblo...
nice and helpful article... very useful in office application that have too many fields..
works like a charm...
Thanks, works perfect. The only problems I had was the uppercase ID in the admin.php:
array("id"=>$data->ID...This lead to a total cofused page admin.php, where an error is on the left.
Now it works!
Firefox 11.0 note
Re part 1, In FF 11, think u need to add this to the div:
~~~
[html]
~~~
to stop the div flickering, Chrome seems ok though.
nothing displays
I have read topic and did the same.
But when i click on {view} icon ,nothing displays.
Help me :(
Thanks for this tutorial
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
<?php echo CHtml::link('View', array( 'url'=>'Yii::app()->createUrl("//backoffice/user/show", array("id"=>$model->id,"asDialog"=>1))', 'options'=>array( 'ajax'=>array( 'type'=>'POST', //ajax post will use 'url' specified above 'url'=>"js:$(this).attr('href')", 'update'=>'#id_view', ), ), ) ); ?>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.
ID
Very cool:
Just, remember to change "ID" to your own primary key in Part 1:
Step 1 -> CGridView view button -> 'url'
andStep 3 -> beginWidget -> 'id' and 'title'
need help
hi ,
i need to help this same as for update action .. please help me
Leave a comment
If you have any questions, please ask in the forum instead.
Join the conversation to share a note.