JavaScript | ゼロからはじめるプログラミング、30日で基礎を学ぶJavaScript:Webページを操作できるようになる - Day19.5:条件 + DOM応用 練習問題

JavaScript JavaScript
スポンサーリンク

Day19.5:条件 + DOM 応用の練習問題

複雑なフォーム処理では、
「複数の項目を複数の条件でチェックし、エラーをまとめて管理し、見た目にも反映する」
という高度な DOM 操作が必要になります。

ここでは、Day19.5 の内容を確実に理解できるように、
実務レベルに近い練習問題と丁寧な解答・解説をまとめます。


複数項目の入力チェック

問題1:ユーザー名・メール・パスワードをチェックし、エラーをまとめて表示してください

次の HTML を前提とします。

<input id="userInput" type="text" placeholder="ユーザー名">
<input id="emailInput" type="text" placeholder="メールアドレス">
<input id="passwordInput" type="password" placeholder="パスワード">
<button id="submitButton">登録</button>
<p id="message"></p>

チェック内容は次の通りです。
ユーザー名:空でない
メール:空でない、@ を含む
パスワード:8文字以上

解答と解説

const userInput = document.getElementById("userInput");
const emailInput = document.getElementById("emailInput");
const passwordInput = document.getElementById("passwordInput");
const submitButton = document.getElementById("submitButton");
const message = document.getElementById("message");

submitButton.addEventListener("click", () => {
  const user = userInput.value.trim();
  const email = emailInput.value.trim();
  const password = passwordInput.value;

  const errors = [];

  if (user === "") {
    errors.push("ユーザー名を入力してください。");
  }

  if (email === "") {
    errors.push("メールアドレスを入力してください。");
  } else if (!email.includes("@")) {
    errors.push("メールアドレスの形式が正しくありません。");
  }

  if (password.length < 8) {
    errors.push("パスワードは8文字以上で入力してください。");
  }

  if (errors.length > 0) {
    message.textContent = errors.join(" ");
    return;
  }

  message.textContent = "登録が完了しました。";
});
JavaScript

複数のエラーを配列にためて、最後にまとめて表示するのがポイントです。
これにより「一度の送信で全部のエラーを伝える」フォームになります。


エラー項目を赤くする

問題2:エラーのある input に error クラスを付けて赤くしてください

次の CSS を前提とします。

<style>
  .error {
    border: 2px solid red;
    background-color: #ffecec;
  }
</style>

解答と解説

submitButton.addEventListener("click", () => {
  const user = userInput.value.trim();
  const email = emailInput.value.trim();
  const password = passwordInput.value;

  userInput.classList.remove("error");
  emailInput.classList.remove("error");
  passwordInput.classList.remove("error");

  const errors = [];

  if (user === "") {
    errors.push("ユーザー名を入力してください。");
    userInput.classList.add("error");
  }

  if (email === "") {
    errors.push("メールアドレスを入力してください。");
    emailInput.classList.add("error");
  } else if (!email.includes("@")) {
    errors.push("メールアドレスの形式が正しくありません。");
    emailInput.classList.add("error");
  }

  if (password.length < 8) {
    errors.push("パスワードは8文字以上で入力してください。");
    passwordInput.classList.add("error");
  }

  if (errors.length > 0) {
    message.textContent = errors.join(" ");
    return;
  }

  message.textContent = "登録が完了しました。";
});
JavaScript

最初に全ての error クラスを remove し、
今回エラーになった項目だけ add するのが正しい流れです。


バリデーションを関数に分ける

問題3:入力チェックを validate 関数に切り出してください

次の HTML は問題1と同じです。

解答と解説

function validate(values) {
  const errors = [];

  if (values.user === "") {
    errors.push({ field: "user", message: "ユーザー名を入力してください。" });
  }

  if (values.email === "") {
    errors.push({ field: "email", message: "メールアドレスを入力してください。" });
  } else if (!values.email.includes("@")) {
    errors.push({ field: "email", message: "メールアドレスの形式が正しくありません。" });
  }

  if (values.password.length < 8) {
    errors.push({ field: "password", message: "パスワードは8文字以上で入力してください。" });
  }

  return errors;
}

submitButton.addEventListener("click", () => {
  const values = {
    user: userInput.value.trim(),
    email: emailInput.value.trim(),
    password: passwordInput.value
  };

  userInput.classList.remove("error");
  emailInput.classList.remove("error");
  passwordInput.classList.remove("error");

  const errors = validate(values);

  if (errors.length > 0) {
    const messages = [];

    errors.forEach((error) => {
      messages.push(error.message);

      if (error.field === "user") {
        userInput.classList.add("error");
      } else if (error.field === "email") {
        emailInput.classList.add("error");
      } else if (error.field === "password") {
        passwordInput.classList.add("error");
      }
    });

    message.textContent = messages.join(" ");
    return;
  }

  message.textContent = "登録が完了しました。";
});
JavaScript

