ホームページ制作/SEO対策なら株式会社サイバーブレーンへ

 03-5961-5681 平日10:00~19:00

 2018-10-24

HTML5 <dialog> - ダイアログ要素

よくある確認ダイアログの失敗談です。
管理機能で、データ一覧に削除ボタンを配置して、クリックされたら確認画面を出力して「OK」がクリックされたら削除を実行する。
といった管理ページの確認画面で、
(簡易的な画面でわかれば良いという要件があるときに)
削除確認はJavaScript標準の window.confirm()を使っていたのですが、この操作を繰り返しているとブラウザで文言の下に「このページによる追加のダイアログ表示を抑制する」といったチェックBOXが出力される(何度めかの出力で)。
そこにチェックを入れると確認ダイアログが出ないので、次に削除をクリックすると無反応状態になり、利用者側からは「削除」ができなくなったので調べてほしいという問い合わせに繋がります。
最終的に画面をみながら理由を丁寧に説明していくと納得していただけるのですが、当然この抑制のチェックボックスを出さないようにしたいので、ダイアログを自前で作る、或いはjQuery等のライブラリーを利用して構築することになります。
これはこれでライブラリーが必須になる(自作の場合は汎用性を考慮すると時間がかかる)ので、HTML5(5.1〜かな?)で定義されているタグを利用することにしました。
初めて利用して一番の失敗が、FORMタグ内に設置するとダイアログが出力されずにサブミットされてしまうことでした。
余裕のあるときにどうしてなのか理由を調べようと思います(多分出来ないことは無いと思われる)
次回はFORMタグ内の設置でどうしてSubmitされたのかを探りたいと思います。
以下サンプルはリスト画面ではなく、詳細ページの画面なので削除した後はリストページに飛ばします。ソースはそこからの抜粋になります。
次回実際に動作確認ができるページを用意しようと思います。

HTMLソース - 該当箇所のみ

<dialog id="deleteConfirm">
    <h2>モーダルダイアログ</h2>
    <p>データを削除します</p>
    <button class="cancel-btn">キャンセル</button>
    <button class="ok-btn">OK</button>
</dialog>

<div>
  <button class="btn-success" type="button" id="delete">このレコードを削除</button>
</div>

JavaScriptソース

/* 削除ボタンがクリックされたら */
$('#delete').on('click', function (e) {

        var id = $('input[name=id]').val();
        if (id === undefined || id === '') {
            alert('レコードIDが取得できません');
            return true;
        }

        var elm = document.getElementById('deleteConfirm');
        if (elm === undefined || elm.tagName != 'DIALOG') {
            alert('確認画面がありません');
            return true;
        }

        confirmDialog(elm, function (ok) {
            if (ok) {
                let params = new URLSearchParams();
                params.append('cmd', 'delete');
                params.append('id', id);
                fetch('./ajaxDelete.php', {
                    credentials: 'include',
                    method: 'post',
                    body: JSON.stringify(params),
                    headers: new Headers({"Content-type": "application/json"})
                }).then(response => {
                    if (response.ok){
                        return response.json();/* jsonメソッドで Promiseを返却 */
                    } else {
                        alert('更新は失敗しました。'+"\n"+'HTTPステータスコード:'+response.status+'('+Response.statusText+')');
                    }
                }).then(json => {
                    alert(json.message);
                }).catch(error => alert('Error:'+ error));
            }
        });

        return false;
    });

/* 
 * daialog要素を表示してok,cancelのクリック結果をcallback関数に 
 * true,falseで渡します。
*/
function confirmDialog(elm, callback) {
        var dom = {};

        if (isElement(elm)) {
            dom = elm;
        } else if (isString(elm)) {
            dom = document.getElementById(elm);
        } else {
            console.log(elm, 'elementではありません');
            return false;
        }
        /*
         XML (および XHTML など XML ベースの言語) では、tagName は大文字・小文字が保たれます。
         HTML では、tagName は標準的な大文字で要素名を返します。
         tagName の値は nodeName の値と同じになります。
         */

        if (dom.tagName == 'DIALOG') {
            dom.showModal();//確認画面の出力
            dom.addEventListener('click', function (e) {
                if (e.target.className.indexOf('cancel-btn') >= 0) {
                    callback(false);
                } else if (e.target.className.indexOf('ok-btn') >= 0) {
                    callback(true);
                } else {
                    return true;
                }
                dom.close();
                /* dom.removeEventListener('click', arguments.callee); */
            }, false);
        }

        return true;
    }

~この記事の著者~

サイト制作に関するご相談はこちら

 03-5961-5681 平日10:00~19:00

メールフォーム

あなたが
サイトに
求める要素
あなたがサイトに求める0要素