質問するログイン新規登録

Q&A

2回答

106閲覧

アンケートフォーム2ページを作成したが、1ページ目、2ページ目、いずれかのデーターしか保存されない

naaS

総合スコア7

CSS3

CSS(Cascading Style Sheet)の第3版です。CSS3と略されることが多いです。色やデザインを柔軟に変更することが可能になります。

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2026/06/05 15:58

編集2026/06/05 16:05

0

0

実現したいこと

1ページ目を保存して2ページ目に遷移し、2ページ目も保存して、送信ボタンを押すと、グーグルのスプレッドシートにアンケートの入力内容を2ページ分書きこめるようにしたい。

発生している問題・分からないこと

グーグルの検証画面では、2ページ目の入力内容のみ表示される。1ページ目が保存されていません。

該当のソースコード

preview.html

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4<meta charset="UTF-8"> 5<title>講義アンケート</title> 6<link rel="stylesheet" href="css/storage.css"> 7<script src="js/storage.js"></script> 8</head> 9<body> 10<h1>講義アンケート</h1> 11<div class="toptext">お手数ですがアンケートの記入にご協力下さい。</div> 12<form> 13<table> 14<tr> 15 <th>この講義を知ったきっかけ</th> 16 <td class="checkbox"> 17 <label> 18 <input type="checkbox" name="theme" value="ホームページ">ホームページ 19 <input type="checkbox" name="theme" value="SNS">SNS 20 <input type="checkbox" name="theme" value="知人の紹介">知人の紹介 21 <input type="checkbox" name="theme" value="メール">メール 22 <input type="checkbox" name="theme" value="チラシ">チラシ 23 <input type="checkbox" name="theme" value="その他">その他 24 </label> 25 </td> 26</tr> 27<tr> 28<th>年代</th> 29<td id="radio_btn"> 30<label><input type="radio" name="age" id="age20" value="20代">20代</label> 31<label><input type="radio" name="age" id="age30" value="30代">30代</label> 32<label><input type="radio" name="age" id="age40" value="40代">40代</label> 33<label><input type="radio" name="age" id="age50" value="50代">50代</label> 34<label><input type="radio" name="age" id="age60" value="60代">60代</label> 35<label><input type="radio" name="age" id="age70" value="70代">70代</label> 36</td> 37</tr> 38<tr> 39<th>性別</th> 40<td id="radio_btn"> 41<label><input type="radio" name="gender" id="male" value="男性">男性</label> 42<label><input type="radio" name="gender" id="woman" value="女性">女性</label> 43<label><input type="radio" name="gender" id="gender_free" value="答えたくない">答えたくない</label> 44</td> 45</tr> 46<tr> 47<th>勤務先の市町村</th> 48<td> 49<input type="text" id="city" name="city" placeholder="例:札幌市"> 50</td> 51</tr> 52<tr> 53<th>雇用形態</th> 54<td id="radio_btn"> 55<label><input type="radio" name="job" id="officer" value="役員">役員</label> 56<label><input type="radio" name="job" id="manager" value="正規雇用(管理職)">正規雇用(管理職)</label> 57<label><input type="radio" name="job" id="regular" value="正規雇用一般">正規雇用一般</label> 58<label><input type="radio" name="job" id="part" value="パート・アルバイト">パート・アルバイト</label> 59<label><input type="radio" name="job" id="contract" value="契約社員">契約社員</label> 60<label><input type="radio" name="job" id="others" value="その他">その他</label> 61</td> 62</tr> 63<tr> 64<th>今回の講義の内容は理解できましたか?</th> 65<td> 66<label><input type="radio" name="understand" id="very_good" value="大変よく理解できた">大変よく理解できた</label><br> 67<label><input type="radio" name="understand" id="good" value="理解できた">理解できた</label><br> 68<label><input type="radio" name="understand" id="normal" value="普通">普通</label><br> 69<label><input type="radio" name="understand" id="bad" value="分かりにくく、あまりよく理解できなかった"> 70分かりにくく、あまりよく理解できなかった</label><br> 71<label><input type="radio" name="understand" id="very_bad" value="分かりにくく、まったく理解できなかった"> 72分かりにくく、まったく理解できなかった</label> 73</td> 74</tr> 75<tr> 76<th> 77今回の講義についての感想・意見・要望 78</th> 79<td> 80<textarea id="comment" name="comment" placeholder="例:オンライン講義を増やしてほしい"></textarea> 81</td> 82</tr> 83</table> 84<div class="page_btn"> 85 <!--button type="button" onclick="saveData(); location.href='page2.html';"> 86 次のページへ 87 </button--> 88 <button type="button" onclick="goNextPage()"> 89 次のページへ 90 </button> 91</div> 92</form> 93</body> 94</html> 95 96 97

