How to avoid rendering entire page on AJAX call for CGridView and CListView

12 followers

This wiki article has not been tagged with a corresponding Yii version yet.
Help us improve the wiki by updating the version information.

CGridView and CListView are great widget to populate records and also provides features like ajax update, column sort, search, drop-down filter, ajax content load and many more...

Both works great but has lankness in Ajax content load. When it request for next page content then Ajax comes with entire web page content and off-course executes all scripts before send output.

Not understanding Anh...., Don't worry see it in action by your self. If your are using any CGridView/CListView then click on any next page and see response using FireBug. There will be entire page content instead only grid/list view content.

Do Fix

Lets go to apply some tricks to prevent entire page content output and script execution...

Step 1: Create a partial view file for CGridView or CListView

Create Partial File: __grid_view_for_subscriber.php

$this->widget('zii.widgets.grid.CGridView', array(
  'id' => $grid_id,
  'dataProvider' => $subscriberActiveDataProvider,
  'columns' => array(
    'first_name',
    'last_name',
    'designation',
    'company',
    'subscribed_on',
  ),
));

Step 2: Main view file

Create View File: subscribers_list.php

/* @var $this SubscriberController */
 
$this->pageTitle = 'Subscribers';
 
// Render partial file created in Step 1
$this->renderPartial('__grid_view_for_subscriber', array(
  'subscriberActiveDataProvider' => $subscriberActiveDataProvider,
  'grid_id' => $grid_id,
));

Step 3: Controller Class

Controller Class: SubscriberController.php

class SubscriberController extends Controller {
  //
 
  public function actionList() {
    $criteria = new CDbCriteria();
    // Add your Query condition here
    // $criteria = 'your condition here';
 
    // Create `activeDataProvider` object for Subscriber model
    // NOTE: Subscriber model is not included in this article
    // Replace model name with your's
    $subscriberActiveDataProvider = new CActiveDataProvider('Subscriber', array(
      'criteria' => $criteria,
    ));
 
    $grid_id = 'subscriber_grid';
 
    // Check is for AJAX request by `subscriber_grid`
    // ajax response only grid content instead entire web page
    if(Yii::app()->request->isAjaxRequest && isset($_GET['ajax']) && $_GET['ajax'] === $grid_id)) {
      // Render partial file created in Step 1
      $this->renderPartial('__grid_view_for_subscriber', array(
        'subscriberActiveDataProvider' => $subscriberActiveDataProvider,
        'grid_id' => $grid_id,
      ));
      Yii::app()->end();
    }
 
    // Render main view file created in Step 2
    $this->render('subscribers_list', array(
      'subscriberActiveDataProvider' => $subscriberActiveDataProvider,
      'grid_id' => $grid_id,
    ));
 
  }
 
  //
}

: THANKS :

Total 5 comments

#14150 report it
kiran sharma at 2013/07/23 03:06am
I am using this method to avoid rendering whole page.
#13818 report it
trond at 2013/06/28 03:37am
@cgabbanini

I guess that is a matter of taste. There isn't really any code duplication in the original solution, since the main view file just includes the partial view.

#13816 report it
cgabbanini at 2013/06/28 02:10am
Another approach

Hi, Thanks for your suggestion. Perhaps another suitable approach could involve changing your view file in the following way, avoiding any code duplication:

<?php if(!Yii::app()->request->isAjaxRequest): ?>
          // Content not to be show on ajax requests ...
<?php endif; ?>
      // Content to be shown on every request ...
#13812 report it
Junior - df9 at 2013/06/27 07:21pm
Very good tip

Thank you!

#13801 report it
trond at 2013/06/27 06:08am
Interesting

So to keep the response to the ajax requests lean, you move the parts needed for the ajax call out to a separate file so that it can be called directly with render partial from the controller.

I guess it is worth while to study the output of the ajax call before the re-factoring to determine how much can be gained from this. For a complex web the gain could be substantial, but for a simple web it may not be worthwhile.

Leave a comment

Please to leave your comment.

Write new article