LoginSignup
0

More than 5 years have passed since last update.

Office UI FabricでパネルUIを表示する

Posted at

まる1日分の周回遅れが発生しているOffice UI Fabric Advent Calendar、第11日目はパネルについて解説します。

OfficeUIのパネル

パネルのサンプルプログラム

Office UI Fabricでダイアログボックスを表示するでも少し触れたように、Office UI Fabric(以降"OfficeUI")では設定画面の表示方法として、ダイアログの他にパネルを使うという方法もありそうです。

設定項目をパネルで設定する簡単なサンプルを作成してみました。以下のような表示になります。パネルもダイアログの表示と同じく、モーダル状態で表示されます(設定項目の値をトグルボタン表示にしてみたところ、ディップスイッチみたいな感じになってしまいました……)。

img600.png

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

<!DOCTYPE html>
<html ng-app="App">
  <head>
    <meta charset="utf-8" />
    <title>Panel 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>
    <script type="text/javascript" src="https://rawgit.com/furandon-pig/701ec8a958b4d80c34fb/raw/c3113233b4c8cad3144ee0947d79aed3e3d13c7a/officeui_panel_helper.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
    <script>
      $(document).ready(function() {
        if ($.fn.Panel) {
            $('.ms-Panel').Panel();
        }
        // Vanilla JS Components
        if (typeof fabric !== "undefined") {
          if ('Panel' in fabric) {
            var element = document.querySelector('.ms-Panel');
            var component = new fabric['Panel'](element);
          }
        }
      });
    </script>
  </head>
  <body ng-controller="AppController">
    <div class="ms-Grid-col ms-u-sm6 ms-u-md8 ms-u-lg12">
      <button class="ms-Button ms-Button--primary js-togglePanel"> <!-- ボタンを表示する -->
        <span class="ms-Button-label">
          <i class="ms-Icon ms-Icon--gear" aria-hidden="true"></i>設定
        </span>
      </button>
    </div>
    <div class="ms-Grid-col ms-u-sm6 ms-u-md8 ms-u-lg12">
      <div class="ms-Grid-col ms-u-sm6">
        <div class="ms-Table">
          <div class="ms-Table-row">
            <span class="ms-Table-cell">設定項目</span>
            <span class="ms-Table-cell">設定値</span>
            <span class="ms-Table-cell"><br></span>
          </div>
          <div class="ms-Table-row" ng-repeat="configItem in configItems">
            <span class="ms-Table-cell">{{configItem.text}}</span>
            <span class="ms-Table-cell">
              <label style="color:{{(configItem.value==true)?'crimson':'green'}};">
                {{configItem.value}}
              </label>
            </span>
            <span class="ms-Table-cell">
              <button class="ms-Button ms-Button--command" ng-click="removeConfig($index)">
                <span class="ms-Button-label" style="color:crimson;">
                  <i class="ms-Icon ms-Icon--trash" aria-hidden="true"></i>削除
                </span>
              </button>
            </span>
          </div>
        </div> <!-- end of ms-Table -->
        <button class="ms-Button ms-Button--command" ng-click="addConfig()">
          <span class="ms-Button-label" style="color:green;">
            <i class="ms-Icon ms-Icon--plus" aria-hidden="true"></i>追加
          </span>
        </button>
      </div>
    </div>
    <div class="ms-Panel"> <!-- ここからパネル -->
      <div class="ms-Overlay ms-Overlay--dark js-togglePanel"><!-- 空のDIVにする --></div>
      <div class="ms-Panel-main">
        <div class="ms-Panel-commands">
          <div class="ms-CommandBar">
            <div class="ms-CommandBar-mainArea">
              <div class="ms-CommandBar-sideCommands">
                <div class="ms-CommandBarItem">
                  <div class="ms-CommandBarItem-linkWrapper">
                    <div class="ms-CommandBarItem-link">
                      <span class="ms-CommandBarItem-icon ms-Icon ms-Icon--star"></span>
                      <span class="ms-CommandBarItem-commandText ms-font-m ms-font-weight-regular">設定</span>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div> <!-- end of ms-Panel-commands -->
        <div class="ms-Panel-contentInner">
          <span class="ms-Panel-headerText">
            <i class="ms-Icon ms-Icon--gear" aria-hidden="true"></i>設定
          </span>
          <div ng-repeat="configItem in configItems">
            <span class="ms-Toggle ms-Toggle--textLeft" style="margin-bottom:8px;"> <!-- トグルボタン -->
              <span class="ms-Toggle-description">{{configItem.text}}</span>
              <input id="toggle{{$index}}" type="checkbox" class="ms-Toggle-input" ng-model="configItem.value">
              <label for="toggle{{$index}}" class="ms-Toggle-field">
                <span class="ms-Label ms-Label--off">OFF</span>
                <span class="ms-Label ms-Label--on">ON</span>
              </label>
            </span> <!-- end of ms-Toggle -->
          </div>
        </div> <!-- end of ms-Panel-contentInner -->
      </div> <!-- end of ms-Panel-main -->
    </div> <!-- end of ms-Panel -->
    <script>
      var app = angular.module('App', []);
      app.controller('AppController', ['$scope',
        function($scope) {
          $scope.init = function() {
            index = 0;
            $scope.configItems = [
              { text: "設定項目(" + (++index) + ")", value: false },
              { text: "設定項目(" + (++index) + ")", value: false },
              { text: "設定項目(" + (++index) + ")", value: false },
            ];
          }
          $scope.addConfig = function() {
            $scope.configItems.push({ text: "設定項目(" + (++index) + ")", value: false });
          }
          $scope.removeConfig = function(index) {
            $scope.configItems.splice(index, 1);
          }
          $scope.init();
        }
      ]);
    </script>
  </body>
