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 練習問題まとめ
今回の練習問題で、
複雑なフォーム処理の基礎がしっかり身につきます。
複数項目のチェック
複数エラーのまとめ表示
エラー項目のハイライト
バリデーション関数の分離
成功時の処理の分離
これらは実務のフォーム処理そのものです。
ここまで理解できていれば、
あなたはもう「ただ動くフォーム」ではなく
「設計されたフォーム」を作れる段階にいます。
