GASによるカスタムダイアログの作り方

# はじめに

Googleドキュメントやスプレッドシート、スライド、フォームなどの GoogleWorkspaceアプリ では Google Apps Script (GAS) を使って組み込みのダイアログやユーザ定義のカスタムダイアログを表示することができます。

# カスタムダイアログの作り方

## アラートダイアログ

ユーザに確認を求めるようなアラート画面は次の手順で作成することができます。

1. GoogleWorkspaceアプリを開く
    新規または既存のGoogleWorkspaceアプリを開いてください。
    <br>
    
1. スクリプトエディタを開く
    メニュー欄から「拡張機能」→「Apps Script」と選択してスクリプトエディタを開きます。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939665/b7231dc5-a1b2-9256-0b30-1c005bcf2177.png)
    <br>

1. アラートダイアログを定義
    任意のファイルで次のような関数を定義します。

    ```javascript
    function onOpen() {
      SpreadsheetApp.getUi()
          .createMenu('カスタムメニュー')
          .addItem('アラートダイアログを表示する', 'showAlert')
          .addToUi();
    }
    
    function showAlert() {
      // ダイアログを表示して待機
      let ui = SpreadsheetApp.getUi();
      let result = ui.alert(
         '確認してください！',
         '本当に続行しますか？',
          ui.ButtonSet.YES_NO
      );
    
      // ユーザの選択を表示
      if (result == ui.Button.YES) {
        ui.alert('続行が許可されました');
      } else {
        ui.alert('続行が許可されませんでした');
      }
    }
    ```
    ※ onOpen()：GoogleWorkspaceアプリが開かれたときに実行される特殊な関数
    <br>
    
1. 動作を確認する
    onOpen関数を手動実行するか、GoogleWorkspaceアプリをリロードして「カスタムメニュー」から「アラートダイアログを表示する」を選択し、ダイアログで「OK」を選択すると次のような結果が表示されるはずです。

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939665/ed3c1945-ccb0-f774-45ed-b4b1977c92a5.png)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939665/d90b6422-a4b9-d629-dff2-bcbb581b65b1.png)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939665/c77ec99c-fe4d-2b8e-a2b2-026a28890ce7.png)


## プロンプトダイアログ

文字の入力を求めるようなプロンプトダイアログは以下の手順で作成できます。

1. GoogleWorkspaceアプリを開く
    新規または既存のGoogleWorkspaceアプリを開いてください。
    <br>
    
1. スクリプトエディタを開く
    メニュー欄から「拡張機能」→「Apps Script」と選択してスクリプトエディタを開きます。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939665/b7231dc5-a1b2-9256-0b30-1c005bcf2177.png)
    <br>

1. プロンプトダイアログを定義
    任意のファイルで次のような関数を定義します。

    ```javascript
    function onOpen() {
      SpreadsheetApp.getUi()
          .createMenu('カスタムメニュー')
          .addItem('プロンプトダイアログを表示する', 'showPrompt')
          .addToUi();
    }
    
    function showPrompt() {
      // ダイアログを表示して待機
      let ui = SpreadsheetApp.getUi();
      let result = ui.prompt(
          'ユーザ登録画面',
          'お名前を入力してください。',
          ui.ButtonSet.OK_CANCEL);
    
      // ユーザ入力を処理
      let button = result.getSelectedButton();
      let name = result.getResponseText();
      if (button == ui.Button.OK) {
        ui.alert(`お名前：${name}`);
      } else if (button == ui.Button.CANCEL) {
        ui.alert(`入力が拒否されました`);
      } else if (button == ui.Button.CLOSE) {
        ui.alert('ユーザ登録画面が×ボタンで閉じられました');
      }
    }
    ```
    ※ onOpen()：GoogleWorkspaceアプリが開かれたときに実行される特殊な関数
    <br>

