GASの応用

【GASxHTML】フォームのバリデーションを実装しよう

バリデーション実装 GASの応用

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

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

前回の記事はこちら。

今回はフォームのバリデーションを実装していきます。

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

現状のフォームの問題点

前回までの記事で作ったフォームには以下のような問題点があります。

  1. 商品が0個でも送信できてしまう
  2. 入力途中で商品が在庫切れとなっても送信できてしまう

商品が0個でも送信できてしまう

このように商品の個数がすべて0個の状態で「確認画面へ」を押すと…

このように確認画面に遷移し、そのまま発注できてしまいます。

しかし、最低でも1個は注文してもらうようにしたいので、商品数が0個の場合は、「少なくとも1個位以上注文してください。」のようなアラートを出した上で、再入力を促したいですね。

入力途中で商品が在庫切れとなっても送信できてしまう

このフォームは複数のユーザーから同時に入力されることも想定しています。

自分が入力しているときに、他の誰かが発注して、商品が在庫切れとなってしまうこともありえるでしょう。

そういったケースを再現するために、スプレッドシート側で「水」の在庫数を5個にしてみます。

次に、フォーム画面で「水」を10個にして「確認画面へ」ボタンを押してみます。

この場合、「入力中に在庫切れとなりました」のようなアラートを出して、再入力を促したいですが、現状ではそのまま確認画面に進めてしまいます。

このまま「発注する」ボタンを押すと発注できてしまいますが、在庫数がないのに発注されるのは困りますね。

バリデーションを実装

上記の問題を解決するために、バリデーションを実装していきましょう。

商品個数が0個で送信されてしまったときの対策

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

function doPost(e) {
  const items = getAllRecords('商品');

  // 注文数が0の場合、alert付きでindex.htmlを返す
  if(isZero(e, items)) {
    const template = HtmlService.createTemplateFromFile('index');
    const alert = '少なくとも1個以上注文してください。';
    template.deployURL = ScriptApp.getService().getUrl();
    template.formHTML = getFormHTML(e, items, alert);
    const htmlOutput = template.evaluate();
    return htmlOutput;
  }

  // index.htmlで「確認画面へ」ボタンが押されたらconfirm.htmlへ
  if(e.parameter.confirm) {
    const template = HtmlService.createTemplateFromFile('confirm');
    template.deployURL = ScriptApp.getService().getUrl();
    template.confirmHTML = getConfirmHTML(e, items);
    const htmlOutput = template.evaluate();
    return htmlOutput;
  }

  // confirm.htmlで「修正する」ボタンが押されたらindex.htmlへ
  if(e.parameter.modify) {
    const template = HtmlService.createTemplateFromFile('index');
    template.deployURL = ScriptApp.getService().getUrl();
    template.formHTML = getFormHTML(e, items);
    const htmlOutput = template.evaluate();
    return htmlOutput;
  }

  // confirm.htmlで「発注する」ボタンが押されたらcomplete.htmlへ
  if(e.parameter.submit) {
    createOrder(e, items);
    updateZaiko(e, items);
    sendMail(e, items);
    const template = HtmlService.createTemplateFromFile('complete');
    template.deployURL = ScriptApp.getService().getUrl();
    const htmlOutput = template.evaluate();
    return htmlOutput;
  }
}

4〜12行目を追加しました。

5行目でisZeroという未定義の関数を呼び出しているので、これを定義する必要があります。以下のコードをコピーしてコード.gsに貼り付けてください。

function isZero(e, items) {
  let total = 0;
  for(const item of items) {
    const itemId = item['商品ID'];
    const count = Number(e.parameter[itemId]);
    if(count) total += count;
  }
  if(total == 0) return true;
  return false;
}

これで実装完了です。デプロイして確認してみます。

商品をすべて0個の状態で「確認画面へ」を押すと…

再度フォーム入力画面に遷移し、赤い文字で「少なくとも1個以上注文してください。」と表示されました!

商品が在庫切れになってしまったときの対策

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

function doPost(e) {
  const items = getAllRecords('商品');

  // 注文数が0の場合、alert付きでindex.htmlを返す
  if(isZero(e, items)) {
    const template = HtmlService.createTemplateFromFile('index');
    const alert = '少なくとも1個以上注文してください。';
    template.deployURL = ScriptApp.getService().getUrl();
    template.formHTML = getFormHTML(e, items, alert);
    const htmlOutput = template.evaluate();
    return htmlOutput;
  }

  // 商品が在庫切れの場合、alert付きでindex.htmlを返す
  if(outOfStock(e, items)) {
    const template = HtmlService.createTemplateFromFile('index');
    const alert = '入力中に在庫切れとなりました。再度入力してください。';
    template.deployURL = ScriptApp.getService().getUrl();
    template.formHTML = getFormHTML(e, items, alert);
    const htmlOutput = template.evaluate();
    return htmlOutput;
  }

  // index.htmlで「確認画面へ」ボタンが押されたらconfirm.htmlへ
  if(e.parameter.confirm) {
    const template = HtmlService.createTemplateFromFile('confirm');
    template.deployURL = ScriptApp.getService().getUrl();
    template.confirmHTML = getConfirmHTML(e, items);
    const htmlOutput = template.evaluate();
    return htmlOutput;
  }

  // confirm.htmlで「修正する」ボタンが押されたらindex.htmlへ
  if(e.parameter.modify) {
    const template = HtmlService.createTemplateFromFile('index');
    template.deployURL = ScriptApp.getService().getUrl();
    template.formHTML = getFormHTML(e, items);
    const htmlOutput = template.evaluate();
    return htmlOutput;
  }

  // confirm.htmlで「発注する」ボタンが押されたらcomplete.htmlへ
  if(e.parameter.submit) {
    createOrder(e, items);
    updateZaiko(e, items);
    sendMail(e, items);
    const template = HtmlService.createTemplateFromFile('complete');
    template.deployURL = ScriptApp.getService().getUrl();
    const htmlOutput = template.evaluate();
    return htmlOutput;
  }
}

14〜22行目を追加しました。

15行目でoutOfStockという未定義の関数を呼び出しているので、これを定義する必要があります。以下のコードをコピーしてコード.gsに貼り付けてください。

function outOfStock(e, items) {
  for(const item of items) {
    const itemId = item['商品ID'];
    const zaiko = item['在庫数'];
    const count = Number(e.parameter[itemId]);
    if(zaiko < count) {
      return true;
    }
  }

  return false;
}

これで実装完了です。再度デプロイして確認してみます。

スプレッドシート側で水の在庫数を5個にして、

フォーム画面で水を10個注文しようとすると…

再度フォーム入力画面に遷移し、赤い文字で「入力中に在庫切れとなりました。再度入力してください。」と表示されました!

まとめ

以上、バリデーションを実装しました。

ユーザー体験を極限まで高めるために、裏側の細かいところまで気を配って実装することが大切ですね。

引き続きユーザー体験を高めるために、次回はスマホ対応させていきましょう!

連載目次: 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をコピーしました