JavaScript | 1 日 90 分 × 7 日アプリ学習:入力チェックアプリ(初級編)

JavaScript
スポンサーリンク

5日目のゴールと今日のテーマ

5日目のテーマは「入力チェックを“フォームっぽいレベル”まで一歩引き上げること」です。
機能はまだ同じです。

空チェック(未入力警告)
文字数制限
条件分岐とエラー表示

ただし今日は、

「どの項目に、どんなエラーが出ているか」をまとめて扱うこと
フォーム全体として「送信していいか」をきれいに判断すること
コードからエラーの状態が一目で分かるように整理すること

ここまで意識して、入力チェックアプリを一段“設計寄り”に育てていきます。


4日目までのフォーム構成を整理する

名前とコメント、2つの入力欄

前回までで、だいたいこんな形になっていました。

<input id="name-input" type="text" placeholder="名前を入力" />
<div id="name-error"></div>

<input id="comment-input" type="text" placeholder="コメントを入力" />
<div id="comment-error"></div>

<button id="submit-button">送信</button>

JavaScript のイメージはこうです。

const nameInputEl = document.getElementById("name-input");
const nameErrorEl = document.getElementById("name-error");
const commentInputEl = document.getElementById("comment-input");
const commentErrorEl = document.getElementById("comment-error");
const submitButton = document.getElementById("submit-button");

const minNameLength = 2;
const maxNameLength = 20;
const minCommentLength = 5;
const maxCommentLength = 100;

submitButton.addEventListener("click", handleSubmit);

function showError(el, message) {
  el.textContent = message;
}

function validate(text, minLength, maxLength) {
  const trimmed = text.trim();

  if (trimmed === "") {
    return "未入力です。";
  }

  if (trimmed.length < minLength) {
    return minLength + "文字以上で入力してください。";
  }

  if (trimmed.length > maxLength) {
    return maxLength + "文字以内で入力してください。";
  }

  return "";
}

function handleSubmit() {
  const nameValue = nameInputEl.value;
  const commentValue = commentInputEl.value;

  const nameError = validate(nameValue, minNameLength, maxNameLength);
  const commentError = validate(commentValue, minCommentLength, maxCommentLength);

  showError(nameErrorEl, nameError);
  showError(commentErrorEl, commentError);

  if (nameError !== "" || commentError !== "") {
    return;
  }

  alert("送信完了しました!");
}
JavaScript

4日目のポイントは、「項目ごとにエラーを出し分ける」ことでした。
5日目はここから、「エラーの状態をもっと整理して扱う」をやります。


今日のテーマ①:エラー状態を“まとめて”扱う

エラーを「ただの文字列」から「状態オブジェクト」にしてみる

今は nameError と commentError を別々の変数で持っています。
これを「フォーム全体のエラー状態」としてまとめて管理してみます。

例えば、こんなオブジェクトを考えます。

const errors = {
  name: "",
  comment: "",
};
JavaScript

ここに、「今の名前のエラー」「今のコメントのエラー」を入れていきます。

handleSubmit をこう書き換えます。

function handleSubmit() {
  const nameValue = nameInputEl.value;
  const commentValue = commentInputEl.value;

  const errors = {
    name: validate(nameValue, minNameLength, maxNameLength),
    comment: validate(commentValue, minCommentLength, maxCommentLength),
  };

  showError(nameErrorEl, errors.name);
  showError(commentErrorEl, errors.comment);

  if (errors.name !== "" || errors.comment !== "") {
    return;
  }

  alert("送信完了しました!");
}
JavaScript

ここでの重要ポイントは、「errors という1つのオブジェクト」に状態をまとめたことです。
これによって、フォーム全体を「ちゃんと通っているのか」を俯瞰しやすくなります。


今日のテーマ②:フォーム全体として「OKかどうか」を関数にする

hasErrors 関数を作る

「エラーが1つでもあるか?」をチェックする処理を関数にします。

function hasErrors(errors) {
  return errors.name !== "" || errors.comment !== "";
}
JavaScript

handleSubmit はこう書き換えられます。

function handleSubmit() {
  const nameValue = nameInputEl.value;
  const commentValue = commentInputEl.value;

  const errors = {
    name: validate(nameValue, minNameLength, maxNameLength),
    comment: validate(commentValue, minCommentLength, maxCommentLength),
  };

  showError(nameErrorEl, errors.name);
  showError(commentErrorEl, errors.comment);

  if (hasErrors(errors)) {
    return;
  }

  alert("送信完了しました!");
}
JavaScript

ここが今日の深掘りポイントのひとつです。

handleSubmit が「やっていること」が日本語で読めるようになっている。
フォーム全体がOKかどうかの判定ロジックを hasErrors に押し込めている。

エラーが増えたとき(入力項目が3つ、4つになったとき)でも、
hasErrors の中身だけ変えればよくなります。


今日のテーマ③:全体エラーメッセージも出してみる

上に「フォームにエラーがあります」と出す

