つくる フォームの入力チェック
このレッスンで分かること
- 未入力の入力欄の
valueは空文字列なので、そのまま falsy として判定できます- 検証に落ちたら早期 return で抜け、通ったときはエラー表示を消します
空のまま送られると、誰から来たのか分からない
前回で送信は止められるようになりました。ところが、名前もメールアドレスも空のまま送信ボタンを押すと、いまのコードは何ごともなく「送信を受け付けました」と答えます。受け取る側から見れば、宛先の分からない問い合わせが届くだけです。届いてから困るくらいなら、押した瞬間に教えてあげたほうがずっと親切です。
今回作るのは、その入力チェックです。決まりは次のとおりです。
- フォームの中、送信ボタンのすぐ上に
id="form-error"class="form-error"の空のpを足す - 前回書いた
submitの処理を書き換える。event.preventDefault()は先頭のまま残す #nameと#emailの値を読み、どちらかが空ならエラー文を出し、フォームにhas-errorを付けて処理を打ち切る- 両方そろっているときは、エラー文と
has-errorを消してから受け付けたと表示する
新しく addEventListener を足すのではなく、前回の処理の中身を差し替えてください。同じフォームに 2 つ登録すると、両方が動いてしまいます。
空文字は falsy なので、そのまま判定できる
空かどうかの書き方はいくつかあります。どれも動きますが、読みやすさに差があります。
| 書き方 | 動くか | 評価 |
|---|---|---|
title === "" | 動く | 空白だけの入力を通してしまう |
title.length === 0 | 動く | 意味は同じだが 1 段まわりくどい |
!title | 動く | 短く、第2章の falsy の考え方に沿っている |
第2章で学んだ falsy が、ここでようやく本領を発揮します。空の入力欄の value は "" であり、"" は falsy です。長さを数えたり空文字と比べたりする必要はありません。
ただし !title だけでは、半角スペースを 1 つ打たれたときに通ってしまいます。空白も文字なので " " は truthy です。そこで、読み取った直後に trim() を通します。
JavaScript
const title = document.querySelector("#book-title").value.trim();
console.log(!title); // 空欄でも空白だけでも truetrim() は前後の空白を取り除いた新しい文字列を返すメソッドです。元の文字列も画面の入力欄も変えません。入力チェックでは value を読んだらすぐ trim()、と手が動くようにしておくと安全です。
落ちたらそこで抜け、直したら消す
第6章で学んだ早期 return がそのまま使えます。エラーのときの処理を書いたら、最後に return を置いて先へ進ませません。
JavaScript
if (!title) {
errorText.textContent = "タイトルを入力してください";
bookForm.classList.add("has-error");
return;
}return を書き忘れると、エラーを出したうえで受け付けたとも表示する、ちぐはぐな画面になります。
見落としがちなのは、その逆側です。エラーを出す処理だけを書いて、正常だったときに消す処理を書き忘れると、一度出たエラー文が画面に残り続けます。直したのに何が悪いのか分からないまま止まってしまい、いちばん嫌われる作りです。状態は 2 通りの見せ方で表すので、消すほうも 2 つあります。
- 文字 … エラー文を入れる。正常なら空文字に戻す
- class … フォームに
has-errorを付ける。正常なら外す
JavaScript
errorText.textContent = "";
bookForm.classList.remove("has-error");has-error が付いている間だけ入力欄の枠が赤くなる CSS は用意してあります。前回のダークモードと同じで、見た目は CSS が持ち、JavaScript は状態の名前を付け外しするだけです。
エラー文には「何がいけないのか」と「どうすれば直るのか」を入れます。エラー の一言では次の一手が分かりません。置く場所も、押した直後に目が向くところにします。スクロールしないと見えないエラーは、出していないのとほとんど変わりません。
なお、ブラウザ側の検証は見ている人に早く気付いてもらうためのもので、安全のためのものではありません。JavaScript は見ている人がいくらでも書き換えられるので、実際にデータを受け取るサーバー側でも同じ検証をやり直します。
よくある間違い
- 条件を
&&でつなぐ —if (!name && !email)は「両方とも空のとき」です。片方だけ空のときは素通りします。どちらか一方でも空なら止めたいので||を使います - エラーを消す処理がない — 正常だったときに文字を空へ戻し、
has-errorを外す行を必ず書きます
課題
- HTML の
.contact-formの中、送信ボタンのすぐ上にid="form-error"class="form-error"の空のpを足す - 前回書いた
submitの処理を書き換える。event.preventDefault()は先頭のまま残す #nameと#emailのvalueをtrim()して読み取り、どちらかが falsy ならエラー文を#form-errorに出し、.contact-formにhas-errorを付けてreturnする- 両方そろっているときは
#form-errorを空にし、has-errorを外して#form-messageに「送信を受け付けました」と出す