將表單驗證的通用部分提煉出來,作成一個簡易插件,方便調用。css
已將源碼放到GitHub上,名字叫zValidate。html
手機可掃描下圖查看示例,PC端可點擊此處查看:git
1)須要引入zepto.js庫,便於DOM操做。github
2)將驗證規則做爲控件的一個屬性,寫在控件的html中,有點MVVM模式的味道。正則表達式
3)將控件包在form中,點擊submit按鈕,將有name或id的控件組成一個數組,分別驗證對應的規則,最終執行自定義的submit方法。數組
4)默認寫了一套錯誤樣式zValidate.css
,但其實能夠不使用樣式,例如彈框顯示錯誤。可在errorPlacement
中定義相應方法。post
5)默認的驗證方法有required、email、url、date等,可經過方法addMethod
自定義擴展。ui
下圖是一個普通的表單結構:this
1)載入zValidateurl
引入CSS文件和zepto庫文件,還有zValidate類文件,這裏說明一下 zValidate.css僅僅是表單和控件的樣式,徹底能夠自定義。
<!--zValidate.css可自定義--> <link rel="stylesheet" href="styles/zValidate.css" /> <script src="scripts/zepto/zepto.js"></script> <script src="scripts/zValidate.js"></script>
2)初始化一個zValidate
$('.validate').zValidate();
3)zValidate演示中的表單結構
控件是由fieldset包裹的,input輸入框使用了form-control樣式類,一個form表單在最外面,裏面有個submit按鈕。
這個結構只是參考,具體狀況可自定義。
<form id="validate3" method="post"> <div class="form-horizontal"> <fieldset class="form-group"> <div class="controls"> <input class="form-control" type="text" name="xxx"/> </div> </fieldset> <fieldset> <button type="submit">提交</button> </fieldset> </div> </form>
4)選項配置
詳細的選項配置能夠參考此處說明。或參考下圖:
1)init
1. form表單中必須有submit提交按鈕,在init方法中將定義form表單的提交事件。
2. 在form的提交事件中,先驗證控件的規則。
3. 驗證經過,纔會執行自定義的submit方法。
4. return false
是爲了阻止頁面刷新。
me.$currentForm.submit(function() { var result = me.check($elements); //檢查規則 if (result !== false) { me.options.submit.call(me, me.$currentForm, result); //執行自定義事件 } return false; });
2)elements
獲取當前form表單中的標籤,能夠根據實際狀況作調整,有些事件可能readonly
或disabled
的控件也須要提交上去。
this.$currentForm .find("input, select, textarea") .not("[type=submit], [type=reset], image, [disabled], [readonly], button");
3)elementValue
1. 獲取控件的值,控件多是radio、checkbox或普通的輸入框,提取方式不一樣,因此封裝了一層。
2. 先經過checkable
判斷是checkbox 或者 radio,再經過checked
方法獲取單選框與多選框選中的值。
3. number類型的輸入框要特殊處理。
4. 剩下的普通輸入框或下拉框就直接用val()
提取。
var type = $element[0].type; if(zValidate.checkable($element)) {//判斷是check or radio return this.checked($element.attr("name"), $element[0].type.toLowerCase()); }else if(type === "number" && typeof $element[0].validity !== "undefined") { return $element[0].validity.badInput ? false : $element.val(); } var val = $element.val(); return val.replace(/\r/g, "");//將換行去除
4)deserializeValue
將值類型轉換,"true" => true , "null" => null等。
規則內容被放置在控件的一個屬性中,取出來的時候是一個字符串,而更多的時候須要特定的類型,例如Boolean、Number等。
/** * 將值類型轉換 * "true" => true "false" => false "null" => null "42" => 42 * "42.5" => 42.5 "08" => "08" JSON => parse if valid String => self */ zValidate.deserializeValue = function(value) { try { return value ? value == "true" || (value == "false" ? false : value == "null" ? null : +value + "" == value ? +value : /^[\[\{]/.test(value) ? $.parseJSON(value) : value) : value; } catch (e) { return value; } };
5)check
1. 此控件的核心方法,規則的驗證就是在這裏操做。
2. 從上面elementValue
方法中提取控件的值,
3. 將data-*
開頭的屬性提取出來,再遍歷這些屬性,根據屬性值找到相應的規則(規則內容須要deserializeValue
序列化),最後調用規則方法。
4. 若是驗證錯誤,就要提取錯誤信息,並展現出來,默認是高亮,但能夠作成彈框等。
$.each($elements, function(index, input) { var $input = $(input); var name = $input.attr("name") || $input.attr("id"); if (isError || name == "") { return; } var datas = $input[0].dataset; //獲取data-*開頭的屬性 var val = me.elementValue($input); //獲取value params[name] = val; //設置要傳遞的值 $.each(datas, function(key, rule) { if (isError) return isError; rule = zValidate.deserializeValue($.trim(rule)); //格式化類型 if ($.inArray(key, me.rules) >= 0) { if (rule === false || rule === null || rule === undefined) return; var success = me.methods[key].call(me, val, $input, rule); if (!success) { isError = true; message = $input.data(key + "Message"); //錯誤提示 me.options.highlight.call(me, $input); //高亮 me.showLabel(name, $input, message); //顯示錯誤信息 } } }); });
6)methods
默認給出的幾個驗證方法。規則大部分是用正則書寫,也有簡單的比較方式。正則若是不熟悉能夠參考《正則表達式系列》。
required: function(value, $element, param) {//必填 return value.length > 0 || false; }, number: function(value, $element, param) {//合法的數字(負數,小數) return this.optional($element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value); },
7)addMethod
自定義驗證規則,能夠傳入驗證名和驗證方法。驗證方法能夠傳三個參數:
1. val:控件的值
2. $input:控件對象
3. rule:規則內容
使用方法能夠參考下面的代碼:
//自定義驗證規則 validate.addMethod('mobile', function(val, $input, rule) { return ConstCommand.regex.mobile.test(val); });