バリデーションを関数に切り出すことで、
イベントハンドラが「値を集める」「結果を表示する」だけの役割になり、
コードが読みやすく、変更しやすくなります。


成功時の処理を関数に分ける

問題4:成功時にフォームをリセットする handleSuccess 関数を作ってください

次の HTML は問題1と同じです。

解答と解説

function handleSuccess() {
  message.textContent = "登録が完了しました。";

  userInput.value = "";
  emailInput.value = "";
  passwordInput.value = "";
}

submitButton.addEventListener("click", () => {
  const values = {
    user: userInput.value.trim(),
    email: emailInput.value.trim(),
    password: passwordInput.value
  };

  const errors = validate(values);

  if (errors.length > 0) {
    showErrors(errors);
    return;
  }

  handleSuccess();
});
JavaScript

成功時の処理を関数にまとめることで、
「成功したときに何が起きるか」が明確になります。


総合問題:複雑なフォーム処理を完成させる

問題5:ユーザー名・メール・パスワード・確認用パスワード・利用規約チェックをすべて扱うフォームを完成させてください

次の HTML を前提とします。

<input id="userInput" type="text" placeholder="ユーザー名">
<input id="emailInput" type="text" placeholder="メールアドレス">
<input id="passwordInput" type="password" placeholder="パスワード">
<input id="passwordConfirmInput" type="password" placeholder="パスワード(確認)">
<label><input id="termsCheckbox" type="checkbox"> 利用規約に同意します</label>
<button id="submitButton">登録</button>
<p id="message"></p>

解答と解説(完成版)

function validate(values) {
  const errors = [];

  if (values.user === "") {
    errors.push({ field: "user", message: "ユーザー名を入力してください。" });
  }

  if (values.email === "") {
    errors.push({ field: "email", message: "メールアドレスを入力してください。" });
  } else if (!values.email.includes("@")) {
    errors.push({ field: "email", message: "メールアドレスの形式が正しくありません。" });
  }

  if (values.password.length < 8) {
    errors.push({ field: "password", message: "パスワードは8文字以上で入力してください。" });
  }

  if (values.passwordConfirm === "") {
    errors.push({ field: "passwordConfirm", message: "確認用パスワードを入力してください。" });
  } else if (values.password !== values.passwordConfirm) {
    errors.push({ field: "passwordConfirm", message: "パスワードが一致しません。" });
  }

  if (!values.termsChecked) {
    errors.push({ field: "terms", message: "利用規約に同意してください。" });
  }

  return errors;
}

function showErrors(errors) {
  const messages = [];

  userInput.classList.remove("error");
  emailInput.classList.remove("error");
  passwordInput.classList.remove("error");
  passwordConfirmInput.classList.remove("error");

  errors.forEach((error) => {
    messages.push(error.message);

    if (error.field === "user") userInput.classList.add("error");
    if (error.field === "email") emailInput.classList.add("error");
    if (error.field === "password") passwordInput.classList.add("error");
    if (error.field === "passwordConfirm") passwordConfirmInput.classList.add("error");
  });

  message.textContent = messages.join(" ");
}

function handleSuccess(values) {
  message.textContent = `登録が完了しました。ようこそ、${values.user} さん。`;

  userInput.value = "";
  emailInput.value = "";
  passwordInput.value = "";
  passwordConfirmInput.value = "";
  termsCheckbox.checked = false;
}

submitButton.addEventListener("click", () => {
  const values = {
    user: userInput.value.trim(),
    email: emailInput.value.trim(),
    password: passwordInput.value,
    passwordConfirm: passwordConfirmInput.value,
    termsChecked: termsCheckbox.checked
  };

  const errors = validate(values);

  if (errors.length > 0) {
    showErrors(errors);
    return;
  }

  handleSuccess(values);
});
JavaScript

複雑なフォーム処理のポイントがすべて入っています。

エラーを配列で管理
エラー項目にクラスを付けて視覚的に伝える
バリデーションを関数に分離
成功時の処理も関数に分離
textContent を使って安全に表示


Day19.5 練習問題まとめ

今回の練習問題で、
複雑なフォーム処理の基礎がしっかり身につきます。

複数項目のチェック
複数エラーのまとめ表示
エラー項目のハイライト
バリデーション関数の分離
成功時の処理の分離

これらは実務のフォーム処理そのものです。
ここまで理解できていれば、
あなたはもう「ただ動くフォーム」ではなく
「設計されたフォーム」を作れる段階にいます。

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