みなさんこんにちは!GASおじさんです。
「GAS x HTMLで確認画面付きの本格的な発注フォームを作ろう」シリーズの第4回です。
前回の記事はこちら。
今回は「doPost関数で確認画面ページに遷移させよう」ということでやっていきます。
Youtubeでも解説していますので、動画で見たい方は以下からどうぞ。
前回のおさらい
前回はBootstrapを使ってフォーム画面の見た目を整えるところまで実装できました。

無事見た目を整えることはできたのですが、機能面はまだ実装できておりません。
ためしにEmailとお名前を入力して、フォームの送信ボタン(上記画像では「確認画面へ」ボタン)をクリックしてみてください。
以下のようにまっさらなページに遷移するだけで何も起きないと思います。

今回はこの状態から、「確認画面へ」ボタンを押したら、以下のような確認画面ページに遷移するようにしていきたいと思います。

doPost関数で確認画面ページに遷移させよう
確認画面ページ(confirm.html)を用意する
ということでやっていきます。
まずはテンプレートとなる確認画面ページのHTMLを用意していきましょう。
confirm.html
という名前のHTMLファイルを作成してください。

作成したらbodyタグの中に、<h2>確認画面</h2>
を挿入して保存してください。
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h2>確認画面</h2>
</body>
</html>

doPost関数でフォーム送信後confirm.htmlに遷移させる
doPost関数を定義する
次にコード.gs
ファイルにdoPost
関数を定義します。
以下のコードをコピーしてコード.gsに貼り付けてください。
function doPost(e) {
const template = HtmlService.createTemplateFromFile('confirm');
const htmlOutput = template.evaluate();
return htmlOutput;
}

このdoPost関数とは何かというと、フォーム送信時に実行される特殊な関数です。
doGet関数と似ていますね。
- doGetはデプロイしたURLにアクセスしたときに(GETリクエストしたときに)実行される
- doPostはフォームの送信ボタンが押されたときに(POSTリクエストしたときに)実行される
というような形で対比させるとわかりやすいでしょう。上記のコードは、
- doGet関数が実行されたら
index.html
を返す
- doPost関数が実行されたら
confirm.html
を返す
というような内容になっています。
それでは、この状態で一度保存してデプロイしてみましょう。
右上の「デプロイ」から「新しいデプロイ」をクリックします。

続けて右下の「デプロイ」ボタンをクリックしてデプロイします。

ウェブアプリのURLをクリックしてページを表示しましょう。

Emailとお名前を適当に入力して、「確認画面へ」ボタンをクリックします。

これで確認画面ページが表示されるはず!
と思いきや…

またも白紙のページが表示されてしまいました。
これはなぜかというと、index.htmlのformタグにaction属性が設定されていないからです。
formタグにaction属性を与える
HTMLでformタグを使う際は、actionという属性を与えてあげることによって、フォーム送信後の動きを実装することができます。
現状index.htmlのformタグは、以下のようになっていると思います。
<form class="mb-5" method="POST">

ここにaction属性を与えてあげましょう。
<form class="mb-5" method="POST" action="">

このaction属性にURLを設定することによって、フォーム送信後そのURLに遷移させることができます。
フォーム送信後のURLは、デプロイURLを設定します。
画面右上の「デプロイ」から「デプロイを管理」をクリックしてください。

デプロイ済みウェブアプリのURLをコピーします。

コピーしたURLをactionの二重引用符の中に貼り付けましょう。
<form class="mb-5" method="POST" action="https://script.google.com/macros/s/xxxxxxxxxx/exec">

これで再度デプロイしてみます。
ファイルを保存したら、再度右上の「デプロイ」から「新しいデプロイ」をしてください。
デプロイが完了したらウェブアプリを開いて、再度Emailとお名前を入力し「確認画面へ」を押してみます。

すると、、、

「確認画面」という文字が表示されたページに遷移しました!
これは先ほどconfirm.htmlに書いたh2タグの文字ですね。
つまり、フォーム送信後、無事confirm.htmlを返すことに成功していることが確認できました。
常に最新のデプロイURLが反映されるようにする
ここで1点問題があります。
先ほどformタグのactionにデプロイURLを反映しましたが、その後新たにデプロイを行なったため、最新のデプロイURLが新しいものに変わっています。
つまり、現状formのactionに設定されているURLは、1個古いバージョンのデプロイURLなんですね。
なのでこれを新しいものにする必要があるのですが、
新しいURLをコピーしてactionに貼り付けて再度デプロイすると、またその時点でデプロイURLが新しいものに変化してしまうので、これではイタチごっこの状態になってしまいます。
これを解決するために、デプロイURLを変数化してformタグに反映する必要があります。
ということでまずはコード.gsファイルでデプロイURLを変数化します。
コード.gsのdoGet関数に、
template.deployURL = ScriptApp.getService().getUrl();
という1行を追加してください。
function doGet(e) {
const template = HtmlService.createTemplateFromFile('index');
template.deployURL = ScriptApp.getService().getUrl();
const htmlOutput = template.evaluate();
return htmlOutput;
}

