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.
Questions:
how do I revert to do the original behavior? I cannot figure out how to use ajaxUpdateError.
wouldn’t it be nice to have an option for the original behavior ?? It is quite a nuisance to have it broken.
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]
[edit 2]
looks like this issue was already reported and fixed
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.
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 ?
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.
Yii::import('zii.widgets.grid.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
parent::init();
}
}
nearly all of my controllers do not have their own ‘delete’ action. Example from CoursesController.php:
public function actionDelete() {
parent::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
$this->loadModel()->delete();
// if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser
if (!isset($_GET['ajax']))
$this->redirect(array('admin'));
}
else
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
'errorHandler'=>array(
'errorAction'=>'site/error',
),
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));
break;
}
default: {
$this->render('error', $error);
break;
}
}
} 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'];
SO:
if the user has delete privs, they see a "delete" (red X) icon in a CButtonColumn of the GridView
if they press the delete button, first they get the ajax "are you sure" confirmation
then the actionDelete() executes
if the deletion is blocked (typically because child records exist and we do not want cascade-delete), then a custom exception 601 is thrown
exception is caught by SiteController.ActionError()
this rendersPartial system/601 view
which echoes the error message
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.