非同期通信で選択肢チェックボックスを動的生成:google.script.runの実践

前回は、スプレッドシートの「マスタ設定」シートから選択肢の配列を抽出するGASバックエンド関数を実装しました。

今回は、ブラウザ側のHTML/JavaScriptからその関数を呼び出し、受け取ったデータをもとにチェックボックス要素を画面上へ動的に組み立てるフロントエンドの実装を解説します。

GAS特有の非同期通信API「google.script.run」の正しい使い方と、モバイル端末でも快適にタップできるUIの工夫を詳しく見ていきましょう。

google.script.runによる非同期通信とDOM動的生成の処理フロー

google.script.runによる非同期通信とDOM動的生成の処理フロー

google.script.run の基本動作と非同期連携

ブラウザ側のJavaScriptからGASのサーバーサイド関数を呼び出すには、Googleが提供する専用のAPI google.script.run を使用します。

google.script.run
  .withSuccessHandler(function(categoryList) {
    // サーバーから正常に配列が返ってきたときの処理
  })
  .withFailureHandler(function(error) {
    // 通信エラーや例外が発生したときの処理
  })
  .getCategoryList();

この呼び出しは「非同期処理」として実行されます。ブラウザはサーバーからの返信を待つ間も固まることなく、画面全体のレイアウト描画や他のスクリプトの実行をスムーズに進めることができます。

  • withSuccessHandler(callback):GAS関数の戻り値が引数として渡される成功時コールバックです。
  • withFailureHandler(callback):万が一サーバー側でエラーが起きた場合に呼ばれ、画面に親切なエラー通知を表示できます。

DOM操作によるチェックボックスの動的生成

サーバーから受け取ったカテゴリー配列をもとに、HTML要素を組み立ててコンテナへ追加します。

// カテゴリーリストを取得してチェックボックスを生成
google.script.run.withSuccessHandler(function(categoryList) {
  const categoryGroup = document.getElementById('category-checkbox-group');
  if (categoryList && categoryList.length > 0) {
    categoryList.forEach(function(item, index) {
      const checkboxOption = document.createElement('div');
      checkboxOption.className = 'checkbox-option';
      const checkboxId = 'category-' + index;
      
      checkboxOption.innerHTML = 
        '<input type="checkbox" id="' + checkboxId + '" name="category" value="' + item + '">' +
        '<label for="' + checkboxId + '">' + item + '</label>';
        
      categoryGroup.appendChild(checkboxOption);
    });
    
    // 生成後にクリック領域拡張と「その他」連動イベントを設定
    setupCheckboxClickHandlers();
    setupOtherInputHandlers();
  } else {
    categoryGroup.innerHTML = '<p style="color: #777; font-size: 14px;">選択肢が設定されていません。</p>';
  }
}).withFailureHandler(function(error) {
  console.error('カテゴリーリストの取得に失敗しました:', error);
  document.getElementById('category-checkbox-group').innerHTML = 
    '<p style="color: #e53935; font-size: 14px;">データの取得に失敗しました。</p>';
}).getCategoryList();

この実装により、スプレッドシートの行数に合わせて、自動的に無駄のないチェックボックス群が描画されます。

スマートフォンで押しやすくするUIの工夫

標準のチェックボックスはタップ領域が小さく、特にスマートフォンでは押し間違いが発生しやすくなります。
外側のラッパー要素(.checkbox-option)の余白部分をタップしてもチェックが反転するようにイベントを付与します。

function setupCheckboxClickHandlers() {
  document.querySelectorAll('.checkbox-option').forEach(function(option) {
    if (!option.dataset.clickHandlerSet) {
      option.addEventListener('click', function(e) {
        // クリック対象がチェックボックス本体そのものでない場合に処理
        if (e.target.type !== 'checkbox') {
          const checkbox = this.querySelector('input[type="checkbox"]');
          if (checkbox) {
            checkbox.checked = !checkbox.checked;
            // 状態変化を手動で通知(「その他」連動ハンドラーに知らせる)
            checkbox.dispatchEvent(new Event('change'));
          }
        }
      });
      option.dataset.clickHandlerSet = 'true';
    }
  });
}

重要な実装上のポイント

  • dataset.clickHandlerSet による重複防止:非同期で複数回UIが更新された場合でも、二重にイベントリスナーが登録されてトグルが打ち消されるのを防ぎます。
  • dispatchEvent(new Event(‘change’)):プログラムから checkbox.checked を書き換えただけでは change イベントが発火しないため、手動でイベントを通知して連動処理を起動させます。

まとめと次回の内容

今回は、非同期通信によってスプレッドシートのデータを読み出し、快適なタッチ操作に対応したチェックボックスを動的生成する技術を解説しました。

次回は、選択肢に「その他」が含まれる場合の自由入力欄の表示制御と、送信ボタンが押された際の入力検証(バリデーション)、エラー箇所への自動スムーズスクロールの実装について詳しく解説します。


eguchi.netをもっと見る

購読すると最新の投稿がメールで送信されます。