1. 動作を確認する
    onOpen関数を手動実行するか、GoogleWorkspaceアプリをリロードして「カスタムメニュー」から「プロンプトダイアログを表示する」を選択し、名前を入力すると次のような結果が表示されるはずです。

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939665/ceeda48c-9764-f12c-af56-95fe8157e4ba.png)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939665/47268731-78f1-9874-fe32-198a73769b96.png)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939665/7cadcc89-925f-4afd-beb9-bd75534806f4.png)


## カスタムダイアログ（基本形）

GoogleWorkspaceアプリでは組み込みのダイアログだけでなくHTML/CSSからユーザがカスタマイズしたダイアログを作成することもできます。

以下は最もシンプルにユーザ定義のダイアログを表示するだけのサンプルです。

1. GoogleWorkspaceアプリを開く
    新規または既存のGoogleWorkspaceアプリを開いてください。
    <br>
    
1. スクリプトエディタを開く
    メニュー欄から「拡張機能」→「Apps Script」と選択してスクリプトエディタを開きます。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939665/b7231dc5-a1b2-9256-0b30-1c005bcf2177.png)
    <br>

1. カスタムダイアログを定義
    任意のスクリプトファイルで次のような関数を定義します。

    ```javascript
    function onOpen() {
      SpreadsheetApp.getUi()
          .createMenu('カスタムメニュー')
          .addItem('カスタムダイアログを表示する', 'showDialog')
          .addToUi();
    }
    
    function showDialog() {
      // ダイアログを表示して待機
      let html = HtmlService.createHtmlOutputFromFile('ダイアログ')
          .setWidth(400)
          .setHeight(100);
      SpreadsheetApp.getUi()
          .showModalDialog(html, 'カスタムダイアログ');
    }
    ```
    ※ onOpen()：GoogleWorkspaceアプリが開かれたときに実行される特殊な関数

    続いて、「ダイアログ」という名前で次のようなHTMLファイルを定義します。

    ```html
    Hello, world! <input type="button" value="Close" onclick="google.script.host.close()"/>
    ```
    <br>

1. 動作を確認する
    onOpen関数を手動実行するか、GoogleWorkspaceアプリをリロードして「カスタムメニュー」から「カスタムダイアログを表示する」を選択しすると次のような結果が表示されるはずです。

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939665/37bd1444-f6c4-deb2-8ea2-bdb1b6019b33.png)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939665/e966719e-909f-8ca0-a3e9-b1eac119c53b.png)


## カスタムダイアログ（フォーム付き）

カスタムダイアログにはフォームを付けてダイアログとGASサーバの間で処理を連携させることもできます。

1. GoogleWorkspaceアプリを開く
    新規または既存のGoogleWorkspaceアプリを開いてください。
    <br>
    
1. スクリプトエディタを開く
    メニュー欄から「拡張機能」→「Apps Script」と選択してスクリプトエディタを開きます。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939665/b7231dc5-a1b2-9256-0b30-1c005bcf2177.png)
    <br>

