jQueryUIのダイアログで、ダイアログ内のボタンクリックをトリガーとして待つような書き方に戸惑ったのでシェアします。
結論としては、「ボタンのクリックイベントをどこに定義するか」に気をつければキレイに書けました。
動きの確認
やりたい事は、以下のような流れで処理を行いたいです。
- ダイアログの表示ボタンをクリックする。
- ダイアログが表示される。
- ダイアログの閉じるボタンをクリックする
- ダイアログが閉じる。
以下実際の動き。単純なダイアログ。
コード
解説
index.html
html側はボタンの定義と、ダイアログ部分の定義のみ。特筆すべき所は無いかなと思います。
<!DOCTYPE html> <html> <head> <link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/jquery.ui/1.12.1/themes/black-tie/jquery-ui.css"> </head> <body> <button id="open-dialog">ダイアログ表示</button> <div id="dialog" style="display:none"> <button id="close-dialog">閉じる</button> </div> <script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.4.1.min.js"></script> <script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/jquery.ui/1.12.1/jquery-ui.min.js"></script> <script type="text/javascript" src="./script.js"></script> </body> </html>
script.js
ダイアログの表示/非表示処理を書くJavaScript側。ポイントは、ダイアログ表示/非表示処理部分を丸ごと別関数にして、その中でクリックイベントを定義、Promiseを返す。
jQuery.noConflict(); (function($) { const confirmDialog = function() { $("#dialog").dialog(); return new Promise(function(resolve, reject) { $("#close-dialog").click(function(e) { $("#dialog").dialog("close"); resolve(); }); }); }; $("#open-dialog").click(function(e) { console.log("ダイアログを表示しました"); confirmDialog().then(function(resp) { console.log("ダイアログを閉じました"); }); console.log("ここの処理は先に実行されてしまう"); }); })(jQuery);
幾つかconsole.log()を書いていますが、期待した通りに表示されている事がわかります。2個目のログで出力されているように、Promiseチェーンの外に書いた処理は先に実行されるので注意。
script.js:14 ダイアログを表示しました script.js:18 ここの処理は先に実行されてしまう script.js:16 ダイアログを閉じました