Yii 1.1: Avoiding duplicate script download when using Ajax calls to render different Views



I had to partially render two types of views, depending on user selection. Wanted to display a GRID or a LIST style with an event that AJAX'ed new contents and update a layer with them.

Views exposed

The Grid View
Grid View
The List View
List View
If you see the buttons on the right of the box, you will identify those who change from Grid to List and viceversa.

The issue

Until then all was easy, the issue came when both views had to be processed to render the scripts that provide the dynamics of the grid or the list rendered. I couldn't do it on AJAX calls as I realized that every time a request was made and the partial views had its contents processed (review parameters of renderPartial), the scripts where downloaded again and again, making sometimes multiple function binding to the buttons.

The solution

The only way to do it was to register the required scripts of both partial views on the view that will render the buttons that perform AJAX requests. This is how I did it:

// workaround to register required scripts for grid and list
// $view is a variable with selected or primary option
// and _list and _grid where the two partial views to render
$fake = $this->renderPartial(($view==='_grid'?'_list':'_grid'),
                             array('model'=>$model), true, true); 
echo $this->renderPartial($view, array('model'=>$model), true, false);

As you can see, $fake is used to process the partial view required scripts and hold the contents that will not be rendered. After doing this, AJAX calls to the controller can return the contents of views without the need to process its output anymore:

public function actionIndex()
      $model = new MyModel('search');
      // style to display?
      $r = Yii::app()->getRequest();
      $view = $r->getParam('style',false)?'_'.$r->getParam('style') : '_grid';
         // now we render the views without the need to process
         // output anymore 
      $this->render('index', array('model'=>$model,'view'=>$view));

Total 6 comments

#18046 report it
Antonio Ramirez at 2014/09/02 03:28am

This is an error that normally occurred when you (on the same controller's action) have a render and renderPartial with processOutput parameter set to true.

If you have previously rendered the main view with render all your assets are registered and if, on the same controller's action, you call renderPartial with process output, the same files are registered by CClientScript behind the scenes (as it happens with the main rendering).

That means that the same asset files are re-registered, once on the main render and again with renderPartial with output process set to true.

Hope this helps to clarify

#16396 report it
styopdev at 2014/02/19 02:34am

You have not explained full how use this method, how i can check if style or scripts exist, for send false from frontend.

#6379 report it
Antonio Ramirez at 2012/01/04 06:21pm
Re: Code relation/place

What you need to do is to render the grids normally on your first render and when you renderPartial the ajax requests you DO NOT process output (check fourth parameter of the function).

The strange repeats is due that the scripts are re-rendered thus re-binding the js events to the elements on the page.

#6367 report it
brecht at 2012/01/03 12:37pm
Code relation/place


I don't really get your explanation, where does the code go? I don't get the connection between the first and the second part.

my problem: I have two grids in one page, each of them first rendered without ajax-call on page-request. After this, ajax request to replace the grids using partialRender.

When the link with the ajax request is clicked, it goes well, after this, i get strange repeats of the requests.

#5152 report it
Maurizio Domba Cerin at 2011/09/19 06:36am
Re: Layout


This is a commercial theme design

#5129 report it
prchakal at 2011/09/17 12:06am


Can you give the layout (html/css/js) of the pages that is showed in your screenshot?


Leave a comment

Please to leave your comment.

Write new article