Escape from Default’s Yii2 Delete Confirm Box

EDIT: Article has been updated with latest changes on Yii2 yii.js API.

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, ok, cancel) {
    bootbox.confirm(message, function (confirmed) {
       if (confirmed) {
         !ok || ok();
       } else {
         !cancel || cancel();
       }
    });
    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.

bootbox dialog

7 comments

  1. Hashie5   •  

    Awesome! Please keep adding more yii2 articles, they’re very interesting.

  2. yiqing-95   •  

    thanks for sharing it , and keep writing .

  3. makro   •  

    It works but… if I press OK it only closes dialog but doesn’t act like a normal js alert…

  4. Antonio Ramirez   •     Author

    It has been changed… will update the post

  5. Antonio Ramirez   •     Author

    The results should be the same… check how its implemented on the confirm.

Add Comment Register



Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>