はじめに
GAS Webアプリでスマートフォン向けの入力フォームを作る場合、利用者が誤って再読み込み、戻る、タブを閉じる操作をすると、入力途中の内容が失われることがあります。
写真、選択肢、テキストを複数登録する業務フォームでは、入力途中の消失はかなりストレスになります。
ブラウザ標準のbeforeunloadイベントを使うと、入力途中の状態でページを離れようとしたときに確認ダイアログを出せます。
使う場面
- スマホで長めの入力フォームを使う
- 写真、選択肢、テキストなどを複数登録する
- 送信前に誤操作で入力内容が消えると困る
- GAS Webアプリで業務用フォームを作る
写真付き現場報告書作成Webアプリのように、現場でスマートフォン入力するアプリでは入れておきたい防御策です。
基本実装
入力済みかどうかをisDirty、送信中かどうかをisSubmittingで管理します。
<script>
const state = {
isDirty: false,
isSubmitting: false,
};
window.addEventListener('beforeunload', confirmBeforeUnload);
document.addEventListener('input', markDirty);
document.addEventListener('change', markDirty);
function confirmBeforeUnload(event) {
if (!state.isDirty || state.isSubmitting) return;
event.preventDefault();
event.returnValue = '';
}
function markDirty() {
state.isDirty = true;
}
</script>
event.returnValue = ''を設定すると、ブラウザ標準の確認ダイアログが出ます。確認文言はブラウザ側で固定されるため、任意の日本語メッセージにはできません。
送信処理との組み合わせ
正常な送信では確認ダイアログを出したくないため、送信中はisSubmitting = trueにします。
<script>
function submitForm(payload) {
state.isSubmitting = true;
google.script.run
.withSuccessHandler(function(result) {
state.isDirty = false;
state.isSubmitting = false;
renderSuccess(result);
})
.withFailureHandler(function(err) {
state.isSubmitting = false;
renderError(err);
})
.serverFunction(payload);
}
</script>
送信成功時はisDirty = falseに戻します。送信失敗時は、入力内容を再送できるようにisDirtyを残しておくのが自然です。
localStorageとの使い分け
beforeunloadは、離脱前に注意を出すための仕組みです。入力内容そのものを復元する機能ではありません。
完全に入力内容を守りたい場合は、localStorageなどの一時保存と組み合わせます。
ただし、写真ファイルはブラウザのセキュリティ都合で復元しにくいことがあります。写真を再選択してもらう注意書きや、送信前の確認画面を用意する設計も重要です。
注意点
- iOSやAndroidのブラウザでは、状況によって確認ダイアログが出ないことがある
- カメラアプリやファイル選択UIへの遷移は完全には制御できない
- 確認文言はブラウザ側で固定される
- 送信中に確認が出ると利用者が混乱するため、
isSubmittingで抑制する - 完全な保護が必要な場合は、下書き保存と組み合わせる
関連記事
- GASで作る工事現場向け写真付き報告書Webアプリ
- GASのgoogle.script.runでエラーハンドリングを実装する方法
- GAS Webアプリでスマホ写真を送信前に圧縮する方法
- GAS Webアプリのスマホ対応フォント設定
まとめ
GAS Webアプリの入力フォームでは、beforeunloadで入力途中の離脱確認を入れておくと、誤操作による入力消失を減らせます。
写真付き報告書のように入力に手間がかかるフォームでは、送信状態フラグ、エラーハンドリング、必要に応じた一時保存を組み合わせると、現場で使いやすい画面になります。
