Bootstrap の Modal と jQuery の Deferred を使って confirm もどき

Bootstrap の Modal を confirm の代わりとして使いたい時がありますよね。そんなときに Modal と jQuery.Deferred を組み合わせるといいかなと思ったので試してみました。

JavaScript · Bootstrap

Deferred Object | jQuery API Documentation

まず html。ほぼ Bootstrap のドキュメントにあるサンプルそのままです。実際には動的に作るか埋め込んでおくのかなと思います。

<div id="confirm" class="modal fade">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                <h4 class="modal-title"></h4>
            </div>
            <div class="modal-body">
                <p></p>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-primary">はい</button>
                <button type="button" class="btn btn-default" data-dismiss="modal">いいえ</button>
            </div>
        </div>
    </div>
</div>

次にメインの javascriptjQuery のクラスメソッドとして追加しています。(これもプラグインって言うんでしょうかね。)

(function($) {
    $.confirm = function(title, message) {
        var deferred = $.Deferred();

        var $element = $("#confirm");
        $element
            .data("resolve", false) // resolve するかどうかのフラグ
                // タイトルを設定
                .find(".modal-title").text(title).end()
                // メッセージを設定
                .find(".modal-body p").text(message).end()
            //「はい」ボタンのクリックイベント
            .on("click", ".btn-primary", function() {
                // resolve フラグを立てて、モーダルを閉じる
                $element
                    .data("resolve", true)
                    .modal("hide");
            })
            // モーダルの非表示イベント
            .one("hidden.bs.modal", function() {
                $(this).off("click", ".btn-primary");

                // resolveフラグをみて resolve か reject
                if($(this).data("resolve")) {
                    deferred.resolve();
                } else {
                    deferred.reject();
                }
            })
            .modal({ show: true });

        return deferred.promise();
    };
})(jQuery);

使い方はこんな感じ。

$.confirm("確認", "今夜は焼き肉?")
    .done(function() {
        // 「はい」ボタンがクリックされた
        alert("やったね!");
    } )
    .fail(function() {
        // 「いいえ」ボタンや「×」ボタンがクリックされた
        alert("残念><");
    });

こういうのを用意しておくと、他の Deferred オブジェクトと組み合わせることができるので便利かなと思いますし、読みやすいかなって気もします。

どうですかね。