Render a view in a CJuiDialog using AJAX

Currently I’m doing it like this:


<?php

$this->beginWidget('zii.widgets.jui.CJuiDialog', array(

    'id'=>'mydialog',

    'options'=>array(

        'title'=>'Enquiry Details',

        'autoOpen'=>false,

	'height'=>600,

	'width'=>450,

	'show'=>'fade',

	'hide'=>'fade',

    ),

));


echo $this->renderPartial('_view', array('model'=>$model));


$this->endWidget();


echo CHtml::link('open dialog', '#', array(

   'onclick'=>'$("#mydialog").dialog("open"); return false;',

));

?>

I want to change the functionality so that when the link is clicked the view is rendered using AJAX (so that the latest data is fetched).

Try something like:




<?php

$this->beginWidget('zii.widgets.jui.CJuiDialog', array(

    'id'=>'mydialog',

    'options'=>array(

        'title'=>'Enquiry Details',

        'autoOpen'=>false,

        'height'=>600,

        'width'=>450,

        'show'=>'fade',

        'hide'=>'fade',

    ),

));

<div id="forAjaxReplace">

echo $this->renderPartial('_view', array('model'=>$model));


$this->endWidget();


echo CHtml::link('open dialog', '#', array(

   'onclick'=>CHtml::ajax( [...]

	'success'=> 'function(data){

		$("#forAjaxReplace").html(data);

		$("#mydialog").dialog("open"); 

		return false;

	}',

	)

));

?>



Hi Zaccaria,

That almost works, except the whole page is now being displayed in the dialog - I only want the partial view to be displayed.

Hello,

are you sure you used renderPartial() and not just render() ? ::) ;)

(both in the view and in the controller’s action called by ajax)

bye,

Giovanni.

The solution of zac is good, i just would change its code that the layer to update, doesnt need to have any contents at first as is going to be updated before displaying the dialog.

You probably see the whole page displayed because that you point to the wrong action and on url not found your app resolves to the index page or you dont have renderPartial on your ajax response followed by a Yii::app()->end();

Hi guys,

Basically there is no controller action for this, I’m just trying to enclose a view within the CJuiDialog.

Here is my updated code:


<?php

$this->beginWidget('zii.widgets.jui.CJuiDialog', array(

    'id'=>'mydialog',

    'options'=>array(

        'title'=>'Enquiry Details',

        'autoOpen'=>false,

	'height'=>600,

	'width'=>450,

	'show'=>'fade',

	'hide'=>'fade',

    ),

));

?>


<div id="forAjaxReplace">

<?php echo $this->renderPartial('_view', array('model'=>$model)); ?>

</div>


<?php

$this->endWidget();


echo CHtml::link('open dialog', '#', array(

   'onclick'=>CHtml::ajax(array(

        'success'=>'function(data){

            $("#forAjaxReplace").html(data);

            $("#mydialog").dialog("open");

            return false;

        }') 

    )

));

?>

What happens is that the whole page (i.e. the page that calls the dialog) gets displayed in the dialog. When I don’t use AJAX (as per my original post) then only the partial view is displayed.

Your action should be something like:




public function actionMyAction()

{

   [...]

   if(Yii::app()->request->isAjaxRequest)

      $this->renderPartial('_view', array('model'=>$model));

   else

      $this->render('CompleteView', array('model'=>$model));

}




In such way, you will be rendering only your subview in case of ajax request.

As Antonio Ramirez stated, as in this case we are doing the ajax refresh before calling dialog, you can replace even the div #mydialog, but if you are replacing once again, you will have some problem because the CJuiDialog will generate some extra content inside the main div, so you will have to recall dialog.

I usually place an extra div inside the dialog for have something of safe to replace.

I see. That work’s for me. But how come we have to renderPartial() the same view in both the view and the controller?

Actually I took out the renderPartial() from the view file - the content is displayed through the AJAX call but the CSS formatting is not there. The content of the partial view file is a CDetailView widget. It seems that the CDetailView CSS file does not get registered, perhaps because it is being called via the controller and not the view file…

Exactly GSTAR, this is happening when you call renderPartial(). If you wish CSS formatting for your ajax calls, you should register all necessary CSS files from your main render(). Assuming that consecuent AJAX calls, will bring HTML blocks with styles already registered.

Cool, just one more question. When clicking on the link, the ‘#’ still gets put in the address bar, i.e. the ‘return false’ does not seem to be working…

I think that you need to put the return false; ‘after’ the CHtml::ajax — :) as in the way it is now, return false is executed within the ‘success’ callback function.





'onclick'=>CHtml::ajax( [...]

        'success'=> 'function(data){

                $("#forAjaxReplace").html(data);

                $("#mydialog").dialog("open"); 

                // return false; // <--- NOT HERE!

        }',

        ). ';return false;' // <---- HERE! 




Cheers. Now do you have any idea how I can put that jQuery code in to a ‘click’ event listener (using Yii::app()->clientScript->registerScript)

I tried it like this but it’s not working for me:


Yii::app()->clientScript->registerScript("dialog", "

$('#dialog_link').click(function(){

	success: function(data){

		$('#forAjaxReplace').html(data);

		$('#mydialog').dialog('open');

	};

	return false;

});

");

of course is not working GSTAR,

have you seen what it does?

you are telling that when #dialog_link is clicked a function should be fired that does:

success: function(data){

// bla bla bla

};

return false;

there is nothing to do there!!! you need to call any of the $.ajax calls from jquery within the function(){} body.

review your ajax call my friend

I have no idea about this my friend :unsure:

Here you go:




Yii::app()->clientScript->registerScript("dialog",

      "$('#dialog_link').click(function(){

        jQuery.ajax({

            type: 'POST',

            url: '".$url."',

            success: function(html){

               jQuery('#yourID').html(html);

         }});

         return false;

       });",

      CClientScript::POS_READY);



You can also use the CHtml helper (it changes nothing, just looks more yii):




Yii::app()->clientScript->registerScript("dialog",

      "$('#dialog_link').click(function(){".

       CHtml::ajax(array('success'=> "function(html){jQuery('#yourID').html(html); }})<img src='http://www.yiiframework.com/forum/public/style_emoticons/default/wink.gif' class='bbc_emoticon' alt=';)' />

       ."  return false;

       });",

      CClientScript::POS_READY);