Dialogs and Prompts

by 3 contributors:

この記事では、ダイアログボックスを表示・実行するためのコードサンプルを示しています。入門的情報とより多くの議論やサンプルが必要な場合は、chrome コードの中でウィンドウを利用する を参照してください。

ダイアログウィンドウについて

でのダイアログ

アプリケーションでダイアログを生成したい場合、XUL ファイルのルートエレメントとして、(通常の <window> でなく) <dialog> を利用します。これにより

  • いくつかのキーワードのイベント (ENTER/ESC など) を取り扱え、キーボード操作が向上します。
  • OK, Cancel ボタンを OS 既定と整合した形で追加します。(ただし、ボタンの種類とレイアウトは下記のように高度にカスタマイズ可能です)

簡単なダイアログコード

以下の XUL コードは 2 つのボタン、OK と Cancel (dialogbuttons="accept,cancel" 属性) を持つ簡単なダイアログを定義します。

<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>

<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
	id="..." title="..."
	buttons="accept,cancel"
	ondialogaccept="return onAccept();"
	ondialogcancel="return onCancel();">

<script src="chrome://..."/>

<!-- Content -->

</dialog>

onAcceptonCancel 関数をスクリプトに実装するだけです。それらの関数が false 以外の戻り値を返した場合ダイアログは閉じます。

<dialog> のボタン

定義されているもの

ダイアログの buttons 属性では次の 6 つのボタン型を利用できます。

  • accept — OK ボタン
  • cancel — Cancel ボタン
  • disclosure — 詳細情報ボタン
  • help — ヘルプボタン (Thunderbird 1.0 では動作しません。バグ 256915)
  • extra1, extra2 — 既定のラベルや内容が無いボタン二つです。extra2 は既定ではダイアログの左側に配置されます。

これらのボタンに対して、labelaccesskeyoncommanddialog エレメントに buttonlabel<buttonname>, buttonaccesskey<buttonname> や ondialog<buttonname> 属性をいれることにより定義できます。たとえば、Apply ボタンをダイアログに加えたい場合、次のようにします。

<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" 
  id="..."
  buttons="accept,cancel,extra1"
  ondialogaccept="onAccept();"
  ondialogextra1="onApply();"
  buttonlabelextra1="Apply"
  buttonaccesskeyextra1="A">

<!-- Content -->
</dialog>

<tt>gDialog.getButton(dlgtype);</tt> により定義されているどのボタンのオブジェクトでも得られます。gDialog は <dialog> エレメントで、dlgtype は上の 6 つのボタンタイプのうちの一つです。

明示

dialog で定義されているボタンのレイアウトに満足できないなら、XUL ファイルに button エレメントを明示的に定義し、dlgtype をそれに追加することが可能です。dlgtype の有効な値は、上にリストされている 6 つのボタンタイプです。

dlgtype をもつボタンへ oncommand を導入するかわりに、dialog エレメントの ondialog* 属性を利用してください。これは、ボタンの oncommand はボタンが押されたときにのみ実行されるのに対し、ondialog* ハンドラはキーボード入力や他のイベントの時にも実行されることによります。

サンプル:

<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>

<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
        ondialogaccept="alert('ok!');">
<hbox>
  <label value="Hey!"/>

  <spacer flex="1"/>
  <vbox>
    <button dlgtype="accept"/>
    <button dlgtype="cancel"/>
  </vbox>
</hbox>
</dialog>

既定のボタン

Firefox 1.5 以来、defaultButton 属性とプロパティーが <dialog> エレメントに追加されました (バグ 284776)。この属性に利用可能な値は上記のボタン名で、デフォルト値は過去のバージョンとの互換性の観点から "accept" です。

</dialogheader>

<dialogheader> を利用する

dialogheader エレメントをウィンドウにハンドラを追加するのに利用できます。どのように動作するかについて見たい場合は、Firefox もしくは Thunderbird (v1.0 もしくはそれ以前のみ) のオプション (もしくは設定) ダイアログを見てください。セクションボタンの右側のヘッダは <dialogheader> です。

<dialogheader title="General" description="whatever"/>

注 : このエレメントは <dialog> の中でのみ利用すべきで、他のところでは正常に表示されない可能性があります。(<window> の中でも同様に動作しているようには見えますが。)

リンク

引数を渡してダイアログを表示する

以下のコードはダイアログに独自の引数を渡して、ダイアログの中で利用し、ユーザが変更した値を呼び出し側に戻す方法を紹介します。mydialog.xul というダイアログを開いて、引数を渡すコードは次です。

var params = {inn:{name:"foo", description:"bar", enabled:true}, out:null};       
  window.openDialog("chrome://myext/chrome/mydialog.xul", "",
    "chrome, dialog, modal, resizable=yes", params).focus();
  if (params.out) {
    // User clicked ok. Process changed arguments; e.g. write them to disk or whatever
  }
  else {
    // User clicked cancel. Typically, nothing is done here.
  }