</html>

OfficeUIパネルを使用する際の(バッド)ノウハウ

このパネルUIですが、ラジオボタンとドロップダウンリストのケースと同じく、若干のバッドノウハウ(MSのPanelのサンプルを見ただけでは分からない使い方・ハマり所)があります。

モーダル表示は空のDIV要素にする

パネルUIはモーダル状態で表示されます。ということは、モーダル表示用のクラス(ちゃんと確認してないけど、おそらく「ms-Overlay」)でパネルの要素を挟む形になるのかな……?と考えるも、それだと上手く表示されません。

正しく(?)は以下のように、「ms-Overlay」クラスを指定した空のDIV要素を記述してからパネルの中身を記述する形になります。

<div class="ms-Panel"> <!-- ここからパネル -->
  <div class="ms-Overlay ms-Overlay--dark js-togglePanel"><!-- 空のDIVにする --></div>
  ...

パネルUIの初期化

ラジオボタンとドロップダウンリストでは、ページ読み込み時にドロップダウンリストの表示項目を初期化するコードが必要でした。

パネルでも同様に、ページ読み込み時にパネルの初期化を行う必要があります。先のサンプルコードの以下の場所が初期化を行っている箇所です。

      $(document).ready(function() {
        if ($.fn.Panel) {
            $('.ms-Panel').Panel();
        }

Panel()の定義は外部のJavaScriptファイルで行っており、筆者のGistに用意したofficeui_panel_helper.jsを読むこむ形になっています(GistからJavaScriptを読み込むにはrawgitを経由するといった別のバッドノウハウも必要になります……)。

<script type="text/javascript" src="https://rawgit.com/furandon-pig/701ec8a958b4d80c34fb/raw/c3113233b4c8cad3144ee0947d79aed3e3d13c7a/officeui_panel_helper.js"></script>

まとめ

まる1日分の周回遅れが発生した第11日目の記事ではパネルUIについて解説しました。ダイアログとパネルを使い分けることで、効果的なUIが作れそうです。

参考URL

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0