1. カスタムダイアログを定義
    任意のスクリプトファイルで次のような関数を定義します。

    ```javascript
    function onOpen() {
      SpreadsheetApp.getUi()
          .createMenu('カスタムメニュー')
          .addItem('カスタムフォームを表示する', 'showForm')
          .addToUi();
    }
    
    function showForm(){
      let form = HtmlService.createHtmlOutputFromFile("ダイアログ");
      SpreadsheetApp.getUi().showModalDialog(form, "カスタムフォーム");
    }
    
    function processForm(formObject){
      // 引数で受け取ったフォームオブジェクトを解析
      let name = formObject.name;
      let age = formObject.age;
      let email = Session.getActiveUser().getEmail();
    
      // GAS側の処理を実行
      let spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
      let sheet = spreadsheet.getSheetByName('シート1');
      sheet.getRange('A1').setValue(`name: ${name}`);
      sheet.getRange('A2').setValue(`age: ${age}`);
      sheet.getRange('A3').setValue(`email: ${email}`);
    
      // ダイアログにレスポンスを返す
      return {
        name: name,
        age: age,
        email: email
      };
    }
    ```
    ※ onOpen()：GoogleWorkspaceアプリが開かれたときに実行される特殊な関数

    続いて、「ダイアログ」という名前で次のようなHTMLファイルを定義します。

    ```html
    <!DOCTYPE html>
    <html>
      <head>
        <base target="_top">
      </head>
      <body>
        <h3>あなたの情報を入力してください。</h3>
    
        <form onsubmit="handleFormSubmit(this)">
          <label>Name: </label><input name="name" type="text"/><br/>
          <label>Age: </label><input name="age" type="text"/><br/>
          <input type="submit" value="Submit"/>
        </form>
    
        <div id="output"></div>
    
        <script>
        // フォーム送信によってリダイレクトされるのを防ぐ
        window.addEventListener('load', () => {
          let forms = document.querySelectorAll('form');
          for (let i = 0; i < forms.length; i++) {
            forms[i].addEventListener('submit', event => event.preventDefault());
          }
        });
        
        // 正常に処理されたときの動作を定義
        function onSuccess(data) {
          let output = document.getElementById('output');
          output.innerHTML = `
            <br/>スプレッドシートに以下の情報を書き込みました。
            <ul style="color:green;">
              <li>Name: ${data.name}</li>
              <li>Age: ${data.age}</li>
              <li>Email: ${data.email}</li>
            </ul>
          `;
        }
        
        // 例外発生時の動作を定義
        function onFailure(error) {
          let output = document.getElementById('output');
          output.innerHTML = `
            <div style="color:red;">
              ${error.message}
            </div>
          `;
        }
    
        // フォーム送信時の動作を定義
        function handleFormSubmit(formObject) {
          google.script.run
            .withSuccessHandler(onSuccess)
            .withFailureHandler(onFailure)
            .processForm(formObject); // GASの関数名を指定
        }
      </script>
     </body>
    </html>
    ```
    <br>

1. 動作を確認する
    onOpen関数を手動実行するか、GoogleWorkspaceアプリをリロードして「カスタムメニュー」から「カスタムフォームを表示する」を選択し、名前などを入力すると次のような結果が表示されるはずです。

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939665/5072bf3f-bfce-1684-0d87-b1fe600bf193.png)
    ![スクリーンショット 2024-11-21 133041.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939665/13a57306-9387-ce34-d003-c40d91625c6f.png)


## サイドバー

GoogleWorkspaceアプリではダイアログだけでなくユーザ定義のサイドバーも作成できます。

1. GoogleWorkspaceアプリを開く
    新規または既存のGoogleWorkspaceアプリを開いてください。
    <br>
    
1. スクリプトエディタを開く
    メニュー欄から「拡張機能」→「Apps Script」と選択してスクリプトエディタを開きます。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939665/b7231dc5-a1b2-9256-0b30-1c005bcf2177.png)
    <br>

1. サイドバーを定義
    任意のスクリプトファイルで次のような関数を定義します。

    ```javascript
    function onOpen() {
      SpreadsheetApp.getUi()
        .createMenu('カスタムメニュー')
        .addItem('サイドバーを表示する', 'showSidebar')
        .addToUi();
    }
    
    function showSidebar() {
      let html = HtmlService.createHtmlOutputFromFile('サイドバー')
        .setTitle('カスタムサイドバー');
      SpreadsheetApp.getUi().showSidebar(html);
    }
    ```
    ※ onOpen()：GoogleWorkspaceアプリが開かれたときに実行される特殊な関数

    続いて、「サイドバー」という名前で次のようなHTMLファイルを定義します。

    ```html
    <div>
        Hello, world! 
        <input 
            type="button" 
            value="Close" 
            onclick="google.script.host.close()" 
        />
    </div>
    ```
    <br>

1. 動作を確認する
    onOpen関数を手動実行するか、GoogleWorkspaceアプリをリロードして「カスタムメニュー」から「カスタムサイドバーを表示する」を選択しすると次のような結果が表示されるはずです。

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939665/457983bf-c841-ebb6-9ab9-ed8aa31e41d7.png)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939665/a4ef5718-9c93-71b6-4c08-4ae669552898.png)