help with CGridView.ajaxUpdateError

Prior to 1.1.7 my controller could return an ajax response for CGridView "delete" action, which would be rendered in an Alert.

I just installed 1.1.7 and this behavior is gone. My controller still returns the same response, but it is no longer automatically rendered as an Alert.


  1. how do I revert to do the original behavior? I cannot figure out how to use ajaxUpdateError.

  2. wouldn’t it be nice to have an option for the original behavior ?? It is quite a nuisance to have it broken.

This change was enhancement request #1792

changed by r2921 by mdomba…e/detail?r=2921


I was originally just echo’ing text. I’ve tried throwing an error, and also setting response headers to something other than 200, to force js code to recognize the error. Nothing works.

I’ve set the response header to 401 and firebug shows an error. But the “loading” indicator never goes away. Looks like neither the Success nor Error cases of $.fn.yiiGridView.update are getting called. In fact, setting firebug breakpoints inside the success: and error: declarations, neither of them is invoked after the response. Why ??


[edit 2]

looks like this issue was already reported and fixed…e/detail?r=3151

[/edit 2]

[edit 3]

seems the problem is partly fixed. At least now I get the error message, using r3151. but now if deletion succeeds the grid is not updated as it was previously.

[/edit 3]

The issue #1792 was to fix an error that would display an empty alert in the case that a user refreshes or goes to another page while ajax is in progress… so I think some other issue is in question…

I really don’t see how that worked in Yii 1.1.6… as an alert was issued only when ajax had an error (if the request fails)… if you just echoed a text that would not be shown unless you are setting even a header…

Can you post here your code that worked for you in Yii 1.1.6?

If the delete is successful… then the error should not be fired…

Seem you are mixing here different things… so you want your ajax to be successful (deleted done)… but at the same time to fire an ajax error event to display an alert ?

The main function of afterDelete -

is to give the programmer a way to do something after the delete happened… check the documentation… you have there even an example…

Perhaps the topic of this post should have been "problems with CGridView in 1.1.7". Things worked fine in 1.1.6, but broke in 1.1.7. r3151 fixed part of the problem, but not all.

My setup is:

a typical ‘admin.php’:

$this->widget('DRGridView', array(

	'id' => 'courses-grid',

	'dataProvider' => $model->search(),

	'filter' => $model,

	'pager' => array('class' => 'DRLinkPager', 'cssFile' => Yii::app()->request->baseUrl . '/css/pager.css'),

	'columns' => array(

    	//show update button if user has privs

    	array('class' => 'EButtonColumnWithClearFilters',

        	'template' => (Yii::app()->user->checkAccess('coursesUpdate') ? '{update}' : '')),


        	'name' => 'LocationId',

        	'filter' => Locations::model()->LocationList(),




        	'name' => 'CourseTypeId',

        	'filter' => CHtml::listData(CourseTypes::model()->findAll(), 'CourseTypeId', 'CourseTypeId'),





    	// show delete button if user has privs

    	array('class' => 'CButtonColumn',

        	'template' => (Yii::app()->user->checkAccess('coursesDelete') ? '{delete}' : ''),

        	'header' => CHtml::dropDownList('pageSize', DRHelper::getPageSize($this->modelClass),


            	array('onchange' => "$.fn.yiiGridView.update('courses-grid',{ data:{pageSize: $(this).val() }})")





DRGridView extends CGridView:


class DRGridView extends CGridView {

	public function init() {

    	// customize the summary/pager/grid locations.

    	// per #755, put the summary and pager above the grid.

    	// if the user has > 20 items/page for this model, show a 2nd pager below the grid

    	if (DRHelper::getPageSize(Yii::app()->getController()->modelClass) > 20) {

        	$this->template = '{summary}{pager}{items}{pager}'; 

    	} else {

        	$this->template = '{summary}{pager}{items}';


    	$this->cssFile = false; // stylesheet is included by app/views/layouts/main




nearly all of my controllers do not have their own ‘delete’ action. Example from CoursesController.php:

	public function actionDelete() {



they inherit from a common parent DRController. Here is the delete action:

	public function actionDelete() {

    	if (Yii::app()->request->isPostRequest) {

        	// we only allow deletion via POST request


        	// if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser

        	if (!isset($_GET['ajax']))




        	throw new CHttpException(400, 'Invalid request. Please do not repeat this request again.');


all of my models extend DRActiveRecord, which extends CActiveRecord. The beforeDelete() action of DRActiveRecord is fairly long, but here’s the important part:

    	if ($blocked || $preBlocked) {

        	// JJD 5/4/10 if ajax context (CGridView deletion), use error page 601 (custom Delete error) which is just the text

        	// otherwise return false, and Admin view will render all errors inline

        	if (yii::app()->getRequest()->isAjaxRequest) {

            	$out = '';

            	foreach ($this->errors as $errname => $errtext) {

                	foreach ($errtext as $name => $val) {

                    	$out .= $val . chr(13) . chr(10);



            	throw new CHttpException(601, $out);


        	return false; // always


I have a site-wide error-handler installed in config/main


    	// redirect all errors through the site/error action so we can show an error message wrapped in our normal layout




My SiteController.actionError()

	public function actionError() {

    	$this->setActionLabel(Yii::t('DR', 'Error'));

    	if ($error = Yii::app()->errorHandler->error) {

        	switch ($error['code']) {

            	case '601': {

                    	// raised by DRActiveRecord.beforeDelete() if child records exist

                    	$this->renderPartial('/system/error601', array('data' => $error));



            	default: {

                    	$this->render('error', $error);




    	} else {

        	// do nothing.  Qiang's notes say the user could have manually requested the error URL.



my views/system/error601.php

	// JJD 1/18/11 custom 601 error - ajax version.

	// raised by DRActiveRecord.beforeDelete() method if deletion fails due to child records

	echo Yii::t('DR','Deletion Failed:'). chr(13) . chr(10);

	echo $data['message'];


  1. if the user has delete privs, they see a "delete" (red X) icon in a CButtonColumn of the GridView

  2. if they press the delete button, first they get the ajax "are you sure" confirmation

  3. then the actionDelete() executes

  4. if the deletion is blocked (typically because child records exist and we do not want cascade-delete), then a custom exception 601 is thrown

  5. exception is caught by SiteController.ActionError()

  6. this rendersPartial system/601 view

  7. which echoes the error message

  8. in 1.1.6, the error message is displayed as a javascript alert

in base 1.1.7 (r3135) this was completely broken. the spinning-icon never disappeared, and no error was displayed

r3151 fixed the problem with rendering the js alert, assuming no ajaxUpdateError was specified

however r3151 still has the problem that if the deletion succeeds, the grid is never refreshed, and the spinning icon does not disappear

if I revert CButtonColumn to the 1.1.6 version (r2877) everything works fine, even if I still have jquery.yiigridview.js from r3151

Sorry for the long explanation. I got tired last night and gave up, but will continue debugging and post more as/when I find something.

After updating CButtonColumn.php and jquery.yiigridview.js to r3191 (current trunk version) things appear to be working properly again:

1.A correct error message ( js alert) is shown, and loading-indicator goes away, when deletion fails

  1. the grid refreshes properly and loading-indicator goes away, when deletion succeeds.

Something in the most-recent versions fixed the problems described earlier today.

Maybe the above post will help someone having a similar problem.