きよくらの備忘録

「三日坊主と呼ばせない!日記」改め。主にソフトウェア開発関連の話題。

showModalDialogの小技

たぶん小技というほどのものでも無いし、そもそもshowModalDialogはこういう風に使うものだと思うのですが、よく質問されたりするのでひょっとしてWeb上であまり言及されていないのかと思い、メモの意味を含めて。


showModalDialog周りでよくある質問として、「window.opnerで開き元にアクセスできないんですが……」という類のものがあります。
これは、標準の(?)Javascriptが持っているwindow.openメソッドで別ウィンドウを開いた際に、親ウィンドウを操作するのと同じ事をやろうとしてるために起こっている疑問と思います。


解決策としては、showModalDialogは戻値を戻せるので、ダイアログを閉じた後の呼び出し元の処理で行う、と言うのが一般的と思います。(ダイアログ内で行った操作によって呼び出し元での画面での処理が変わるのであれば、そのために必要な値を戻値に積み込んでやれば良い。複数必要なら、配列にして。)


が、どうしても、ダイアログを開いたままの状態で親ウィンドウを操作してやりたい事もあるかもしれません。(どちらかと言うと、showModelessDialogのほうが、こういった要求は多いかもしれません。)


こういった場合は、「操作したい開き元ウィンドウのオブジェクトをshowModalDialogメソッドの引数として渡してやる*1ことで、対応可能です。
操作したいオブジェクトが複数あるときは、当然配列に突っ込んで配列ごと渡してあげればよいです。
例えば、id="txtHoge01"とid="txtHoge02"と言う名前のinput要素(type="text")に、ダイアログからの操作で値を積み込みたいなら、

var argAry = new Array();
argAry[0] = document.getElementById('txtHoge01');
argAry[1] = document.getElementById('txtHoge02');
var ret = showModalDialog('hogehoge.html', argAry , '.....' );

のような感じで開いてやって、ダイアログ側では

var argAry = window.dialogArguments;
argAry[0].value = '操作によって、txtHoge01に入れたい値';
argAry[1].value = '操作によって、txtHoge02に入れたい値';

のようにすればOK。


乱暴な方法としては、開き元のwindowオブジェクトやdocumentオブジェクトを丸々渡してやることもできますが、大抵は何やってるのか解りにくくなる*2上、ASP.NETなどでは出力されるHTMLのid属性やname属性は必ずしもコードをかいた時のままの文字列である保証がありませんので、

  • 操作する範囲が少数で、ある程度固定できるなら上記のように個別に(複数の場合は個別に配列に格納して)渡す
  • 範囲が広いならうまいこと構造を整えて記述して、DOM操作すること前提でブロック要素単位くらいで渡してやる*3

等が現実的な解では無いか、と思います。

*1:showModalDialogメソッドは、第二引数に任意のオブジェクトを渡すことができます

*2:WEBアプリケーションであるなら、大抵は別々のファイルに記述されているオブジェクトを、直接触りまくるのは抵抗がありますよね

*3:実質的にはdocumentオブジェクトをそのまんま渡してやるのと同じという向きもあるかと思いますが、程度の問題と言うのも可読性/保守性には重要な点と思っています。