Yii 1.1: How to apply a layout to an AJAX update

4 followers

The background

The template system in Yii is quite flexible. By default you have three layers of content:

  1. The Main template holds the header, main navigation and footer
  2. One or more layout files holds the column setup, sub navigation etc.
  3. The view files hold the actual page content.

When you load a page, the render method does the following:

  1. Renders the view file.
  2. Decorates the view with the layout.
  3. Apply the template to the layout.

An AJAX call is normally much more lightweight (and much faster). If you use renderPartial with the processOutput parameter set to false, neither the layout nor the template is never added to the output. All you get is the content produced by the view file.

The problem

Sometimes, however, it can be useful to also switch the layout on an AJAX update, without having to load the whole page with the full overhead of CSS files, javascript, fonts etc. So what we need is a way to render the view file and have it embedded in the layout without also getting the template file applied. That is still much faster than loading the full page.

The solution

The following code snippet from a controller action specifies the view to be rendered and the layout to be applied. For an AJAX update, a renderPartial is used to generate and return the view file. Then a CContentDecorator is created to apply the layout.

switch ($page) {
            case 1:
                $this->layout = '//layouts/teamPlayers';
                $view = 'dashboardPlayers';
                break;
 
            case 2:
                $this->layout = '//layouts/teamEdit';
                $view = 'dashboardEdit';
                break;
 
            default:
                Yii::app()->end();
        }
 
        if (Yii::app()->request->isAjaxRequest) {
            $output = $this->renderPartial($view, $params, true, false);
 
            $params['template'] = '';
            $ContentDecorator = new CContentDecorator;
            $ContentDecorator->view = $this->layout;
            $ContentDecorator->data = $params;
            $ContentDecorator->processOutput($output);
        } else {
            $this->render($view, $params);
        }

Finally the layout file(s) (located in protected\views\layouts) are modified by replacing the beginContent statement with the following code snippet:

<?php
if (isset($_data_['template'])) {
    $this->beginContent($_data_['template']);
} else {
    $this->beginContent('//layouts/dashboard');
}
?>

Be the first person to leave a comment

Please to leave your comment.

Write new article
  • Written by: trond
  • Updated by: CeBe
  • Category: How-tos
  • Yii Version: 1.1
  • Votes: +1
  • Viewed: 2,267 times
  • Created on: Feb 11, 2014
  • Last updated: Apr 14, 2014
  • Tags: AJAX, views