【GASxHTML】スプレッドシートの商品データを動的に表示する | GASおじさんのブログ
GASの応用

【GASxHTML】スプレッドシートの商品データを動的に表示する

商品テーブル GASの応用

みなさんこんにちは!GASおじさんです。

GAS x HTMLで確認画面付きの本格的な発注フォームを作ろう」シリーズの第6回です。

前回の記事はこちら。

前回までで表側の画面の実装ができました。

しかし、現状は仮置きのHTMLで実装しているため、常に一定の画面しか表示されない状態です。ちなみに、このようにいつ訪れても常に一定の画面が表示されるサイトのことを「静的サイト(static website)」といいます。

今回は、スプレッドシートに記入された商品データの内容に応じてHTMLを書き換えて、表示画面が変化するようにしていきましょう。ちなみに、このように訪れるタイミングによって表示される画面が変化するようなサイトのことを「動的サイト(dynamic website)」といいます。

Youtubeでも解説していますので、動画で見たい方は以下からどうぞ。

それではやっていきましょう!

スプレッドシートの商品データを動的に表示する

スプレッドシートに商品データを用意する

まずは商品データ(商品テーブル)を用意しましょう。

スプレッドシートの「シート1」を「商品」に書き換えます。

「シート1」を「商品」に書き換える

次に、以下の表をコピーしてシートに貼り付けてください。

商品ID商品名単価在庫数
water¥70100
teaお茶¥100100
colaコーラ¥130100
smartphoneスマホ¥50,000100
computerパソコン¥100,000100

左上(A1セル)から貼り付けるようにしましょう。

貼り付ける際は、そのまま「貼り付け」するのではなく、「特殊貼り付け」から「値のみ貼り付け」するのがオススメです。(Windowsの場合はCtrl + Shift + V、Macの場合はCommand + Shift + V)

これで商品テーブルのできあがりです。

スクリプトを書き換える

つづいて、商品テーブルから商品情報を取得して、HTMLに反映するために、スクリプトを書き換えていきます。

書き換えるファイルは、「コード.gs」と「index.html」の2つです。

コード.gs

コード.gs
コード.gs

まずはコード.gsのdoGet関数を以下のように書き換えてください。

function doGet(e) {
  const items = getAllRecords('商品');
  const template = HtmlService.createTemplateFromFile('index');
  template.deployURL = ScriptApp.getService().getUrl();
  template.formHTML = getFormHTML(e, items);
  const htmlOutput = template.evaluate();
  return htmlOutput;
}

注目は2行目と5行目。

2行目でgetAllRecords関数を、5行目でgetFormHTML関数を呼び出しているので、これらの関数を定義する必要があります。

まずは以下のgetAllRecords関数をコピーして、コード.gsファイルに追加で貼り付けてください。

function getAllRecords(sheetName) {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getSheetByName(sheetName);
  const values = sheet.getDataRange().getValues();
  const labels = values.shift();

  const records = [];
  for(const value of values) {
    const record = {};
    labels.forEach((label, index) => {
      record[label] = value[index];      
    });
    records.push(record);
  }

  return records;
}

この関数でスプレッドシートから商品情報を取得しています。

次に以下のgetFormHTML関数をコピーして、コード.gsファイルに追加で貼り付けてください。

function getFormHTML(e, items, alert='') {
  const email = e.parameter.email ? e.parameter.email : '';
  const username = e.parameter.username ? e.parameter.username : '';

  let html = `
    <div class="mb-3">
      <label for="email" class="form-label">Email</label>
      <input type="email" class="form-control" id="email" name="email" required value="${email}">
    </div>

    <div class="mb-3">
      <label for="username" class="form-label">お名前</label>
      <input type="text" class="form-control" id="username" name="username" required value="${username}">
    </div>

    <p class="mb-3">商品の個数を入力してください。</p>
    <p class="text-danger">${alert}</p>

    <table class="table">
      <thead>
        <tr>
          <th scope="col">商品</th>
          <th scope="col">単価</th>
          <th scope="col">個数</th>
        </tr>
      </thead>
      <tbody>
  `;

  for(const item of items) {
    const itemId = item['商品ID'];
    const itemName = item['商品名'];
    const unitPrice = item['単価'];
    const zaiko = item['在庫数'];
    if(zaiko > 0) {
      html += `<tr>`;
      html += `<td>${itemName}</td>`;
      html += `<td>@¥${unitPrice.toLocaleString()}</td>`;
      html += `<td>`;
      html += `<select class="form-select" name="${itemId}">`;
      
      for(let i = 0; i <= zaiko; i++) {
        if(i == Number(e.parameter[itemId])) {
          html += `<option value="${i}" selected>${i}</option>`;
        } else {
          html += `<option value="${i}">${i}</option>`;
        }
      }

      html += `</select>`;
      html += `</td>`;
      html += `</tr>`;
    }
  }

  html += `</tbody>`;
  html += `</table>`;

  return html;
}