page2.html

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4<meta charset="UTF-8"> 5<link rel="stylesheet" href="css/storage.css"> 6<script src="js/storage.js"></script> 7<style> 8textarea{ 9 width:98%; 10 height:20px; 11 padding:1%; 12 resize:vertical; 13} 14</style> 15</head> 16<body> 17<h1>講義アンケート2ページ目</h1> 18<div class="toptext">お手数ですがアンケートの記入にご協力下さい。</div> 19<form> 20<table> 21<tr> 22<th>将来、望む雇用形態</th> 23<td id="radio_btn"> 24<label> 25<input type="radio" name="future_job" value="管理職以上">管理職以上</label> 26<label><input type="radio" name="future_job" value="正社員">正社員</label> 27<label><input type="radio" name="future_job" value="アルバイト・パート">契約社員</label> 28<label><input type="radio" name="future_job" value="契約社員">契約社員</label> 29<label><input type="radio" name="future_job" value="派遣社員">派遣社員</label> 30</td> 31</tr> 32<tr> 33 <th>将来、希望する勤務地</th> 34 <td class=""> 35<select id="pref"> 36<option value="大都市">大都市</option> 37<option value="中堅都市">中堅都市</option> 38<option value="地方都市">地方都市</option> 39<option value="地方市町村">地方市町村</option> 40<option value="その他地域">その他地域</option> 41<option value="フリーランス">フリーランス</option> 42</select> 43</td> 44</tr> 45<tr> 46<th>平日20時~21時30分までという講義時間帯は適切だったでしょうか?<br>もし、不適切だと感じる場合は、適切だと思う時間帯を記入してください。</th> 47<td> 48<input type="text" id="lecture_time" name="lecture_time" placeholder="(例)土曜日昼間にしてほしい"> 49</td> 50</tr> 51<tr> 52<th> 53受講料は適切な金額だと思いますか?<br>高すぎると感じる場合は、いくらなら適切と思うかも書いてください。 54</th> 55<td> 56<textarea id="fee_comment" name="fee_comment" class="small_text" placeholder="例:3日あたり10000円がちょうどいい。"></textarea> 57</td> 58</tr> 59<tr> 60<th> 61ゲストで呼んでほしい講師がいたら記述してください。<br>講師の名前、所属先、呼んでほしい理由も書き添えて下さい。 62</th> 63<td> 64<textarea id="guest_comment" name="guest_comment" class="large_text" placeholder="例:○○大学○○学部○○教授"></textarea> 65</td> 66</tr> 67</table> 68<div class="submit_area"> 69 <button type="button" onclick="saveData(); sendData();"> 70 送信する 71 </button> 72 <!--button type="button" onclick="sendData()"> 73 送信する 74 </button--> 75</div> 762ページ 77</form> 78</body> 79</html> 80 81 82 83

storage.css

