Googleフォームはスプレッドシートと直接連携することができ、とても便利なツールです。しかし、フォームの見た目は独特で見る人によっては送信ボタンを押すまでの心理的なハードルが上がるかもしれません。
Googleフォームは画像を表示したり色やフォントを変えたりすることはできますが、フォーム自体をCSSでカスタマイズすることはできません。
そんな場合に、WEBサイトに埋め込んだHTMLとCSSのフォームとGoogleフォームを連携させて、Googleフォームに回答を記録させることができます。
ここではその方法を詳しく解説しています。
HTML/CSSフォームとGoogleフォーム連携の流れ
HTML/CSSフォームとGoogleフォームを連携する流れは以下のようになります。
通常のテキストボックスだけでなく、ラジオボタンやプルダウン、チェックボックス、長文テキストボックスなども連携させることができます。
連携時のポイント
HTML/CSSフォームとGoogleフォームを連携するときは以下の点に注意してください。
カスタムフォームとの連携時に、Googleフォームの便利機能の一つである回答コピーの自動送信は使用できません。
詳細については下記をご参照ください。
(参考)GoogleフォームとHTML/CSSのカスタムフォームの連携|回答のコピーを回答者に送信はできない
Googleフォームの作成
まずはGoogleフォームを作成します。
ここでは簡易的に次のようなフォームを作成しました。
GoogleフォームのURLとname属性を取得する
Googleフォームの作成ができたら、GoogleフォームのURLとname属性を取得します。
GoogleフォームのURL
Googleフォームのformタグのaction属性でフォームのURL「https://docs.google.com/forms/u/0/d/e/~/formResponse」を取得します。(※編集画面やviewformのURLではありません)]
開発モードにして「formResponse」と検索します。
上記の場合、取得するURLは以下になります。
name属性の取得
続いて、各設問のname属性を取得します。
Googleフォームの入力画面(https://docs.google.com/forms/d/e/~/viewform)を開いて、各設問に適当な値を入力します。
この状態で開発モードにし「entry」と検索します。
name=”entry.XXXXXXXXX”がついたinputタグの一覧が表示されます。
このname属性をメモしておきます。
これを、以下で作成するHTML/CSSのカスタムフォームのname属性で指定します。
HTML/CSSカスタムフォームの作成
Googleフォームの内容に合わせてHTMLを使ってカスタムフォームを作成します。
作成するのは以下のようなフォームです。
HTML
<main class="contact-wrapper">
<h1 class="contact-h1">お問い合わせフォーム</h1>
<form action="https://docs.google.com/forms/u/0/d/e/1FAIpQLSd_t3Nu_k8X9CjxK9MVjfNGfU2NLe_ghnYeyPJw5a8Gl2u3lg/formResponse">
<!-- テキスト入力 -->
<div class="form-wrapper">
<label class="form_block">
<div class="form_label">お名前<span class="form-required">必須</span></div>
<input type="text" name="entry.398798226" class="form_field" placeholder="田中太郎" required>
</label>
</div>
<!-- メールアドレス -->
<div class="form-wrapper">
<label class="form_block">
<div class="form_label">メールアドレス<span class="form-required">必須</span></div>
<input type="email" id="email" class="form_field" name="emailAddress" placeholder="t.tanaka@gmail.com" pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$" required>
</label>
</div>
<!-- 電話番号 -->
<div class="form-wrapper">
<label class="form_block">
<div class="form_label">電話番号<span class="form-required">必須</span></div>
<input type="tel" name="entry.412682472" class="form_field" pattern="\d{3}-\d{4}-\d{4}" placeholder="090-1234-5678(※ハイフンあり。半角で記入してください)" required>
</label>
</div>
<!-- ラジオボタン -->
<div class="form-wrapper">
<div class="form_label">性別</div>
<div class="form_radio-wrapper">
<label class="label_radio">
<input type="radio" name="entry.1519160350" value="男性" checked class="form_radio">
<span class="radio_span">男性</span>
</label>
<label class="label_radio">
<input type="radio" name="entry.1519160350" value="女性" class="form_radio">
<span class="radio_span">女性</span>
</label>
</div>
</div>
<!-- プルダウン -->
<div class="form-wrapper">
<div class="form_label">年代<span class="form-required">必須</span></div>
<select name="entry.510987228" class="form_field">
<option class="select-option" value="20代">20代</option>
<option class="select-option" value="30代">30代</option>
<option class="select-option" value="40代">40代</option>
</select>
</div>
<!-- チェックボックス -->
<div class="form-wrapper">
<div class="form_label">何で知ったか?(複数選択可)<span class="form-required">必須</span></div>
<div class="form_radio-wrapper">
<label class="label_radio">
<input type="checkbox" name="entry.85665797" value="WEB検索" checked class="form_radio">
<span class="radio_span">WEB検索</span>
</label>
<label class="label_radio">
<input type="checkbox" name="entry.85665797" value="インスタグラム" class="form_radio">
<span class="radio_span">インスタグラム</span>
</label>
<label class="label_radio">
<input type="checkbox" name="entry.85665797" value="その他" class="form_radio">
<span class="radio_span">その他</span>
</label>
</div>
</div>
<!-- テキストエリア -->
<div class="form-wrapper">
<label class="form_block">
<div class="form_label">自由コメント
<textarea class="form_field --textfield" placeholder="" name="entry.509306662"></textarea>
</label>
</div>
<!-- 送信ボタン -->
<button type="submit" class="form-btn">送信する</button>
<p class="privacy">※<a href="">個人情報保護方針</a>について同意した上で、送信してください。</p>
</form>
</main>
CSS
.form-wrapper{
margin-bottom: 20px;
}
.form_label{
margin-bottom: 4px;
}
.form-required {
display: inline-block;
margin-left: 10px;
padding: 2px 5px;
border-radius: 3px;
background-color: #f2dede;
color: #a94442;
font-weight: bold;
}
.form_field {
width: 100%;
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
box-sizing: border-box;
}
.form_field:focus {
outline: none;
border-color: #4CAF50; /* フォーカス時のボーダー色 */
box-shadow: 0 0 5px #4CAF50;
}
.form-btn {
background-color: skyblue;
color: white;
font-size: 1.2em;
padding: 10px 40px;
border: none;
border-radius: 40px;
cursor: pointer;
}
.privacy{
font-size: 0.7em;
}
以上で設定は完了です。
この状態でフォームに入力し、送信ボタンをクリックすると、Googleフォームの送信完了画面が表示されます。
スプレッドシートへの自動追記をONにしている場合は、もちろんスプレッドシートにデータが記録されます。
HTMLコードの解説
Googleフォームとカスタムフォームの連携で最も重要になるのがHTMLです。ここでは、各コードの内容を解説します。
formタグ
formタグは以下のようになっています。
<form action="https://docs.google.com/forms/u/0/d/e/1FAIpQLSd_t3Nu_k8X9CjxK9MVjfNGfU2NLe_ghnYeyPJw5a8Gl2u3lg/formResponse">
action
属性
フォーム送信先URLとして、Googleフォームを指定しています。ユーザーが送信したデータをフォームの回答として記録します。
テキスト入力(input type=”text”)
テキスト入力の場合、inputタグのname属性をGoogleフォームと合わせます。
<!-- テキスト入力 -->
<div class="form-wrapper">
<label class="form_block">
<div class="form_label">お名前<span class="form-required">必須</span></div>
<input type="text" name="entry.398798226" class="form_field" placeholder="田中太郎" required>
</label>
</div>
メールアドレス(input type=”email”)
inputタグのname属性をGoogleフォームと合わせます。
Googleフォームで「メールアドレスを収集する」とした場合、name属性は「emailAddress」になります。
<!-- メールアドレス -->
<div class="form-wrapper">
<label class="form_block">
<div class="form_label">メールアドレス<span class="form-required">必須</span></div>
<input type="email" id="email" class="form_field" name="emailAddress" placeholder="t.tanaka@gmail.com" pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$" required>
</label>
</div>
電話番号(input type=”tel”)
inputタグのname属性をGoogleフォームと合わせます。
<!-- 電話番号 -->
<div class="form-wrapper">
<label class="form_block">
<div class="form_label">電話番号<span class="form-required">必須</span></div>
<input type="tel" name="entry.412682472" class="form_field" pattern="\d{3}-\d{4}-\d{4}" placeholder="090-1234-5678(※ハイフンあり。半角で記入してください)" required>
</label>
</div>
pattern属性でハイフンあり半角数値を指定しています。ブラウザによって機能しないことがあるので、完全なバリデーションを機能させたい場合はJavaScriptで組む必要があります。
function validatePhoneNumber(phoneNumber) {
// 簡易的なバリデーション例(ハイフンなしの11桁の数字のみ許可)
const regex = /\d{3}-\d{4}-\d{4}/;
return regex.test(phoneNumber);
}
// フォーム送信時にバリデーションを実行
document.getElementById('myForm').addEventListener('submit', function(event) {
const phoneNumber = document.getElementById('phoneNumber').value;
if (!validatePhoneNumber(phoneNumber)) {
alert('電話番号の形式が正しくありません。');
event.preventDefault();
}
});
ラジオボタン(input type=”radio”)
ラジオボタンの場合、各inputタグごとにGoogleフォームのname属性を指定します(※同じ値になります)。
また、value属性をGoogleフォームの設問の値と必ず一致させる必要があります。
<!-- ラジオボタン -->
<div class="form-wrapper">
<div class="form_label">性別</div>
<div class="form_radio-wrapper">
<label class="label_radio">
<input type="radio" name="entry.1519160350" value="男性" checked class="form_radio">
<span class="radio_span">男性</span>
</label>
<label class="label_radio">
<input type="radio" name="entry.1519160350" value="女性" class="form_radio">
<span class="radio_span">女性</span>
</label>
</div>
</div>
プルダウン(selectタグとoptionタグ)
プルダウンの場合、selectタグにGoogleフォームのname属性を指定します。
※optionタグごとにname属性をつけるわけではありません。
<!-- プルダウン -->
<div class="form-wrapper">
<div class="form_label">年代<span class="form-required">必須</span></div>
<select name="entry.510987228" class="form_field">
<option class="select-option" value="20代">20代</option>
<option class="select-option" value="30代">30代</option>
<option class="select-option" value="40代">40代</option>
</select>
</div>
チェックボックス(input type=”checkbox”)
チェックボックスの場合、各inputタグごとにGoogleフォームのname属性を指定します(※同じ値になります)。
また、value属性をGoogleフォームの設問の値と必ず一致させる必要があります。
<!-- チェックボックス -->
<div class="form-wrapper">
<div class="form_label">何で知ったか?(複数選択可)<span class="form-required">必須</span></div>
<div class="form_radio-wrapper">
<label class="label_radio">
<input type="checkbox" name="entry.85665797" value="WEB検索" checked class="form_radio">
<span class="radio_span">WEB検索</span>
</label>
<label class="label_radio">
<input type="checkbox" name="entry.85665797" value="インスタグラム" class="form_radio">
<span class="radio_span">インスタグラム</span>
</label>
<label class="label_radio">
<input type="checkbox" name="entry.85665797" value="その他" class="form_radio">
<span class="radio_span">その他</span>
</label>
</div>
</div>
テキストエリア(textareaタグ)
inputタグのname属性をGoogleフォームと合わせます。
<!-- テキストエリア -->
<div class="form-wrapper">
<label class="form_block">
<div class="form_label">自由コメント
<textarea class="form_field --textfield" placeholder="" name="entry.509306662"></textarea>
</label>
</div>
送信ボタン(button type=”submit”)
送信ボタンは特にGoogleフォームと連携させる必要はありません。
<!-- 送信ボタン -->
<button type="submit" class="form-btn">送信する</button>
<p class="privacy">※<a href="">個人情報保護方針</a>について同意した上で、送信してください。</p>
サンクスページを表示する
デフォルトではフォーム送信後にGoogleフォームの送信完了画面が表示されます。
これをオリジナルのサンクスページにすることもできます。
formタグに属性を追加
formタグに「method」「target」「onsbumit」属性を追加します。
<form action="https://docs.google.com/forms/u/0/d/e/1FAIpQLSd_t3Nu_k8X9CjxK9MVjfNGfU2NLe_ghnYeyPJw5a8Gl2u3lg/formResponse"
method="post"
target="hidden_iframe"
onsubmit="submitted=true;">
action
属性
フォーム送信先URLとして、Googleフォームを指定しています。ユーザーが送信したデータをフォームの回答として記録します。
method
属性
データ送信のHTTPメソッドを指定しています。値をpostにすることで、post形式でデータ送信をします。フォームデータをサーバーに送信する際に使用され、一般的に安全でデータ量が多い場合にも適しています。
target
属性
送信後の応答が表示されるターゲットを指定します。ここでは hidden_iframeを指定することで、HTML内のiframeタグを入れておくことで、ゆーがーに対して送信完了のページを直接表示せず、バックグラウンドで処理できます。
onsubmit
属性
フォームが送信された際にJavaScriptコードを実行します。
submitted=true; としているため、JavaScript変数 submitted が true に設定されます。これにより、送信ステータスを管理したり、送信後の動作を制御できます。
scriptタグの追加
form閉じタグの前に以下のscriptタグを追加します。
<script type="text/javascript">
var submitted = false;
</script>
submitted というグローバル変数を宣言し、初期値を false に設定しています。
フォームが送信されたかどうかを追跡するために使います。フォーム送信時にこの変数を true に変更し、その状態に応じて処理を分岐します。
trueにする処理はformタグに記入したsubmitted=true;
で行います。
iframeタグの追加
form閉じタグの前に(上記scriptタグの下)に次のコードを追加します。
<iframe name="hidden_iframe" id="hidden_iframe" style="display: none" onload="if(submitted) {window.location='リダイレクト先のURL';}"></iframe>
<iframe>
の用途
フォームの送信後、送信先サーバーからの応答をバックグラウンドで処理します。style="display: none"
によってユーザーには見えない形で埋め込まれています。
name="hidden_iframe"
フォームの target
属性で指定されたターゲット先です。フォーム送信時の結果(応答ページ)がこの <iframe>
内に表示されます。
id="hidden_iframe"
JavaScriptから参照するための一意の識別子。
style="display: none"
表示しないスタイル設定。
onload
<iframe>
の内容がロードされたときにJavaScriptを実行します。
if(submitted) { window.location='リダイレクト先URL'; }
フォーム送信後に <iframe>
の内容がロードされると、このスクリプトが実行されます。
submitted
が true
の場合のみ、window.location
を使ってユーザーを 'リダイレクトURL'
にリダイレクトします。
サンクスページありのHTMLとCSS
HTML
<main class="contact-wrapper">
<h1 class="contact-h1">お問い合わせフォーム</h1>
<form action="https://docs.google.com/forms/u/0/d/e/1FAIpQLSd_t3Nu_k8X9CjxK9MVjfNGfU2NLe_ghnYeyPJw5a8Gl2u3lg/formResponse" method="post" target="hidden_iframe" onsubmit="submitted=true;">
<!-- テキスト入力 -->
<div class="form-wrapper">
<label class="form_block">
<div class="form_label">お名前<span class="form-required">必須</span></div>
<input type="text" name="entry.398798226" class="form_field" placeholder="田中太郎" required>
</label>
</div>
<!-- メールアドレス -->
<div class="form-wrapper">
<label class="form_block">
<div class="form_label">メールアドレス<span class="form-required">必須</span></div>
<input type="email" id="email" class="form_field" name="emailAddress" placeholder="t.tanaka@gmail.com" pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$" required>
</label>
</div>
<!-- 電話番号 -->
<div class="form-wrapper">
<label class="form_block">
<div class="form_label">電話番号<span class="form-required">必須</span></div>
<input type="tel" name="entry.412682472" class="form_field" pattern="\d{3}-\d{4}-\d{4}" placeholder="090-1234-5678(※ハイフンあり。半角で記入してください)" required>
</label>
</div>
<!-- ラジオボタン -->
<div class="form-wrapper">
<div class="form_label">性別</div>
<div class="form_radio-wrapper">
<label class="label_radio">
<input type="radio" name="entry.1519160350" value="男性" checked class="form_radio">
<span class="radio_span">男性</span>
</label>
<label class="label_radio">
<input type="radio" name="entry.1519160350" value="女性" class="form_radio">
<span class="radio_span">女性</span>
</label>
</div>
</div>
<!-- プルダウン -->
<div class="form-wrapper">
<div class="form_label">年代<span class="form-required">必須</span></div>
<select name="entry.510987228" class="form_field">
<option class="select-option" value="20代">20代</option>
<option class="select-option" value="30代">30代</option>
<option class="select-option" value="40代">40代</option>
</select>
</div>
<!-- チェックボックス -->
<div class="form-wrapper">
<div class="form_label">何で知ったか?(複数選択可)<span class="form-required">必須</span></div>
<div class="form_radio-wrapper">
<label class="label_radio">
<input type="checkbox" name="entry.85665797" value="WEB検索" checked class="form_radio">
<span class="radio_span">WEB検索</span>
</label>
<label class="label_radio">
<input type="checkbox" name="entry.85665797" value="インスタグラム" class="form_radio">
<span class="radio_span">インスタグラム</span>
</label>
<label class="label_radio">
<input type="checkbox" name="entry.85665797" value="その他" class="form_radio">
<span class="radio_span">その他</span>
</label>
</div>
</div>
<!-- テキストエリア -->
<div class="form-wrapper">
<label class="form_block">
<div class="form_label">自由コメント
<textarea class="form_field --textfield" placeholder="" name="entry.509306662"></textarea>
</label>
</div>
<!-- 送信ボタン -->
<button type="submit" class="form-btn">送信する</button>
<p class="privacy">※<a href="">個人情報保護方針</a>について同意した上で、送信してください。</p>
<!-- サンクスページにリダイレクト -->
<script type="text/javascript">
var submitted = false;
</script>
<iframe name="hidden_iframe" id="hidden_iframe" style="display: none" onload="if(submitted) {window.location='/thanks/';}"></iframe>
</form>
</main>
.form-wrapper{
margin-bottom: 20px;
}
.form_label{
margin-bottom: 4px;
}
.form-required {
display: inline-block;
margin-left: 10px;
padding: 2px 5px;
border-radius: 3px;
background-color: #f2dede;
color: #a94442;
font-weight: bold;
}
.form_field {
width: 100%;
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
box-sizing: border-box;
}
.form_field:focus {
outline: none;
border-color: #4CAF50; /* フォーカス時のボーダー色 */
box-shadow: 0 0 5px #4CAF50;
}
.form-btn {
background-color: skyblue;
color: white;
font-size: 1.2em;
padding: 10px 40px;
border: none;
border-radius: 40px;
cursor: pointer;
}
.privacy{
font-size: 0.7em;
}