やはり調べた範囲では、client側のvalidationは jQuery.validation が、よさそ
参考url
- https://jqueryvalidation.org/
- https://jqueryvalidation.org/validate/
- https://kudakurage.hatenadiary.com/entry/20091211/1260521031
html & javascript source
詳細は、src 内のコメントを参照下さい。
src内に記載していない機能も多くありますので、 それらは、 https://jqueryvalidation.org/validate/ を参照下さい。
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script src="//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="//cdn.jsdelivr.net/npm/jquery-validation@1.19.2/dist/jquery.validate.min.js"></script> <!--〒→住所変換 by google 日本語入力api--> <script src="/contact2/common/zip2address.js"></script> <!--自動フリガナ入力--> <script src="/contact2/common/jquery.autoKana.js"></script> <script src="foo.js"></script> </head> <body class="catalogForm"> <form action="" method="post" name="form1" id="form1" class="clearDiv"> <div> <input type="text" name="name" placeholder="氏名(必須)"/> <input type="text" name="name_kana" placeholder="氏名カナ"/> </div> <div> <input type="text" name="tel" placeholder="TEL"/> </div> <div> <input type="text" name="mail" placeholder="mail"/> <input type="text" name="mail2" placeholder="mail確認"/> </div> <input type="text" name="zipcode" placeholder="郵便番号"/> <button type="button" onClick="myform.conv_zip2address()" >〒→住所変換</button><br/> <input type="text" name="address_pref" placeholder="都道府県"/> <input type="text" name="address_city" placeholder="区市町村"/> <input type="text" name="address_other" placeholder="住所 その他"/><br/> <select name="job" style="width:175px;"> <option value="">職業選択欄</option> <option value="会社員">会社員</option> <option value="公務員">公務員</option> <option value="学生" >学生</option> <option value="その他">その他</option> </select> <input type="text" name="job_other" placeholder="職業=その他の場合、入力"/><br/> 訪問のきっかけ(最大2個選択)<br/> <label style="display:inline-block; width:175px;"> <input type="checkbox" name="visit_trriger" value="tv"/>テレビ </label> <label style="display:inline-block; width:175px;"> <input type="checkbox" name="visit_trriger" value="homepage"/>ホームページ </label> <label style="display:inline-block; width:175px;"> <input type="checkbox" name="visit_trriger" value="homepage"/>知人の紹介 </label> <br/> <textarea name="opinion" style="width:500px; height:50px;" >よろしければ、ご意見をお聞かせ下さい(10文字以内)</textarea> <br/> <button type="button" onClick="myform.validate_all()">VALIDATE</button> </form> <script> $(document).ready( function(){ myform.init_input_page(); }); </script> </body> </html>
(function() { var MyForm = function() {}; MyForm.prototype = { validate_rule: { "rules" : {"name" :{"required" : true, "rangelength": [1,50] }, //「is_katakana」は独自作成のrule "name_kana" :{"required" : true, is_katakana:true}, "mail" :{email: true }, "mail2" :{email: true, equalTo: 'input[name="mail"]' }, // 「職業=その他」を選択した場合、text欄に入力 "job_other" :{ "required":{"depends":function(element) { return true ? $('select[name="job"]').val()=="その他": false; }}}, // checkbox選択数のvalidation "visit_trriger":{"rangelength": [0, 2] }, //checkboxも選択数を指定可 "opinion" :{"rangelength": [0,10] } }, messages: {"name" :{"required" :"氏名は必須項目です", "maxlength":"氏名は50文字以内で入力下さい"}, "name_kana":{"required" :"氏名(カナ)は必須項目です", "is_katakana": "氏名(カナ)はカタカナで入力下さい"}, "mail" :{"email" :"@ のあるメールアドレス形式で入力下さい"}, "mail2" :{"email" :"@ のあるメールアドレス形式で入力下さい", "equalTo" :"同じメールアドレスを2箇所へ入力下さい" }, "job_other":{"required" :"職業(その他)の場合、入力下さい"}, "visit_trriger":{"rangelength":"訪問のきっかけは2個まで選択可能です"}, "opinion" :{"maxlength":"10文字以内で入力下さい"} }, }, validate_opt_rule: { // validation後のtagやclass等 errorElement: "span", // validation NG 時の要素が label->span errorClass: "validate_NG",// validation NG 時のclass validClass: "validate_OK",// validation OK 時のclass //validation実行のタイミング onsubmit :false, onfocusout:false, onkeyup :false, onclick :false }, init_input_page: function(){ // jquery.validation の有効化 $("#form1").validate(Object.assign(this.validate_rule, this.validate_opt_rule)); // jquery.validation の独自ruleの追加 this.add_opt_validate_method(); $('input[type="text"]').attr("autocomplete","off"); //氏名→氏名カナ の自動入力 $.fn.autoKana('input[name="name"]', 'input[name="name_kana"]', {katakana:true }); }, add_opt_validate_method:function(){ var this_obj = this; // カタカナ validationの独自rule // 内部でカタカナ化の変換を行っていますが // 別method & 別タイミングで行った方がいいかも jQuery.validator.addMethod("is_katakana", function(value, element) { if(this.optional(element)) return true; //未入力はcheckしない value = this_obj.conv_zenkaku_ascii_to_han(value); value = this_obj.conv_zenkaku_hira_to_kana(value); value = this_obj.conv_hankaku_kana_to_zen(value); $(element).val(value); //「カナ」に加え、半角英数字記号もOKとしています re_pat = '^(['+'ァ-ヶー'+'a-zA-Z0-9!-/:-@¥[-`{-~'+']+)$'; var re = new RegExp(re_pat,''); return re.test(value); }); }, validate_all: function(){ alert("result of validate_all:"+ $('#form1').valid() ); }, // refer to https://github.com/hokaccha/js-zip2address conv_zip2address: function(){ var zipcode = $('input[name="zipcode"]').val().trim(); zipcode = this.conv_zenkaku_ascii_to_han(zipcode); $('input[name="zipcode"]').val(zipcode); zip2address(zipcode, function(address) { if (! address) { return null; } // google日本語入力API が、区市町村+町 で返す為、parse var address_city = address.city.match(/^.+?[区市町村]/); var address_pref_city = address.pref+address_city; var address_other = address.all; address_other = address_other.replace(address_pref_city, ''); $('input[name="address_pref"]').val(address.pref); $('input[name="address_city"]').val(address_city); $('input[name="address_other"]').val(address_other); }); }, // 全角英数字記号->半角 conv_zenkaku_ascii_to_han: function(org_str){ var half_str = org_str.replace( /[!-~]/g, function( tmp_str ) { return String.fromCharCode(tmp_str.charCodeAt(0) - 0xFEE0); } ); // 上記のcode shiftで変換NG文字の変換 return half_str.replace(/”/g, "\"") .replace(/’/g, "'") .replace(/‘/g, "`") .replace(/¥/g, "\\") .replace(/ /g, " ") .replace(/〜/g, "~"); return half_str; }, // 全角ひらがな->カナ conv_zenkaku_hira_to_kana: function(org_str){ new_str = org_str.replace(/[\u3041-\u3096]/g, function(match) { var chr = match.charCodeAt(0) + 0x60; return String.fromCharCode(chr); }); return new_str; }, // 半角カナ->全角 conv_hankaku_kana_to_zen: function(org_str){ var kana_map ={ // 濁音や半濁音は先に定義 'ガ': 'ガ', 'ギ': 'ギ', 'グ': 'グ', 'ゲ': 'ゲ', 'ゴ': 'ゴ', 'ザ': 'ザ', 'ジ': 'ジ', 'ズ': 'ズ', 'ゼ': 'ゼ', 'ゾ': 'ゾ', 'ダ': 'ダ', 'ヂ': 'ヂ', 'ヅ': 'ヅ', 'デ': 'デ', 'ド': 'ド', 'バ': 'バ', 'ビ': 'ビ', 'ブ': 'ブ', 'ベ': 'ベ', 'ボ': 'ボ', 'パ': 'パ', 'ピ': 'ピ', 'プ': 'プ', 'ペ': 'ペ', 'ポ': 'ポ', 'ヴ': 'ヴ', 'ヷ': 'ヷ', 'ヺ': 'ヺ', 'ア': 'ア', 'イ': 'イ', 'ウ': 'ウ', 'エ': 'エ', 'オ': 'オ', 'カ': 'カ', 'キ': 'キ', 'ク': 'ク', 'ケ': 'ケ', 'コ': 'コ', 'サ': 'サ', 'シ': 'シ', 'ス': 'ス', 'セ': 'セ', 'ソ': 'ソ', 'タ': 'タ', 'チ': 'チ', 'ツ': 'ツ', 'テ': 'テ', 'ト': 'ト', 'ナ': 'ナ', 'ニ': 'ニ', 'ヌ': 'ヌ', 'ネ': 'ネ', 'ノ': 'ノ', 'ハ': 'ハ', 'ヒ': 'ヒ', 'フ': 'フ', 'ヘ': 'ヘ', 'ホ': 'ホ', 'マ': 'マ', 'ミ': 'ミ', 'ム': 'ム', 'メ': 'メ', 'モ': 'モ', 'ヤ': 'ヤ', 'ユ': 'ユ', 'ヨ': 'ヨ', 'ラ': 'ラ', 'リ': 'リ', 'ル': 'ル', 'レ': 'レ', 'ロ': 'ロ', 'ワ': 'ワ', 'ヲ': 'ヲ', 'ン': 'ン', 'ァ': 'ァ', 'ィ': 'ィ', 'ゥ': 'ゥ', 'ェ': 'ェ', 'ォ': 'ォ', 'ッ': 'ッ', 'ャ': 'ャ', 'ュ': 'ュ', 'ョ': 'ョ', '。': '。', '、': '、', 'ー': 'ー', '「': '「', '」': '」', '・': '・'}; var re = new RegExp('('+Object.keys(kana_map).join('|')+')','g'); return org_str.replace(re, function (match) { return kana_map[match]; }).replace(/゙/g, '゛').replace(/゚/g, '゜'); } }; window.myform = new MyForm(); })();