項目ごとのエラーに加えて、フォームの一番上に「エラーがあります」とまとめて出すことも多いです。

HTML に全体メッセージの場所を追加します。

<div id="form-error"></div>

JavaScriptで取得します。

const formErrorEl = document.getElementById("form-error");
JavaScript

全体エラー表示用の小さい関数を用意します。

function showFormError(message) {
  formErrorEl.textContent = message;
}
JavaScript

handleSubmit に組み込みます。

function handleSubmit() {
  const nameValue = nameInputEl.value;
  const commentValue = commentInputEl.value;

  const errors = {
    name: validate(nameValue, minNameLength, maxNameLength),
    comment: validate(commentValue, minCommentLength, maxCommentLength),
  };

  showError(nameErrorEl, errors.name);
  showError(commentErrorEl, errors.comment);

  if (hasErrors(errors)) {
    showFormError("入力内容に誤りがあります。各項目のエラーを確認してください。");
    return;
  }

  showFormError("");
  alert("送信完了しました!");
}
JavaScript

ここでの大事なポイントは、「エラーがある/ない」を hasErrors だけ見れば分かる状態にしておくことです。
フォーム全体のメッセージは、「hasErrors の結果」にだけ依存しています。


入力中の動きも「全体の状態」として扱ってみる

該当項目のエラーを消す+必要なら全体メッセージも消す

4日目では、input イベントで「その項目のエラーだけ消す」ということをしました。
5日目では、フォーム全体のエラーも一緒に考えます。

例えばこうです。

nameInputEl.addEventListener("input", () => {
  showError(nameErrorEl, "");
  showFormError("");
});

commentInputEl.addEventListener("input", () => {
  showError(commentErrorEl, "");
  showFormError("");
});
JavaScript

これで、

送信 → エラーが出る(項目ごと+全体)
ユーザーがどこかを直し始める → とりあえずその項目のエラーと全体エラーを消す

という流れになります。

「今なおしてる最中だから、一旦“エラーがある状態”を解除してあげる」
このやさしさは、実はロジックの設計にも関係しています。


少しだけ現実寄りの例:名前は短め、コメントは長め

項目ごとにルールを変える意味

名前は 2〜20 文字、コメントは 10〜200 文字、みたいな形にしてみましょう。

const minNameLength = 2;
const maxNameLength = 20;
const minCommentLength = 10;
const maxCommentLength = 200;
JavaScript

validate を呼ぶときだけ、こう変えます。

const errors = {
  name: validate(nameValue, minNameLength, maxNameLength),
  comment: validate(commentValue, minCommentLength, maxCommentLength),
};
JavaScript

ここでの重要ポイントは、

「validate は1つしかないのに、項目ごとに違うルールを適用できている」

ということです。

つまり、

チェックロジック(書き方)は共通。
具体的な制限値だけを項目ごとに変えている。

これは、「ルールをデータとして渡す」設計の小さな踏み込みです。


5日目までの全体像をイメージとしてまとめる

コードの構造を日本語で説明してみる

大まかには、こういう構造になっています。

入力欄(名前・コメント)と、項目ごとのエラー表示場所、全体エラー表示場所を持つ。
validate は「テキストと min/max を受け取って、ダメならエラーメッセージを返す」純粋なチェック関数。
handleSubmit は「値を集める→項目ごとに validate→ errors オブジェクトにまとめる→項目エラー表示→全体エラー判定→OKなら送信」という流れを管理。
hasErrors は「errors に1つでもエラーメッセージが入っていたら true」を返す。
showError / showFormError は「画面への表示」を担当するだけの小さな関数。

これって、かなり“フォームアプリ”らしい設計になっています。


5日目のまとめと、6日目へのつなぎ

今日やったことを整理します。

エラーを name / comment というオブジェクト(errors)としてまとめて管理した。
hasErrors 関数で「フォーム全体としてOKかどうか」を判定するロジックを一カ所に集約した。
項目ごとのエラーに加えて、「フォーム全体のエラー」も表示する仕組みを入れた。
入力中に項目エラー+全体エラーを消す流れを作り、「直している途中なんだな」ということをロジックにもUIにも反映させた。
validate を1つに保ったまま、項目ごとに min / max を変える「ルールのデータ化」の感覚を体験した。

6日目以降は、ここに例えば、

「特定の文字種だけOK」(数字だけ・ひらがなだけ等)
メールアドレスっぽい形式のチェック
複数のエラーをどう見せるか(1個だけか、全部出すか)

といった“種類の違うチェック”を足していく方向に進めます。

最後にひとつ、あえて聞きたい。

今日の中で、「あ、これ設計としてちょっと気持ちいいな」と感じたところはどこでしたか?
errors オブジェクトでエラーが整理された瞬間か、hasErrors でフォーム全体の判定を一言で書けたところか。

その“気持ちよさ”が、あなたのコード設計のセンスを育てていく核になります。
その感覚を大事に持ったまま、6日目の“チェックの質”の強化に進んでいきましょう。

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