Office UI Fabricでダイアログボックスを表示する

日が変わってしまいましたが、第10日目はOffice UI Fabric(以下"OfficeUI")でのダイアログボックスの使い方を解説しようと思います。

以前のQiitaの記事になりますが、ダイアログの表示をJavaScriptから制御する方法を紹介しています。

 * [Office UI Fabricでダイアログボックスを使用する(暫定版)](http://qiita.com/furandon_pig/items/c5f0efe1c5102f96970c)

## JavaScriptからダイアログの表示を制御する

今回も簡単なサンプルを作成してみました。以下のような表示になります。

![img500.png](https://qiita-image-store.s3.amazonaws.com/0/61137/93ba4f5e-e3b1-6469-8957-03b737094250.png)

ダイアログのタイトルや文言を変えて表示がどうなるか試してみたい方は、以下のURLをご参照ください。

 * Dialog sample(Office UI Fabric sample)
   * [http://furandon_pig.bitbucket.org/sample/officeui/dialog.html](http://furandon_pig.bitbucket.org/sample/officeui/dialog.html)

[以前のQiitaの記事](http://qiita.com/furandon_pig/items/c5f0efe1c5102f96970c)を書いた時点では、OfficeUI付属のサンプルには表示例はあるものの、JavaScriptでの制御方法がサンプルに含まれていない状態でした。その後MSのOfficeUIサンプル例のWebサイトが公開され、[GitHubのOfficeUIソースコード](https://github.com/OfficeDev/Office-UI-Fabric)を持ってこなくても[Dialogのサンプル](http://dev.office.com/fabric/components/dialog)を見られるのですが、やっぱりJavaScriptからの表示、ダイアログの「閉じる」ボタンを押した場合のハンドリング方法が紹介されていません(なぜなんだ……)。

というわけで、先のサンプル画像のソースコードを元に、ダイアログの表示と閉じるボタン等のハンドリング方法を以降で説明します。

サンプルソースコードは以下になります。

```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Dialog Sample</title>
    <link rel="stylesheet" href="//appsforoffice.microsoft.com/fabric/1.0/fabric.min.css">
    <link rel="stylesheet" href="//appsforoffice.microsoft.com/fabric/1.0/fabric.components.min.css">
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
  </head>
  <body>
    <div class="ms-Grid-col ms-u-sm6 ms-u-md8 ms-u-lg12">
      <button class="ms-Button ms-Button--primary" onclick="APP.jsDialog()">
        <span class="ms-Button-label">JavaScript<span>
      </button>
      <button class="ms-Button ms-Button--primary" onclick="APP.jQueryDialog()">
        <span class="ms-Button-label">jQuery<span>
      </button>
    </div>
    <div class="ms-Dialog" id="dialog1" style="visibility:hidden;"> <!-- ダイアログボックス -->
      <div class="ms-Overlay">
        <div class="ms-Dialog-main">
          <div class="ms-Dialog-header">
            <p class="ms-Dialog-title">タイトル</p>
          </div>
          <div class="ms-Dialog-inner">
            <div class="ms-Dialog-content">
              <label class="ms-Label">
                Hello,Dialog.
              </label>
            </div>
            <div class="ms-Dialog-actions">
              <div class="ms-Dialog-actionsRight">
                <button class="ms-Dialog-action ms-Button ms-Button--primary" onclick="APP.closeByOK()">
                  <span class="ms-Button-label">OK</span>
                </button>
                <button class="ms-Dialog-action ms-Button" onclick="APP.closeByCancel()">
                  <span class="ms-Button-label">Cancel</span>
                </button>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <script>
      APP = (function() {
        var isDialogShow = false;
        var dialog = document.getElementById("dialog1");
        toggleShowState = function() {
          isDialogShow = !isDialogShow;
        };
        jsDialog = function() {
          if (isDialogShow == false) {
            dialog.style.visibility = "visible";
          } else {
            dialog.style.visibility = "hidden";
          }
          toggleShowState();
        };
        jQueryDialog = function() {
          if (isDialogShow == false) {
            $('#dialog1').css('visibility', 'visible');
          } else {
            $('#dialog1').css('visibility', 'hidden');
          }
          toggleShowState();
        };
        closeDialog = function() {
          dialog.style.visibility = "hidden";
          toggleShowState();
        };
        closeByOK = function() {
          closeDialog();
        };
        closeByCancel = function() {
          closeDialog();
        };
        return {
          'toggleShowState': toggleShowState,
          'jsDialog'     : jsDialog,
          'jQueryDialog' : jQueryDialog,
          'closeByOK'    : closeByOK,
          'closeByCancel': closeByCancel,
        };
      })();
    </script>
  </body>
</html>
```

ここでのポイントは以下です。

 * ms-Dialogクラスを指定したDIV要素にIDを付けると共に「style="visibility:hidden;"」を設定し、初期状態では非表示にしておく。

```html
<div class="ms-Dialog" id="dialog1" style="visibility:hidden;">
```

 * ダイアログの表示はCSSのvisibilityの値を変えることで実現します。

```js
document.getElementById("dialog1").style.visibility = "visible";  // 素のJavaScriptの場合
$('#dialog1').css('visibility', 'visible');                       // jQueryを使う場合
```

 * ダイアログの非表示は上記と対になるので、こちらもCSSの値変更で実現します。

```js
document.getElementById("dialog1").style.visibility = "hidden";  // 素のJavaScriptの場合
$('#dialog1').css('visibility', 'hidden');                       // jQueryの場合
```

 * ダイアログ上の閉じるボタン等の処理は、コールバック的に関数が呼ばれるイメージで処理を考えると良いかもしれません。
   * 筆者は最初ダイアログが閉じられたら戻り値で押したボタンの情報を取るイメージで実装しようとしてしまいハマってしまいました……。

## ダイアログの使いどころ

これでダイアログボックスの使いかたが把握できました。あとは使いどころですが、[昨日の記事](http://qiita.com/furandon_pig/items/e40096bca5a94d9addf3)にある[一行メモ保存・検索ツール](http://furandon_pig.bitbucket.org/sample/officeui/json_export/)や[ToDoアプリ](http://furandon_pig.bitbucket.org/sample/officeui/todo_app.html)等ではデータの削除確認の際のwindow.confirm()的な使い方をしています。

OfficeUIのダイアログをwindow.confirm()的に扱う方法も[以前の記事](http://qiita.com/furandon_pig/items/93d84d4bd83c167f6590)で紹介しています。

![img502.png](https://qiita-image-store.s3.amazonaws.com/0/61137/1c76f0f9-29bb-f849-e6c1-e9e5ad57e17b.png)

それから、簡単な設定画面でもダイアログを使用しています。

![img501.png](https://qiita-image-store.s3.amazonaws.com/0/61137/4a26e444-7259-e92d-13e2-911dc77650c3.png)

とはいえ、設定画面についてはOfficeUIに[Panel](http://dev.office.com/fabric/components/panel)というUIコンポーネント（画面の右側ににゅいっと出てくるUI）があり、OfficeUIのお作法的にはそこで設定項目を表示・変更するのが順当な方法なのかもしれません。

そう考えると、OfficeUIではユーザの注意を引きたい、あるいは設定項目の変更画面を出したい場合に[ダイアログ](http://dev.office.com/fabric/components/dialog)と[パネル](http://dev.office.com/fabric/components/panel)という2通りの対応方法があるため、より適切（？）なUIが選択できることからBootstrapの場合（モーダルダイアログ一択）よりも自由度があると言えるのかもしれません。

## まとめ

Office UI Adventカレンダー10日目は日が変わってからの投稿になってしまいました。慌てて調べたりサンプルコードを書いていたりしたので、関数名をtypoするレベルのそれはもうひどいミスを連発してしまいました……。

明日（つまり今日ですよ！）ではダイアログの使いどころの話に少し出てきた、[Panel](http://dev.office.com/fabric/components/panel)について解説したいと思います。