mydialog.xul:

<dialog
  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
  id="myDialogId"
  title="My Dialog"
  ondialogaccept="return onOK();"
  onload="onLoad();"
  persist="screenX screenY width height"
  windowtype="myDialogWindowType">

  <script type="application/x-javascript" src="chrome://myext/content/mydialog.js"/>
  <grid>
    <columns><column/><column/></columns>
    <rows>
      <row align="center"><label value="Name:"/><textbox id="name"/></row>
      <row align="center"><label value="Description:"/><textbox id="description"/></row>
      <row align="center"><spacer/><checkbox id="enabled" label="Check to Enable"/></row>
    </rows>
  </grid>
</dialog>

mydialog.js:

// ダイアログが表示されるときに一度呼ばれる
function onLoad() {
  // 呼び出し側によって渡される引数
  document.getElementById("name").value = window.arguments[0].inn.name;
  document.getElementById("description").value = window.arguments[0].inn.description;
  document.getElementById("enabled").checked = window.arguments[0].inn.enabled;
}

// ユーザが OK をクリックした時だけに一度実行される
function onOK() {
   // 変更した引数を返す
   // ユーザが cancel をクリックした時は、window.arguments[0].out は null のまま
   // この関数が呼ばれないので
   window.arguments[0].out = {name:document.getElementById("name").value,
        description:document.getElementById("description").value,    
        enabled:document.getElementById("enabled").checked};
   return true;
}

ダイアログにパラメータを渡し、戻り値を受け取る方法 も参照してください。

標準の "ファイルを開く" / "ファイルを保存する" / "フォルダ選択" ダイアログを表示する

nsIFilePicker 参照

プロンプトとプロンプトのサービス

ここまででダイアログについては理解したと思いますので、プロンプトについて見てみましょう。ダイアログと異なり、独自の XUL を要求しません。しかしながら、このため、カスタマイズ性には劣ります。ウェブ開発者にとっては、alert() 関数でおなじみです。

Image:AlertHelloWorld.png

これがもっとも単純なプロンプトのサンプルです。

nsIPromptService は C++ や chrome JavaScript コード (ウェブページの JS ではありません) への XPCOM インターフェースで、いくつかのタイプのダイアログを表示するメソッドを提供します。

ファイル・フォルダー選択ダイアログについては、nsIFilePicker を参照してください。

nsIPromptService は理解するために重要な 9 つの関数といくつかの定数をもちます。この文書では、これらのうちいくつかについて解説し、すべてについてサンプルを提供します。

nsIPromptService を取得する

はじめに、メッセージを表示するためのプロンプトサービスを取得する必要があります。これは

var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
                        .getService(Components.interfaces.nsIPromptService);

として行えます。

nsIPromptService メソッド

alert()

alert() は最も単純な関数で、単に指定されたタイトルとメッセージでメッセージボックスを表示します。たとえば、

var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
                        .getService(Components.interfaces.nsIPromptService);
prompts.alert(window, "Window title", "Hello world!");

です。

他のたくさんの nsIPromptService のメソッドと同じく、最初のパラメータは nsIWindowWatcher.openWindow親ウィンドウ です。もし、親ウィンドウが nsIWindowWatcher.activeWindow である場合、null を入れることもできます。

alertCheck()

alertCheck() は指定されたタイトル・文字列・チェックボックスでメッセージボックスを表示します。チェックボックスは、"このメッセージを次から表示しない" オプションか同様のものです。

var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
                        .getService(Components.interfaces.nsIPromptService);
check = {value: false}; // default value
prompts.alertCheck(window, "Window title", "You have been warned", 
                   "Don't ask again", check);
// do something with check.value;

チェックボックスの状態の取得方法に注意してください。この関数は check オブジェクトの value メンバーを変更します。そして、結果は check.value で受け取ることになります。これは、XPCOM コンポーネントでのいわゆる "out" パラメータの標準的な取得方法です。

confirm() と confirmCheck()

confirm() も単純です。指定されたタイトル・文字列、そして OK Cancel の二つのボタンを持つダイアログを表示します。

var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
                        .getService(Components.interfaces.nsIPromptService);
var result = prompts.confirm(window, "Title", "Do you want to quit?");

次のものはチェックボックスを持つ確認メッセージを表示するサンプルです。これは、confirm()alertCheck() の混合で、追加コメント無しに簡単に理解できるでしょう。

var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
                        .getService(Components.interfaces.nsIPromptService);
var check = {value: false};
var result = prompts.confirmCheck(window, "Title", "Do you want to quit?", 
                                  "Do not ask me again", check);
// do something check.value / result

prompt()

prompt() は非常に重要で、入力を受け付けるさまざまな場面で有用です。XUL ダイアログを準備したり、テキストボックスを追加するかわりに、この関数を呼ぶだけですみます。最初のいくつかの引数は他の関数と同じですが、追加のオブジェクトを要求します。これらのオブジェクトは関数が呼ばれる前に既定の値を設定し、戻ってきたあとは新しい値に変更されています。

