You are viewing revision #2 of this wiki article.
This is the latest version of this article.
You may want to see the changes made in this revision.
If you started playing with Yii2's new GridView, you will soon realize that some things have improved quite a lot, but I am sure its going to be a bit confusing at first glance when you try to modify certain javascript behaviors like for example, its delete confirmation dialog box.
I am sure there will be others finding better solutions, but on my case, I found the following quite simple to execute. On this article I am going to show you how to use the excellent library "BootboxJS" to display our confirmation box. So, the first thing you need to do is to download that library and place it on your "web/js" folder (I am using the basic template application structure for the example).
Override Yii.js Module
The first thing we need to do is to override the methods "confirm" and "allowAction" on the yii.js module. The reason is that the module is the responsible of handling the click events of our rendered ActionColumn action links.In order to override its methods, lets create a javascript file named "main.js" (for example) and we are going to place it on our "web/js" folder. These are the contents:
yii.allowAction = function ($e) {
var message = $e.data('confirm');
return message === undefined || yii.confirm(message, $e);
};
yii.confirm = function (message, $e) {
bootbox.confirm(message, function (confirmed) {
if (confirmed) {
yii.handleAction($e);
}
});
// confirm will always return false on the first call
// to cancel click handler
return false;
}
Bootbox confirm by default doesn't have a title, to add a title (modal-title) to your confirm box, use this code instead:
yii.allowAction = function ($e) {
var message = $e.data('confirm');
return message === undefined || yii.confirm(message, $e);
};
yii.confirm = function (message, $e) {
bootbox.confirm({
title: 'Confirm',
message: 'Are you sure?',
callback: function (result) {
if (result) {
yii.handleAction($e);
}
}
});
// confirm will always return false on the first call
// to cancel click handler
return false;
}
The way the module comes by default is by using the native browser's confirm dialog window that obviously stops the asynchronous execution of Javascript, but when you try to use "bootbox::confirm" method, that is not happening as the callback of the plugin does not return until the user clicks on one of the dialog's buttons.
Thats the reason we override the "yii::confirm", because we require the reference of the DOM object in order to call "yii::handleAction" properly. But is "yii::allowAction" the method who receives that reference, and thats why we had to override that method as well.
With this solution, the "yii::allowAction" will return false the first time, but "bootbox::confirm" will react according to user's action. Thats the price you pay, but it works.
Register Your Assets
There is one last thing to do, modify our application's asset bundle to register both "bootbox.min.js" and "main.js" script files.For that we go to our "assets/AppAsset.php" file and write the following:
namespace backend\assets;
use yii\web\AssetBundle;
class AppAsset extends AssetBundle
{
public $basePath = '@webroot';
public $baseUrl = '@web';
public $css = ['css/site.css'];
// register the library first after our
// script
public $js = ['js/bootbox.min.js', 'js/main.js'];
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap\BootstrapAsset',
];
}
And thats it, next time we click on the delete action of our grid, we will see a beautiful Bootstrap Confirm dialog.
Cannot make it work...
Upon clicking the delete icon I'm redirected immediately to the error page with a "Method Not Allowed (#405)" error. For some reason it's making a GET request instead of a POST request which is rejected by the controller. FireBug confirms that both scripts are loaded at first; after the error page is show I click on the browser's back button and only bootbox.min.js loads. Any ideas?
Thanks,
not work for me too!
I got this error:
$e.data() is not function
i v tried this --- > add debug line using alert:
if (confirmed) { alert("type of $e "+$.type($e)); yii.handleAction($e); }
seems the type of $e is a function !!!!
How make it work at YII v2.0.0
yii.js was changed on september 2014. Here is my code that works on new version:
// --- Delete action (bootbox) --- yii.confirm = function (message, ok, cancel) { bootbox.confirm( { message: message, buttons: { confirm: { label: "OK" }, cancel: { label: "Cancel" } }, callback: function (confirmed) { if (confirmed) { !ok || ok(); } else { !cancel || cancel(); } } } ); // confirm will always return false on the first call // to cancel click handler return false; }
Double confirm
The confirm popup is coming two times when I click on a submit button.
By a normal link it works fine. AS I have see, in yii2 the form will be update after the first confirm and raise the click event of the button again.
Any solution?
How to make it work with pjax gridview refresh
Radek's code is working, but when I click 'ok', the page refreshes, but it should trigger pjax reload, how can I do this?
$.pjax.reload({container: '#grid-pjax'});
Modal windows appear greyed out
I'm using the latest version of Yii 2.0.2.
I don't get any error, but when the modal window appear, she is greyed out.
It's impossible to click on anything, nor OK or cancel or anything.
Any ideas welcome ?
confirm box, default on cancel action
Hi, is it possible, in the confirm box, to change the default focus from "ok" to "cancel"? So if a user hit the "enter" button it would cancel the operation?
Thank you
Dropped
yii.allowAction()
Dropped
yii.allowAction()
and modifiedyii.confirm()
… on Sep 7, 2014https://github.com/yiisoft/yii2/commit/b4c4b4053a72b3cffaf64393ff438ff45b1c99f2
PERFECT!!!
Works like a charm!!
And better... no need to change anything under vendor. Wonderful article and very well explained.
In new versions of Yii you must use Radek's code on main.js.
// --- Delete action (bootbox) --- yii.confirm = function (message, ok, cancel) { bootbox.confirm( { message: message, buttons: { confirm: { label: "OK" }, cancel: { label: "Cancel" } }, callback: function (confirmed) { if (confirmed) { !ok || ok(); } else { !cancel || cancel(); } } } ); // confirm will always return false on the first call // to cancel click handler return false; }
(THIS IS RADEK'S CODE. NOT MINE.)
Note:
If you use Yii advanced template, place your js files usually under something like /public_html/your_app/frontend/js.
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.