Render buttons/links/icons to display a CJuiDialog with a content / ajax-response / iframe with a single line of code.
Replace the standard CButtonColumn with the EJuiDlgsColumn of this extension to open the view and update action in a dialog like explained in the wiki articles (see Resources).
Easy using of the jQuery fancybox plugin. Works inside a ajax-enviroment.
Developed with Yii 1.1.10
Extract the zip file into protected/extensions.
Register the components in the import section of config/main.php
// autoloading model and component classes 'import'=>array( ... 'ext.quickdlgs.*', ),
Use the static methods from the EQuickDlgs class in a view to render buttons/links/icons to open a dialog. Take a look at the methods/parameters in the source of EQuickDlgs.php.
For example this can be used to display a 'More info' or 'Help' button in a form.
EQuickDlgs::contentButton( array( 'content' => 'This is the help text', //$this->renderPartial('_help',array(),true), 'dialogTitle' => 'Help', 'dialogWidth' => 200, 'dialogHeight' => 300, 'openButtonText' => 'Help me', 'closeButtonText' => 'Close', //comment to remove the close button from the dialog ) );
Use EQuickDlgs::contentLink, EQuickDlgs::contentIcon and EQuickDlgs::contentPopup the same way.
All the content of the dialog will be loaded together with the page. Use an ajax-button, if you want to load the dialogcontent on the first button-click.
A icon for the view action of the current or another controller. You have to specify the 'controllerRoute' and the 'actionParams'
EQuickDlgs::ajaxIcon( Yii::app()->baseUrl .'images/view.png', array( 'controllerRoute' => 'view', //'member/view' 'actionParams' => array('id'=>$model->id), //array('id'=>$model->member->id), 'dialogTitle' => 'Detailview', 'dialogWidth' => 800, 'dialogHeight' => 600, 'openButtonText' => 'View record', 'closeButtonText' => 'Close', ) );
If you 'reuse' a default controller view action inside a dialog, the full page (with header, menu ...) will be displayed. You have to 'renderPartial' instead of 'render'.
You simply have to replace the controller->render with EQuickDlgs::render. This will check if the request comes from a dialog. So it will work the standard way or within a dialog.
public function actionView($id) { EQuickDlgs::render('view',array('model'=>$this->loadModel($id))); //$this->render('view',array('model'=>$this->loadModel($id))); }
You will have problems if you show list, create, update, admin action views inside an ajax-dialog, because the javascript (pagination ...) will not work as expected.
You can use an iframe-dialog instead of the ajax for that purpose.
Other ajax functions: EQuickDlgs::ajaxLink, EQuickDlgs::ajaxButton, EQuickDlgs::ajaxPopup
A remote url as iframe-dialog:
EQuickDlgs::iframePopup( array( 'url' => 'http://www.yiiframework.com', 'dialogWidth' => 1024, 'dialogHeight' => 768, 'hideTitleBar' => true, 'closeButtonText' => 'Close', );
If you want to place a 'Create' button in a admin-view above the CGridView:
EQuickDlgs::iframeButton( array( 'controllerRoute' => 'create', 'dialogTitle' => 'Create item', 'dialogWidth' => 800, 'dialogHeight' => 600, 'openButtonText' => 'Create new', 'closeButtonText' => 'Close', 'closeOnAction' => true, //important to invoke the close action in the actionCreate 'refreshGridId' => 'group-grid', //the grid with this id will be refreshed after closing ) );
In this case you have to make a few changes to the actionCreate method of the controller, because the dialog should be closed after saving the record.
The content should be rendered into a 'iframe' layout, because the application header, menu ... should not be visible, but the css/js-files should be present.
Edit and modify the default iframe-layout-file 'ext.quickdlgs.layouts.iframe' for your needs.
Like above, the EQuickDlgs::render method will do the rest.
public function actionCreate() { .... if(model->save()) { //close the dialog and update the grid instead of redirect if called by the create-dialog EQuickDlgs::checkDialogJsScript(); $this->redirect(array('admin')); } //check if the iframe layout (or renderPartial) has to be used EQuickDlgs::render('create',array('model'=>$model)); //$this->render('create',array('model'=>$model)); }
Other iframe functions: EQuickDlgs::iframeLink, EQuickDlgs::iframeIcon
This buttoncolumn can be used as replacement for the standard CButtonColumn. It overrides the 'view' and 'update' buttons, the 'delete' or other custom buttons will work like inside the CButtonColumn.
'id'=>'group-grid', 'dataProvider'=>$model->search(), 'columns'=>array( 'id', 'name', .... ), array( 'class'=>'EJuiDlgsColumn', //configure like CButtonColumns: //but some properties (buttons.view.url,buttons.view.id, buttons.view.ajax, buttons.update.click ...) will be set by the component //'template'=>'{view}', 'viewButtonImageUrl'=>Yii::Yii::app()->baseUrl .'images/dialogview.png', 'buttons'=>array( 'view' => array( 'label'=> 'ajax dialog view', ), 'delete' => array( 'label'=> 'someLabel', ), ), //---------- additional config for the dialogs starts here ------------- //if you want to use a custom dialog config: default is 'ext.quickdlgs.juimodal' //'viewDialogConfig' => 'ext.quickdlgs.mycustomjuiattributes' //don't override the CButtonColumn view button //'viewDialogEnabled' = false, //the attributes for the EAjaxJuiDlg widget: use like the 'attributes' param from EQuickDlgs::ajaxButton above 'viewDialog'=>array( //'controllerRoute' => 'view', //=default //'actionParams' => array('id' => '$data->primaryKey'), //=default 'dialogTitle' => 'View detail', 'hideTitleBar' => true, //'dialogWidth' => 800, //use the value from the dialog config //'dialogHeight' => 600, ), //the attributes for the EFrameJuiDlg widget. use like the 'attributes' param from EQuickDlgs::iframeButton 'updateDialog'=>array( //'controllerRoute' => 'update', //=default //'actionParams' => array('id' => '$data->primaryKey'), //=default 'dialogTitle' => 'View detail', 'dialogWidth' => 1024, //override the value from the dialog config 'dialogHeight' => 600, ), ), ),
See the code of the EJuiDlgsColumn for more options.
As a descandant of the CButtonColumn all other attributes/possibilities are the same.
The default attributes are generated from the file 'ext.quickdlgs.config.juimodal'. You can change this by setting the property 'viewDialogConfig'.
The button 'view' will open an ajax-dialog, the 'update' an iframe-dialog. So you have the change the code of the actionView and the actionCreate like above.
public function actionView($id) { EQuickDlgs::render('view',array('model'=>$this->loadModel($id))); //$this->render('view',array('model'=>$this->loadModel($id))); } public function actionUpdate($id) { .... if(model->save()) { //close the dialog and update the grid instead of redirect if called by the update-dialog EQuickDlgs::checkDialogJsScript(); $this->redirect(array('admin','id'=>$model->id)); } //check if the iframe layout (or renderPartial) has to be used EQuickDlgs::render('update',array('model'=>$model)); //$this->render('update',array('model'=>$model)); }
The EJuiDlgsColumn does all the coding explained in the wiki-articles.
Tip: You can add an additional buttoncolum to list the records of a related model.
Assume you have a 'function actionList($parentId)' in a MemberController with a view that uses CListView and the records are filtered by the 'parendId'.
Because of the js-code in the view (CListView with pagination...) you should use the iframe-dialog of the 'update' button (not the ajax of the view button).
$this->widget('zii.widgets.grid.CGridView', array( 'id'=>'mygrid', 'dataProvider'=>$model->search(), 'columns'=>array( 'id', 'name', ... array( 'class'=>'EJuiDlgsColumn', //all default for the view, update ), array( 'class'=>'EJuiDlgsColumn', 'template'=>'{update}', 'updateButtonImageUrl'=>Yii::Yii::app()->baseUrl .'images/viewdetaildialog.png', 'updateDialog'=>array( 'controllerRoute' => 'members/list', 'actionParams' => array('parentId'=>'$data->id'), 'dialogTitle' => 'View detail', 'dialogWidth' => 1024, //override the value from the dialog config 'dialogHeight' => 600, ), ), ),
Use the EFancybox widget and place the items inside beginWidget and endWidget.
$widget=$this->beginWidget('ext.quickdlgs.EFancybox'); $widget->image($smallImageUrl,$largeImageUrl); //show a image-fancybox $widget->content('Some text','Lorem ipsum dolor sit amet, consectetur adipiscing elit',array('title'=>'This is the title')); //show content in a fancybox $widget->url('A fancy ajax content',$this->createUrl('fancycontent')); //ajax content $widget->url('Yii','http://www.yiiframework.com',array(),true); //iframe content $this->endWidget();
Set the fancybox options by setting 'imageOptions', 'contentOptions' and/or 'urlOptions'
$widget=$this->beginWidget('ext.quickdlgs.EFancybox', array( 'easing'=>true, 'imageOptions' => array( 'overlayColor' => '#000', 'overlayOpacity' => 0.9, 'transitionIn' => 'elastic', 'transitionOut' => 'elastic', 'speedIn' => 600, 'speedOut' => 200, ), ); $widget->image($smallImageUrl1,$largeImageUrl1); $widget->image($smallImageUrl2,$largeImageUrl2); ... $this->endWidget();
The Fancybox widget supports ajax, that means it can be used inside a ajax-environment. IMPORTANT: In this case you have to set the property directOutput=true or Yii::app()->request->isAjaxRequest.
Album example with a CListView:
Your 'album' view
$items = array(); $items[] = array('imgUrlSmall'=>...,'imgUrlLarge'=>..); $items[] = array('imgUrlSmall'=>...,'imgUrlLarge'=>..); ... $dataProvider = new CArrayDataProvider($items, array( 'keyField'=>'imgUrlSmall', 'pagination'=>array( 'pageSize'=>5, ), )); $fancyWidget=$this->beginWidget('ext.quickdlgs.EFancybox',array( 'directOutput'=>Yii::app()->request->isAjaxRequest, //important because of ajax pager 'imageOptions'=>array( 'width'=>1024, 'height'=>576, ) )); $this->widget('zii.widgets.CListView', array( 'dataProvider'=>$dataProvider, 'itemView'=>'_album', 'viewData' => array('fancyWidget'=>$fancyWidget), )); $this->endWidget();
Your _album view
... $fancyWidget->image($data['imgUrlSmall'],$data['imgUrlLarge']); ...
v2.0:
v1.2:
v1.1: Changed EJuiDlgsColumn.php
Total 20 comments
in some browsers the height="100%" do not work . blow is what i v modified (EFrameJuiDlg::renderDialogContent) :
or for simple just do it this way :
exchange the the order of defaultOptions and the iframeHtmlOptions
after do this we can explicity specify the "height" for the iframe using iframeHtmlOptions attribute !
Is it right, that you you didn't set the urlManager->urlFormat to 'path'?
The problem is, that it depends on the settings of the Yii urlManager (and maybe the rules) if I have to add more urlparams as '?....' or '&....'.
If the urlManager is set to 'urlFormat'=>'path' then a '?' is needed otherwise a '&'. To fit both urlManager settings, a possible solution in the EJuiDlgsColumn::createButtonUrl could be:
Does this work for you?
That's the same comment I referenced in my comment but the solution hasn't worked it's way into the extension yet. There are now at least two places this solution is needed.
Check
http://www.yiiframework.com/extension/quickdlgs/#c8800
When using EJuiDlgsColumn to create a dialog, I couldn't get the dialog to close automatically until I changed line 426 from
to
I couldn't get it to work as expected otherwise. This problem is similar to #8800: Problem with URL but I didn't make the same change to account for not having the url provided.
I have solved the ajax-problem in the Fancybox feature.
But in the moment it seems to be nearly impossible to do the same with a CJuiDialog without hacking the core.
I started a topic here
please help me, click this link below, please please help me any one T_T
something went wrong with my dialog (quickdlgs)
My thread, Help meeee..
Don't reload page with ajax where you defined your dialog:
in view file:
What should i do, if the CListView doing ajax update, quickdlgs popup doesnt works. i must refresh page to make popup works again. please help me, what should i do.
some people may know that the bootstrap may have some conflicts to the jqueryUi . but now the another bootstrap extension come to us Yii-Booster , and this extension introduce the small set of jqueryUi components to bootstrap see JqueryUi in Bootstrap
:)
Worked fine in Chrome, but
added in extensions config/juimodal.php to fix height for IE8 and firefox:
added in EFrameJuiDlg.php to show no border for IE8
There seems to be bug in code in EAjaxJuiDlg.php(line 82) and EFrameJuiDlg.php(line 80)
There should be code like as
instead of
Please use this forum topic to discuss this extension.
Change the generation of the link code in EBaseJuiDlg::renderButton to
Thanks for the hint, I will do this in the next release.
But don't uncomment line 332, the EJuiDlgsColumn will not work. I have changed my answer below...
Thanks uncommenting line 332 worked. Now one more help when the javascript is disabled how can we let the url open the request content normal as ordinary url incase the dialog fails. In one of my files I had implemented like this so that when js is enabled the dialog open and if js is disabled the url will point to the respective page normal way. Thanks.
You can set the property 'contentWrapperHtmlOptions'=>array(style=>'display:none') in the config/juimodal.php or in the attributes when calling EQuickdlgs::xxx
Best regards
I have tested it but need a way to not show the content in case javascript is disable where can I include something like the code below.
Thanks for the hard work.
c@cba, thanks for this hint. I have found some more bugs in v1.0 :-(
In v1.1 I did change the properties from EJuiDlgsColumn for more flexibility, not compatible with v1.0. Hope upgrading its not to much work for those who are using this component.
Hi Joblo,
I'm using the
EJuiDlgsColumnin my CGridview.Previously I had a customized 'Delete' Button in my CButtonColumn like this:
When I switched to using EJuiDlgsColumn, these options were not recognized (the 'Delete' button behaved in the default Yii-way).
Changing the first line of the
init()function in EJuiDlgsColumn.php like the following solved my problem:Thanks again for the extension.
Best regards...
Leave a comment
Please login to leave your comment.