var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
                        .getService(Components.interfaces.nsIPromptService);
var input = {value: "default value"};
var check = {value: false};
result = prompts.prompt(window, "Title", "What's your name?", input, "Do not ask again", check);
// input.value is the string user entered
// check.value indicates whether or not the checkbox is checked
// result - whether user clicked OK (true) or Cancel

promptPassword() と promptUsernameAndPassword()

次のものは、prompt の別のバージョンで、パスワード入力ボックスを持つ promptPassword() と、ユーザ名とパスワード入力ボックスを持つpromptUsernameAndPassword() です。

//promptPassword
var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
                        .getService(Components.interfaces.nsIPromptService);
input = {value:"password"};
check = {value:false};
okorcancel = prompts.promptPassword(window, 'title', 'Text', input, 'Check?', check);
return input.value;
return check.value;
return okorcancel;

//promptUsernameAndPassword
var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
                        .getService(Components.interfaces.nsIPromptService);
username = {value:"ihoss"};
password = {value:"password"};
check = {value:false};
okorcancel = prompts.promptUsernameAndPassword(window, 'title', 'Text', username, password, 'Check?', check);
return username.value;
return password.value;
return check.value;
return okorcancel;

confirmEx()
var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
                        .getService(Components.interfaces.nsIPromptService);
var check = {value: false};
var flags = 0;
var button = prompts.confirmEx(window, "Window title", "Message text", flags, 
             "Button 0", "Button 1", "Button 2", "Checkbox label", check);
// |check.value| indicates whether or not the checkbox is checked
// |button| indicates which button was clicked

confirmEx() は独自のメッセージを利用可能になるようにカスタマイズ可能な形で設計されています。(必要なら翻訳された) 既定のもしくはコードで設定したラベルを持つ最大で 3 つのボタンと、必要ならチェックボックスも表示できます。もしチェックボックスが必要ないならば、null を 8 番目のパラメータ (チェックボックスのラベル) に与えてください。

flags はダイアログにどのボタンを表示するかを決定するフラグです。それぞれのボタンは、タイトルフラグと配置フラグの積で定義されます。

ボタン配置フラグボタンタイトルフラグ
BUTTON_POS_0
BUTTON_POS_1
BUTTON_POS_2
BUTTON_TITLE_OK
BUTTON_TITLE_CANCEL
BUTTON_TITLE_YES
BUTTON_TITLE_NO
BUTTON_TITLE_SAVE
BUTTON_TITLE_DONT_SAVE
BUTTON_TITLE_REVERT
BUTTON_TITLE_IS_STRING

ボタンには定義されているタイトルも利用可能です。もしくは、BUTTON_TITLE_IS_STRING が指定されれば、ボタンに指定された文字列パラメータが利用されます。

flags はボタンの値の和に設定します。

どのボタンが表示されるかはプラットフォームによります。ボタンのデフォルトフラグが flags にない場合、ボタン 0 が既定で選択されます。

ボタンのデフォルトフラグ
BUTTON_POS_0_DEFAULT
BUTTON_POS_1_DEFAULT
BUTTON_POS_2_DEFAULT

たとえば、flags が次のように設定された場合、ダイアログは保存ボタン、キャンセルボタン、そしてタイトルが confirmEx() の 7 番目の引数で指定されるボタンを表示します。(上記のサンプルでは "Button 2" です。)

var flags = prompts.BUTTON_TITLE_SAVE      * prompts.BUTTON_POS_0 +
            prompts.BUTTON_TITLE_CANCEL    * prompts.BUTTON_POS_1 +
            prompts.BUTTON_TITLE_IS_STRING * prompts.BUTTON_POS_2;

flagsSTD_OK_CANCEL_BUTTONS もしくは STD_YES_NO_BUTTONS にすれば、OK/Cancel もしくは Yes/No ボタンのセットを表示します。

select()

select() はリストボックスと OK/Cancel ボタンを持つダイアログを表示します。リストボックスは、指定されたオプションを表示し、ユーザはそれの一つを選択できます。selected.value にユーザが選択した項目のインデックスが入りますので、list[selected.value] により値を取得できます。4 番目のパラメータは、表示したいエントリの個数で、list アレイの長さと等しいか少なくなるべきです。その値までの個数のアイテムがリストボックスに表示されます。

var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
                        .getService(Components.interfaces.nsIPromptService);
var list = ["ihoss", "internet", "firefox", "xul", "stupid entry", "out of ideas"]
var selected = {};
var ok = prompts.select(window, "Window title", "Prompt text", 
                        list.length, list, selected);
// selected.value contains the index
// |ok| indicates whether OK or Cancel button was pressed

オリジナルバージョン

このチュートリアルのオリジナルは、ここ にあります。

リンク

nsIPromptService


ドキュメントのタグと貢献者

タグ: 
Contributors to this page: Milly, Shimono, Mgjbot
最終更新者: Milly,