こうすることで最新のデプロイURLをindex.html側でdeployURL
という変数として扱うことができます。
次にindex.htmlのformタグを以下のように書き換えてください。
<form class="mb-5" method="POST" action="<?= deployURL ?>">

actionに与えたURLの部分を、<?= deployURL ?>
と書き換えました。
こうすることでコード.gsファイルで定義した変数deployURL
をindex.html側に反映することができます。
確認画面の見た目を整える
最後に「確認画面」という文字だけが書かれたシンプルな確認画面を、最終形のリッチな見た目に近づけていきましょう。
confirm.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 ?>">
<div class="mb-3">
<label for="email" class="form-label">Email</label>
<input type="email" class="form-control" id="email" name="email" value="test@gmail.com" readonly>
</div>
<div class="mb-3">
<label for="username" class="form-label">お名前</label>
<input type="username" class="form-control" id="username" name="username" value="テスト" readonly>
</div>
<p class="mb-3">商品の個数を入力してください。</p>
<table class="table">
<thead>
<tr>
<th scope="col" class="text-start">商品</th>
<th scope="col" class="text-end">単価</th>
<th scope="col" class="text-end">個数</th>
<th scope="col" class="text-end">金額</th>
</tr>
</thead>
<tbody>
<tr>
<td class="text-start">パソコン</td>
<td class="text-end">@¥100,000</td>
<td class="text-end">
<div class="d-flex justify-content-end">
<input type="number" style="max-width: 100px; min-width: 60px;" class="form-control text-end" name="computer" value="1" readonly>
</div>
</td>
<td class="text-end">¥100,000</td>
</tr>
<tr>
<td class="text-start">スマホ</td>
<td class="text-end">@¥50,000</td>
<td class="text-end">
<div class="d-flex justify-content-end">
<input type="number" style="max-width: 100px; min-width: 60px;" class="form-control text-end" name="smartphone" value="3" readonly>
</div>
</td>
<td class="text-end">¥150,000</td>
</tr>
<tr>
<td colspan="2" class="text-end fs-2">合計:</td>
<td colspan="2" class="text-end fs-2">¥250,000</td>
</tr>
</tbody>
</table>
<button type="submit" class="btn btn-primary" name="submit" value="true">発注する</button>
</form>
</div>
</body>
</html>

また、こちらでもdeployURL
という変数を利用しているため、コード.gsのdoPost関数にも、
template.deployURL = ScriptApp.getService().getUrl();
を追加してください。
function doPost(e) {
const template = HtmlService.createTemplateFromFile('confirm');
template.deployURL = ScriptApp.getService().getUrl();
const htmlOutput = template.evaluate();
return htmlOutput;
}

ここまでできたらファイルを保存して、再度デプロイします。
右上の「デプロイ」から「新しいデプロイ」を実行して、ページの動きを確認してみましょう。

各項目を適当に入力して「確認画面へ」ボタンを押すと、、、

リッチな見た目の確認画面に遷移しました!
なお、現状はEmailやお名前などは仮置きのデータを置いているため、実際の入力内容と異なっていますが、ここらへんについては後々実装していきます。
まとめ
以上、「doPost関数で確認画面ページに遷移させよう」ということで解説しました。
今回のポイントは以下の2点ですね。
- doPost関数(GAS)
- formタグのaction属性(HTML)
より深く理解したい人はこの2点について詳しく調べてみるといいでしょう。
次回は「確認画面ページから発注完了ページに遷移させよう」ということで解説していきます。以下をクリックして次に進みましょう!
連載目次: GAS x HTMLで確認画面付きの本格的な発注フォームを作ろう
- 【GAS x HTML】確認画面付きの本格的な発注フォームを作る
- GASとHTMLで簡単なWebページを表示する方法
- 【GAS】Bootstrapを使ってフォーム画面を作る方法
- doPost関数で確認画面ページに遷移させよう
- 確認画面ページから発注完了ページに遷移させよう
- 【GASxHTML】スプレッドシートの商品データを動的に表示する
- フォームの入力内容を確認画面ページに渡そう
- 確認画面ページに「修正する」ボタンを実装しよう
- 確認画面ページの「発注する」ボタンクリック後の機能を実装しよう
- 【GASxHTML】フォームのバリデーションを実装しよう
- GASとHTMLで作ったWebアプリをスマホ対応させる方法
コメント