JavaScript | 1 日 90 分 × 7 日アプリ学習:フォーム送信シミュレーター(初級編)

JavaScript
スポンサーリンク

7日目のゴールと今日やること

7日目のテーマは
「フォーム送信シミュレーターを“作品として完成させる”」
ことです。

ここまでの 1〜6 日間であなたは、

  • submit の制御
  • preventDefault の本質
  • 入力 → 確認 → 擬似送信完了 の流れ
  • バリデーション
  • 項目ごとのエラー表示
  • formData の一元管理
  • 確認画面の自動生成
  • 完了画面の演出

これらをすべて扱えるようになりました。

7日目は、
「全体を理解し、説明できるようにし、コードを整えて作品化する」
という最終仕上げを行います。


フォーム送信アプリの「全体構造」を理解する

アプリは 3 つのレイヤーでできている

フォーム送信シミュレーターは、
次の 3 つのレイヤーが協力して動いています。

HTML:構造

入力欄、確認画面、完了画面などの“枠”を作る。

CSS:見た目

active や display の切り替えで画面を見せたり隠したりする。

JavaScript:動き

submit を止め、入力を集め、画面を切り替え、送信完了を演出する。

この 3 つが役割分担して動くことで、
「アプリのように動くフォーム」が成立します。


submit 制御と preventDefault の本質を深掘りする

フォームアプリの心臓は「送信を止めること」

フォームは本来、
送信ボタンを押すとページがリロードされます。

しかしアプリでは、

  • 入力チェック
  • 確認画面
  • 擬似送信
  • 完了画面

これらを JavaScript で制御したいので、
ブラウザの自動送信を止める必要があります。

それが preventDefault です。

form.addEventListener("submit", (e) => {
  e.preventDefault();
});
JavaScript

深掘り:preventDefault は「アプリの自由度」を生む

これを使うことで、

  • ページ遷移なしで画面を切り替えられる
  • 入力チェックを好きな順番でできる
  • 送信完了を自由に演出できる

つまり、
フォームを“アプリ化”するための必須スイッチ
と言えます。


入力 → 確認画面 → 擬似送信完了 の流れを整理する

入力画面でやること

  • 入力値を formData に集める
  • validateForm でチェックする
  • エラーがあれば showErrors で表示
  • 問題なければ確認画面へ進む

確認画面でやること

  • formData を元に画面を自動生成
  • 戻るボタンで入力画面へ戻る
  • 送信ボタンで擬似送信へ進む

擬似送信完了でやること

  • loadingScreen を表示
  • setTimeout で送信中を演出
  • 完了画面でメッセージを表示

この流れを理解できれば、
あなたはもう「フォームアプリの仕組みを説明できる人」です。


コードにコメントをつけて“他人に渡せるコード”にする

コメントは「未来の自分へのメモ」

コードは書いた瞬間は理解できますが、
1週間後には忘れます。

そこで、
「なぜこの処理が必要なのか」
をコメントとして残します。

例:

// フォーム送信を止めて、アプリ側で処理を行う
e.preventDefault();

// 入力値をまとめて取得する
formData = collectFormData();

// バリデーション(入力チェック)
const errors = validateForm(formData);
JavaScript

深掘り:コメントは「コードの意図」を伝える

  • 何をしているか
  • なぜ必要なのか
  • どんな前提で動いているのか

これらを言葉にできると、
コードの理解が一気に深まります。


7日目の完成コード(コメント付き)

JavaScript(重要部分のみ)

// 入力データをまとめて保持するオブジェクト
let formData = {};

// 入力値をまとめて取得する関数
function collectFormData() {
  const data = {};
  const inputs = form.querySelectorAll("input, textarea, select");

  inputs.forEach(input => {
    const key = input.name;
    if (!key) return;

    // チェックボックスは配列で管理
    if (input.type === "checkbox") {
      if (!data[key]) data[key] = [];
      if (input.checked) data[key].push(input.value);

    // ラジオボタンは選ばれたものだけ
    } else if (input.type === "radio") {
      if (input.checked) data[key] = input.value;

    // それ以外はそのまま値を入れる
    } else {
      data[key] = input.value.trim();
    }
  });

  return data;
}

// 入力チェックを行う関数
function validateForm(data) {
  const errors = {};

  if (!data.name) errors.name = "名前を入力してください。";
  if (!data.email) errors.email = "メールアドレスを入力してください。";

  return errors;
}

// エラーを画面に表示する関数
function showErrors(errors) {
  const errorElements = document.querySelectorAll(".error");
  errorElements.forEach(el => (el.textContent = ""));

  for (const key in errors) {
    const el = document.getElementById(`error-${key}`);
    if (el) el.textContent = errors[key];
  }
}

// 確認画面を自動生成する関数
function renderConfirmScreen(data) {
  let html = "";
  for (const key in data) {
    const value = Array.isArray(data[key])
      ? data[key].join("、")
      : data[key];
    html += `<p>${key}${value}</p>`;
  }
  confirmList.innerHTML = html;
}

// 完了画面を表示する関数
function showCompleteScreen(data) {
  const msg = document.getElementById("completeMessage");
  msg.textContent = `${data.name} さん、送信が完了しました。ありがとうございました。`;
  completeScreen.style.display = "block";
}

// submit イベントのメイン処理
form.addEventListener("submit", (e) => {
  e.preventDefault(); // 本当の送信を止める

  formData = collectFormData(); // 入力値を集める
  const errors = validateForm(formData); // バリデーション

  if (Object.keys(errors).length > 0) {
    showErrors(errors); // エラー表示
    return;
  }

  showErrors({}); // エラーを消す
  renderConfirmScreen(formData); // 確認画面生成

  form.style.display = "none";
  confirmScreen.style.display = "block";
});

// 戻るボタン
backButton.addEventListener("click", () => {
  confirmScreen.style.display = "none";
  form.style.display = "block";
});

// 擬似送信 → 完了画面
sendButton.addEventListener("click", () => {
  confirmScreen.style.display = "none";
  loadingScreen.style.display = "block";

  setTimeout(() => {
    loadingScreen.style.display = "none";
    showCompleteScreen(formData);
  }, 1500);
});
JavaScript

今日いちばん深く理解してほしいこと

フォームアプリは「状態管理 × 画面切り替え」でできている

  • 入力画面
  • 確認画面
  • 送信中画面
  • 完了画面

これらを JavaScript が状態として管理し、
CSS が見た目を切り替えています。

この構造を理解できれば、
あなたはもう「フォームアプリを作れる人」です。

コードを“説明できる”ことが完成の証

  • なぜ preventDefault が必要なのか
  • なぜ formData を使うのか
  • なぜ確認画面を自動生成するのか

これらを自分の言葉で説明できるようになると、
理解が本物になります。


7日間の学習を終えて

あなたはこの 1 週間で、

  • submit 制御
  • preventDefault
  • バリデーション
  • 画面切り替え
  • データ管理
  • 自動生成
  • 完了演出

これらをすべて習得しました。

これはもう立派な「ミニ Web アプリ」です。

最後にひとつだけ。

このフォーム送信アプリ、
あなたならどんなデザインやメッセージを加えてみたいでしょう。

その「自分の色を足したくなる感覚」が、
もう立派な“アプリ開発者の感性”です。

タイトルとURLをコピーしました