DIALOGの1

東の低い空にオレンジ色の月。 よく見ると月の前を飛行機が飛んでいるのだが、この大きさじゃ分からないか。
Internet Explorer
世の中ではとっくに終わっている感があるIEだが、社内システムでは今も現役。 酷いのになるとIE11をIE8互換モードで使っていたりする。 周回遅れが2周分。
そんな状況も来年には強制的に終了となるのだが、終わらせるのも簡単じゃないんだよなぁ…。
IEの終了で問題になるのが、IEと共に終了してしまう非互換の機能。 その一つに showModalDialog がある。
- 何かを選択するかキャンセルするまで、呼び出し元は操作できない。
- 何かを選択した場合、その選択結果は戻り値として返ってくる。
これがとても使い勝手が良かったのだ。 なので他のブラウザに対して非互換と知りながらも 「だってこのシステムはIE限定だから」 と言い訳して、ちょくちょく使ってきた。
で、今更ながらこの showModalDialog をどうすりゃいいのか気になって調べてみたら、今は DIALOG なんてものがあるんだね。
DIALOG
せっかくなので使ってみた。
下の [Show DIALOG] ボタンをクリックすると、左右を選択するダイアログをモーダルで表示する。 そこで [OK] ボタンをクリックすると、ダイアログを消して選択の結果を表示する。 [Cancel] をクリックした場合はダイアログを消すだけ。
以下、ソースコードとか気付きとか。
まずはダイアログ部分のHTML
<dialog id="dlg01" onclose="dialogClosed()">
<div>
選べ
</div>
<div>
<label>
<input type="checkbox" id="chkL" />
左
</label>
<label>
<input type="checkbox" id="chkR" />
右
</label>
</div>
<div>
<button onclick="doOK()">OK</button>
<button onclick="doCancel()">Cancel</button>
</div>
</dialog>
ダイアログを表示するボタン部分。
<button onclick="showDialog()">Show DIALOG</button>
そしてJavaScript
function showDialog() {
document.getElementById( "dlg01" ).showModal();
}
function doOK() {
document.getElementById( "dlg01" ).close( JSON.stringify( {
"L" : document.getElementById( "chkL" ).checked ,
"R" : document.getElementById( "chkR" ).checked ,
} ) );
}
function doCancel() {
document.getElementById( "dlg01" ).close();
}
function dialogClosed() {
const returnValue = document.getElementById( "dlg01" ).returnValue;
if ( returnValue ) {
const { L, R } = JSON.parse( returnValue );
document.getElementById( "dspL" ).innerText = L;
document.getElementById( "dspR" ).innerText = R;
}
}
とりあえず押さえておくべきこと。
- DIALOG Element はメソッドとして show と showModal と close を持っている。
- DIALOG Element はプロパティとして returnValue を持っている。
- ダイアログを閉じる時、 close の引数として値を渡すと、それが returnValue に設定される。 呼び出し元との値の受け渡しはこれを使う。 ただし文字列または暗黙の型変換で文字列になるもの限定。 色々返したい場合はオブジェクトを JSON.stringify して渡し、受け取って JSON.parse するなどの工夫が必要になる。
- 開いているダイアログは esc キーでも閉じる。 close メソッドで閉じると close イベントが発火するが、 esc の場合は cancel イベントが発火する。
- CSS で display を直接指定しちゃ駄目。 table とか grid とか flex とか。 これらを指定すると close してもダイアログが消えず、ウインドウの下端に表示されたままになる。 直接でなければ問題ない。 使いたい場合は、dialogの下にコンテナ用のdivを置いて、そこに指定すればいい。 これなら close でちゃんと消える。
- showModal で開くと、モーダルなので当然だが、呼び出し元は操作できない。 でもスクロールは効く。 そしてスクロールに合わせてダイアログも移動する。 この挙動は CSS の position で制御できる。
これで showModalDialog を直接置き換えることはできないけど、モーダルではあるし、値の受け渡しもできる。 つまり代替はできるのだな。 若干の妥協は必要だけど。
この DIALOG がいつ頃からあるのか気になって検索してみたら、一番古い記事は2015年だった。 そんな昔からあったんだね。