メールフォームのバリデーションをする時、値の判定をリアルタイムで行ってくれるjsのバリデーションを制作してみました。
リアルタイムバリデーションの要件定義
リアルタイムというのはinputの項目からフォーカスを外した時に値をチェックしてくれるということです。
各フォーム項目のバリデーション実行タイミングはinput要素からフォーカスが外れた時、またはセレクトやラジオボタンの値が変更された時となります。
そして、フォームデータが送信されるのも全ての内容にエラーが存在しなかった時にのみ送信される仕組みとなっています。
HTMLで基本的なフォームを制作
フォームの要素はよく使う基本的なものを利用しています。要素の下にエラーメッセージを予め準備しCSSで非表示において、バリデーションでチェックでエラー判定の時、エラーメッセージが表示されます。
<form name="mailform" action="confirm.php" method="POST"> <table> <tbody> <tr> <th>名前(必須)</th> <td class="js-text-require"> <input type="text" name="name" value="" maxlength="100" placeholder="名前"> <div class="error">名前を正しく入力してください。</div> </td> </tr> <tr> <th>メールアドレス(必須)</th> <td class="js-email-require"> <input type="email" name="mail" value="" maxlength="100" placeholder="メールアドレス"> <div class="error">メールアドレスを正しく入力してください。</div> </td> </tr> <tr> <th>電話番号(必須)</th> <td class="js-phone-require"> <input type="tel" name="phone" value="" maxlength="100" placeholder="電話番号"> <div class="error">電話番号を正しく入力してください。</div> </td> </tr> <tr> <th>ラジオボタン(必須)</th> <td class="js-radio-require"> <label> <input type="radio" name="radio-sample" value="ラジオサンプル1">ラジオサンプル1 </label> <label> <input type="radio" name="radio-sample" value="ラジオサンプル2">ラジオサンプル2 </label> <label> <input type="radio" name="radio-sample" value="ラジオサンプル3">ラジオサンプル3 </label> <div class="error">ラジオボタンを選択してください。</div> </td> </tr> <tr> <th>チェックボックス(必須)</th> <td class="js-checkbox-require"> <label> <input type="checkbox" name="checkbox-sample[]" value="チェックサンプル1">チェックサンプル1 </label> <label> <input type="checkbox" name="checkbox-sample[]" value="チェックサンプル2">チェックサンプル2 </label> <label> <input type="checkbox" name="checkbox-sample[]" value="チェックサンプル3">チェックサンプル3 </label> <div class="error">チェックボックスを選択してください。</div> </td> </tr> <tr> <th>セレクトボックス(必須)</th> <td class="js-select-require"> <select name="select-sample"> <option></option> <option>セレクトサンプル1</option> <option>セレクトサンプル2</option> <option>セレクトサンプル3</option> </select> <div class="error">セレクトボックスを選択してください。</div> </td> </tr> <tr> <th>本文</th> <td class="js-content-limit"> <textarea name="content" cols="30" rows="10" maxlength="200" placeholder="本文"></textarea> <div class="error">文字数をオーバーしています。</div> </td> </tr> </tbody> </table> <button class="btn" type="submit" value="送信">送信</button> </form>
javascriptで入力内容のチェック
ここではjQueryでjsを記述しています。まずは要素に合わせて関数を一づつ制作します。文字数の制限と、型が一致するかどうかを正規表現で制作します。
指定した内容と一致しない要素があればエラーメッセージのclassがonとなり、メッセージ表示されます。
後で使うので、すべての関数をまとめて実行するための、batch_execution()という関数も作っておきます。
// input[type="text"]のバリデーション function text_require(_this) { if(_this.val().length > 200 || _this.val() == ''){ _this.next('.error').addClass('on'); } else { _this.next('.error').removeClass('on'); } } // メールフォームのバリデーション function mail_validate(_this){ if(_this.val().length > 200 || _this.val().match(/^([a-zA-Z0-9])+([a-zA-Z0-9._-])*@([a-zA-Z0-9_-])+([a-zA-Z0-9._-]+)+$/) == null){ _this.next('.error').addClass('on'); } else { _this.next('.error').removeClass('on'); } } // 電話番号のバリデーション function phone_validate(_this){ if(_this.val().match(/^[0-9]+$/) == null){ _this.next('.error').addClass('on'); } else { _this.next('.error').removeClass('on'); } } //チェックボックスのバリデーション function check_require(_this) { var check_require = _this.parents('td.js-checkbox-require').find('input[type="checkbox"]:checked').length if(check_require > 0){ _this.parents('td.js-checkbox-require').children('.error').removeClass('on'); } else { _this.parents('td.js-checkbox-require').children('.error').addClass('on'); } } //ラジオボタンのバリデーション function radio_require(_this) { var radio_require = _this.parents('td.js-radio-require').find('input[type="radio"]:checked').length if(radio_require > 0){ _this.parents('td.js-radio-require').children('.error').removeClass('on'); } else { _this.parents('td.js-radio-require').children('.error').addClass('on'); } } //セレクトのバリデーション function select_require(_this) { var select_require = _this.val(); if(select_require == false){ _this.parents('td.js-select-require').children('.error').addClass('on'); } else { _this.parents('td.js-select-require').children('.error').removeClass('on'); } } //本文の文字数制限 function content_limit(_this) { if(_this.val().length > 200){ _this.next('.error').addClass('on'); } else { _this.next('.error').removeClass('on'); } } /*----------------------------------- /* 各種関数のまとめ -----------------------------------*/ function batch_execution() { text_require($(".js-text-require input[type=text]")); mail_validate($(".js-email-require input[type=email]")); phone_validate($(".js-phone-require input[type=tel]")); check_require($(".js-checkbox-require input[type=checkbox]")); radio_require($(".js-radio-require input[type=radio]")); select_require($(".js-select-require select")); }
上の関数を実行するタイミングを一つづつセットしていきます。
フォーカスが外れ時に実行されるのがblurで要素が変更された時が実行されるのがchangeとなります。
最後に送信ボタンを押された時、すべての関数をまとめて実行し、onになっているエラーメッセージが存在する場合、内容を送信させないようにしてjsのバリデーションは完成です。
/*----------------------------------- * 処理の実行 -----------------------------------*/ $(function(){ /** * バリデーションの実行タイミング */ $('.js-text-require input[type="text"]').blur(function(){ text_require($(this)); }); $('.js-email-require input[type="email"]').blur(function(){ mail_validate($(this)); }); $('.js-phone-require input[type="tel"]').blur(function(){ phone_validate($(this)); }); $('.js-checkbox-require input[type="checkbox"]').on('change', function(){ check_require($(this)); }); $('.js-radio-require input[type="radio"]').on('change', function(){ radio_require($(this)); }); $('.js-select-require select').on('change', function(){ select_require($(this)); }); $('.js-content-limit textarea').blur(function(){ content_limit($(this)); }); /** * エラーがある場合submitのを止める */ $('[name="mailform"]').submit(function() { batch_execution(); if( $('.error.on').length > 0) { return false } }); });
ここで制作したjsのバリデーションは、postする前のチェックしかおこなっていませんので、セキュリティ的には問題ありのフォームです。
悪意のある攻撃を仕掛けてくる人は、入力フォームを介さず直接postデータを送ってきたりするので、javascriptのバリデーションなんて無意味なのです。ユーザーの使いやすさ向上という意味では有効ですが。
実際にpostされたデータチェックするたのphpによるバリデーションも制作は必須なので、次回そちらのサンプルも公開していきます。