この関数で商品テーブルの内容に応じたHTMLを生成しています。

※コードが徐々に長くなってきたので、コピー漏れやタイプミスがないように気をつけましょう。
タイプミスなどがないように気をつけましょう!
タイプミスなどがないように気をつけましょう!

ここまでできたらコード.gsファイルの書き換えは完了です。

index.html

index.html
index.html

次にindex.htmlを次のように書き換えてください(index.html内のコードを一旦全消去して、以下のコードを貼り付けてください)。

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
  </head>
  <body>
    <div class="container" style="max-width: 600px;">
      <h2 class="text-center m-4">発注フォーム</h2>
      <form class="mb-5" method="POST" action="<?= deployURL ?>">
        <? output._ = formHTML ?>
        <button type="submit" class="btn btn-outline-primary" name="confirm" value="true">確認画面へ</button>
      </form>
    </div>
  </body>
</html>

注目は11行目。

<? output._ = formHTML ?>の部分が、コード.gsのgetFormHTML関数で生成したHTMLに対応しています。

デプロイして画面を確認

ここまでできたらデプロイして画面を確認してみましょう。

画面右上の「デプロイ」ボタンから「新しいデプロイ」をして、ウェブアプリURLを開きます。

すると…

スプレッドシートに入力した商品情報が反映されていることが確認できました!

ためしにスプレッドシートの商品テーブルの内容を変更してみましょう。

水の単価を70円から100円に変更してみます。

その後、ウェブアプリ画面に戻ってブラウザをリロードすると…

単価が100円に変更されました!

つづいて、「水」の在庫数を「0」に、「お茶」の在庫数を「10」にしてみます。

この状態でウェブアプリ画面に戻ってブラウザをリロードすると…

「水」は一覧から消えて、「お茶」の個数上限は「10」になりました!

まとめ

以上、スプレッドシートの商品データを動的に表示する方法について解説してきました。

ポイントは、コード.gsファイルの

template.formHTML = getFormHTML(e, items);

という1行と、

index.htmlファイルの

<? output._ = formHTML ?>

という1行です。

これらの記述があることによって、GASファイル(.gsファイル)とHTMLファイル(.htmlファイル)の間で情報をやりとりすることができるようになり、その結果HTMLを動的に生成することができるようになります。

この辺の仕組みについては動画でより詳しい解説をしようと思っております。とりあえずは当記事のコードをコピーして、ウェブアプリを動かすことを目標に進めてみてください!

今回はフォーム画面(index.html)を動的な画面にすることに成功したので、次回は確認画面(confirm.html)を動的な画面にしていきます!以下をクリックして次に進みましょう!

連載目次: GAS x HTMLで確認画面付きの本格的な発注フォームを作ろう

  1. 【GAS x HTML】確認画面付きの本格的な発注フォームを作る
  2. GASとHTMLで簡単なWebページを表示する方法
  3. 【GAS】Bootstrapを使ってフォーム画面を作る方法
  4. doPost関数で確認画面ページに遷移させよう
  5. 確認画面ページから発注完了ページに遷移させよう
  6. 【GASxHTML】スプレッドシートの商品データを動的に表示する
  7. フォームの入力内容を確認画面ページに渡そう
  8. 確認画面ページに「修正する」ボタンを実装しよう
  9. 確認画面ページの「発注する」ボタンクリック後の機能を実装しよう
  10. 【GASxHTML】フォームのバリデーションを実装しよう
  11. GASとHTMLで作ったWebアプリをスマホ対応させる方法

GASを勉強するならこちら!

▼オススメ書籍はこちら!

スポンサーリンク
GASおじさんをフォローする

コメント

タイトルとURLをコピーしました