1@charset "UTF-8"; 2body{ 3 font-family: sans-serif; 4 background:#f5f5f5; 5 padding:30px; 6} 7h1{ 8 text-align:center; 9 margin-bottom:30px; 10} 11.toptext { 12 margin-bottom:30px; 13} 14table{ 15 width:100%; 16 border-collapse:collapse; 17 background:#fff; 18} 19th, 20td{ 21 border:1px solid #999; 22 padding:12px; 23 vertical-align:top; 24} 25th{ 26 width:30%; 27 background:#e9eef5; 28 text-align:left; 29} 30.checkbox input { 31 margin-right:15px; 32 display:inline-block; 33 margin-bottom:8px; 34} 35#radio_btn label { 36 margin-right:15px; 37 38 margin-bottom:8px; 39} 40input[type="text"]{ 41 width:98%; 42 padding:1%; 43} 44textarea{ 45 width:98%; 46 height:180px; 47 padding:1%; 48 resize:vertical; 49} 50.submit_area{ 51 text-align:center; 52 margin-top:30px; 53} 54button{ 55 padding:12px 40px; 56 font-size:16px; 57 cursor:pointer; 58} 59.page_btn { 60 text-align: center; 61 margin-top: 30px; 62} 63.page_btn a { 64 text-decoration: none; 65} 66.small_text{ 67 height:60px; 68} 69.large_text{ 70 height:150px; 71} 72.submit_area{ 73 text-align:center; 74 margin-top:30px; 75}

storage.js

1https://codepen.io/editor/vxgqlvoa-the-reactor/pen/019e987c-ea8e-7e5f-bd5f-c09a728aac80 2

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

各htmlに、コメントアウトしてあるコードがあります。次のページへボタン、 送信するボタン。これらは、現在のコードを書き替えて動作を比較。jsも、htmlの1ページ目の値の取得のコードを削除と復活、しましたが正常に動作しない。ビジュアルスタジオコードの簡易サーバーもうまくいきませんでした。

補足

jsは、文字数制限がありますので、コーデパンに書きました。
以下はグーグルのスプレッドシートです。
https://docs.google.com/spreadsheets/d/19PmAfc-sQaENAxne8uBiNq_PS-2MST6hSA4GpbqVkD0/edit?hl=ja&gid=0#gid=0
正常に入力ができませんでした。

以下はデプロイの画面です。
https://script.google.com/home/projects/1H5Jk2cDyxcHrNA98XYtRvYFhD2ydyDWH4tsJvosye-sN-CjTJkQ4GZRo/edit

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

guest

回答2

0

コンソールでデータが全部送信されているのを確認できたなら、フロントエンド側はもう大丈夫です。
問題はほぼ間違いなくGASの書き方にあります。


まず見たところ、あなたのGASのコードで

javascript

1sheet.appendRow([...])

と書いてありますが、この sheet がどこにも定義されていません。
これが一番大きな原因です。

GASでは、スプレッドシートを操作する前に

javascript

1SpreadsheetApp.openById('シートID').getActiveSheet()

とかを使って、どのシートに書き込むのかを明示してあげないといけません。
これをやらないと sheet is not defined エラーになって、何も書けません。
多分ログを見ればエラーが出ているはずです。

具体的には、doPost 関数の先頭で以下のように書いてください。

javascript

1const SPREADSHEET_ID = '19PmAfc-sQaENAxne8uBiNq_PS-2MST6hSA4GpbqVkD0'; 2const sheet = SpreadsheetApp.openById(SPREADSHEET_ID).getActiveSheet();

もしシート名がデフォルトの「シート1」ではないなら、.getSheetByName('シート名') に変えてください。


次に、日付だけが書き込まれて他の項目が入っていないという現象についてです。

これはおそらく、data.agedata.gender といった値が全部 undefined になっているからです。
つまり、GASが受け取ったJSONの中に age というキーが存在していないか、パース自体に失敗している可能性があります。

確認するには、GASのコードにログを仕込んでください。

javascript

1console.log('生のPOSTデータ:', e.postData.contents); 2let data = JSON.parse(e.postData.contents); 3console.log('パース後:', data);

ログはエディタの「表示」→「ログ」から見られます。
何が送られてきているか、ぜひ確認してみてください。


もう一つ、よくあるのが「デプロイの更新忘れ」です。

GASはコードを保存しただけではウェブアプリに反映されません。
必ず「デプロイ」→「新しいデプロイ」を実行して、新しいURLを発行し、
そのURLをあなたの storage.js の中の GAS_URL にセットし直してください。

古いURLのまま動かしていると、古いコード(sheet が定義されていない方)が動き続けます。

投稿2026/06/06 08:13

blixor

総合スコア50

0

何が悪いか

1ページ目と2ページ目で、localStorageに保存するときのキーが同じ(たぶん"formData")だから、2ページ目で保存した瞬間に1ページ目のデータが上書きされて消える。
それだけが原因じゃなくて、そもそも1ページ目のデータ取得がうまくいってない可能性もあるけど、まずは上書き問題を直さないと話にならない。

どう直すか

キーをページごとに分ける。
1ページ目は"page1"、2ページ目は"page2"で保存。
送信するときに両方読み込んでくっつけてからGASに送る。

下のstorage.js、全部置き換えて使ってみて。

javascript

1// 1ページ目のデータを拾う 2function getPage1Data() { 3 let data = {}; 4 let theme = document.querySelectorAll('input[name="theme"]:checked'); 5 data.theme = Array.from(theme).map(cb => cb.value); 6 let age = document.querySelector('input[name="age"]:checked'); 7 data.age = age ? age.value : ''; 8 let gender = document.querySelector('input[name="gender"]:checked'); 9 data.gender = gender ? gender.value : ''; 10 let job = document.querySelector('input[name="job"]:checked'); 11 data.job = job ? job.value : ''; 12 let understand = document.querySelector('input[name="understand"]:checked'); 13 data.understand = understand ? understand.value : ''; 14 let city = document.getElementById('city'); 15 data.city = city ? city.value : ''; 16 let comment = document.getElementById('comment'); 17 data.comment = comment ? comment.value : ''; 18 return data; 19} 20 21// 2ページ目のデータを拾う 22function getPage2Data() { 23 let data = {}; 24 let future = document.querySelector('input[name="future_job"]:checked'); 25 data.future_job = future ? future.value : ''; 26 let pref = document.getElementById('pref'); 27 data.pref = pref ? pref.value : ''; 28 let lecture = document.getElementById('lecture_time'); 29 data.lecture_time = lecture ? lecture.value : ''; 30 let fee = document.getElementById('fee_comment'); 31 data.fee_comment = fee ? fee.value : ''; 32 let guest = document.getElementById('guest_comment'); 33 data.guest_comment = guest ? guest.value : ''; 34 return data; 35} 36 37// 指定したページだけ保存 38function savePage(pageNum) { 39 if (pageNum === 1) { 40 let data = getPage1Data(); 41 localStorage.setItem('page1', JSON.stringify(data)); 42 console.log('page1保存', data); 43 } else if (pageNum === 2) { 44 let data = getPage2Data(); 45 localStorage.setItem('page2', JSON.stringify(data)); 46 console.log('page2保存', data); 47 } 48} 49 50// 1ページ目の「次へ」ボタン用 51function goNextPage() { 52 savePage(1); 53 location.href = 'page2.html'; 54} 55 56// 2ページ目の「送信」ボタン用 57function sendData() { 58 savePage(2); // 念のため2ページ目も保存 59 60 let page1 = JSON.parse(localStorage.getItem('page1') || '{}'); 61 let page2 = JSON.parse(localStorage.getItem('page2') || '{}'); 62 let allData = Object.assign({}, page1, page2); 63 64 console.log('送信データ', allData); 65 66 // ★★★ ここに自分のGASのURLを入れてね ★★★ 67 let GAS_URL = 'https://script.google.com/macros/s/あなたのID/exec'; 68 69 fetch(GAS_URL, { 70 method: 'POST', 71 mode: 'no-cors', 72 headers: { 'Content-Type': 'application/json' }, 73 body: JSON.stringify(allData) 74 }) 75 .then(() => { 76 alert('送信完了。ありがとうございました。'); 77 localStorage.removeItem('page1'); 78 localStorage.removeItem('page2'); 79 }) 80 .catch(err => { 81 console.error('送信エラー', err); 82 alert('送信失敗。ネットワークかGASのURLを確認して。'); 83 }); 84}

HTML側の修正

page2.html の送信ボタン、これ↓を

html

1<button type="button" onclick="saveData(); sendData();">送信する</button>

こう変えてくれ。

html

1<button type="button" onclick="sendData()">送信する</button>

preview.html はそのままで大丈夫。goNextPage() が呼ばれてるから。

GAS側の注意点

GASのdoPostでちゃんとJSONを受け取れてるかも確認して。
最低限これ↓があれば動く。

javascript

1function doPost(e) { 2 let data = JSON.parse(e.postData.contents); 3 // dataに全ページの項目が入ってる 4 // スプレッドシートに書き込む処理をここに書く 5 return ContentService.createTextOutput("OK"); 6}

デプロイしたら最新のURLをGAS_URLにセットし直すのを忘れずに。

動作確認

  1. 上記storage.jsに置き換え
  2. preview.htmlで適当に入力 → 次へ
  3. page2.htmlで入力 → 送信
  4. F12のコンソールでエラーが出てないか、page1保存とか送信データのログが出てるか確認
  5. スプレッドシートに両方のデータが1行で入ってれば完了

もしそれでも1ページ目のデータが消えるなら、コンソールでlocalStorage.getItem('page1')を直接見てみて。何も入ってなければ、1ページ目のHTMLのidやnameがコードと合ってない可能性がある。

とりあえずこれで直るはず。やってみて。

投稿2026/06/06 01:34

blixor

総合スコア50

naaS

2026/06/06 05:29 編集

ありがとうございます。htmlとjsのコードを書き直しました。グーグルの検証画面のコンソール上はデーターはすべて送信されていました。GASの方は、スプレッドシートが日付けしか書き込まれていませんでした。 htmlとjsのファイルは正常で、デプロイの方のコードは function doPost(e) { let data = JSON.parse(e.postData.contents); // dataに全ページの項目が入ってる // スプレッドシートに書き込む処理をここに書く sheet.appendRow([ new Date(), data.age, data.gender, data.city, data.job, data.understand, data.comment, data.future_job, data.pref, data.lecture_time, data.fee_comment, data.guest_comment ]); return ContentService.createTextOutput("OK"); }にしました。 自分が書き間違えたか、スプレッドシートそのものが別なものになっているのだと思います。 さらに調べます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.25%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問