- 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
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'
and
Step 3 -> beginWidget -> 'id' and 'title'
need help
hi ,
i need to help this same as for update action .. please help me
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.