validate.js頁面驗證js使用方法

validate.js包含三個主要的構造: FormValidatorInputValidatorBaseValidator構造會new一個對象,對有限屬性進行覆蓋:

  FormValidator是表單的驗證構造,需要兩個參數,第一個爲表單元素,第二個爲構造的參數列表(是一個JSON對象會覆蓋掉該對象中的同名屬性)。

  InputValidator 是表單元素的驗證構造,有三個參數,第一個參數爲該對象的宿主對象(元素所在的form對象,如果傳入Null則會自動查找所在form),第二個參數爲表單元素,第三個參數爲構造屬性(是一個JSON對象會覆蓋掉該對象中的同名屬性)。

  BaseValidator爲所有驗證規則的基礎構造,構造包含兩個參數第一個參數爲驗證規則的宿主對象(一般爲InputValidator),第二個參數是驗證規則的參數列表對象(是一個JSON對象會覆蓋掉該對象中的同名屬性)。

  在使用時不需要手動調用構造參數,框架已將構造過程嵌入到了JQuery對象中,只需要用JQuery查找到對象,然後調用elementValidator方法(或同名方法initValidator)就會根據元素類型(tagName是否form)獲得相應的對象(FormValidatorInputValidator),方法需要一個參數用來覆蓋掉對象中的默認成員。

  需要使用InputValidator對象的addValidator方法構造BaseValidator對象,addValidator包含兩個參數第一個參數爲驗證規則名稱(必須是已註冊的驗證規則),第二個參數是用來覆蓋掉驗證規則對象默認成員的JSON對象,關於註冊規則將在最後說明。

 

2. 使用方法

 

2.1 初始化驗證的表單

  在頁面的load事件中調用$("#表單ID").elementValidator(或同名方法initValidator),該方法參數爲JSON Object

  $("#sForm").elementValidator({

  autoSubmit : true,//驗證通過後是否自動提交表單(默認爲true,自動提交)

  failStop:false,//驗證表單項時 某一元素驗證失敗是否終止驗證程序(默認爲false,每次表單驗證都會驗證全部元素)

  exceptionFail:true,//驗證過程中出現異常是否標記爲驗證失敗(默認爲true)

  beforeValidate:false,//在驗證之前執行的方法,如果該方法返回false則不再進行驗證,並返回false

  onFail:function(callback){},//驗證失敗會調用的方法,默認是一個空方法

  onVali:function(callback){}//驗證通過會調用的方法,默認是一個空方法

  });

  //****參數不填均爲默認值

 

2.2 初始化需要驗證的表單項

  在頁面的load事件中調用$("#元素ID").elementValidator(或同名方法initValidator) ,該方法參數爲JSON Object,調用該方法會返回一個InputValidator對象,然後通過該對象的addValidator(RuleName,{/*RuleOption*/})方法添加驗證規則

  (不需要的參數不要填寫填寫之後便會覆蓋掉默認的值,以下均爲默認值)

  $('#Email').initValidator({

  autoBind :true,//是否自動綁定驗證到元素的事件(會綁定change,focus,blur,changeblur時會進行驗證)

  msgTarget : 元素ID + "_tip",//驗證反饋元素的ID,用來顯示驗證結果,默認爲元素ID + "_tip"

  readyMsg  "",//初始狀態消息

  focusMsg: "",//獲取焦點後的消息

  validMsg  "",//驗證通過後的消息

  waitMsg  "",//等待狀態的消息

  errorMsg  "",//驗證錯誤的消息

  againMsg  "",//重試的消息

  readyClass: 'validation-ready',//初始狀態的CSS樣式

  errorClass  'validation-error',//錯誤狀態的CSS樣式

  focusClass:'validation-focus',//獲取焦點的CSS樣式

  validClass:'validation-valid',//驗證通過的CSS樣式

  waitClass  'validation-wait',//等待狀態的CSS樣式

  againClass  'validation-error',//需要重試的CSS樣式

  allowEmpty  false//是否允許爲空當設置爲true如果元素的值未填則不會進行驗證,並設置該元素的驗證狀態爲通過

  affected null,//affected元素的change事件會影響到該元素的狀態狀態取決於affectState的值

  affectState:"ready",//默認爲ready狀態

  showMsg : function(state, message{//顯示該元素驗證消息的方法,會覆蓋掉默認顯示消息方法,如果使用默認的顯示消息方法,請確保不要包含該條屬性

  message message || this[state "Msg"];

  var msgTarget $("#" this.msgTarget);

  msgTarget.removeClass().addClass(this[state "Class"]).html(message);

  },

  }).addValidator('NotNull', {//添加非空驗證

  errorMsg : '請輸入郵箱地址'

  }).addValidator('Email', {//添加郵箱格式驗證

  errorMsg : '郵箱格式錯誤,請重新輸入'

  }).addValidator('URLValue', {//添加URL資源文本驗證

  url : 'validate',

  sendData : {

  'type' : 'email'

  },

  sendKey : 'Email',

  eqValue : 'false',

  errorMsg : '該郵箱已被註冊,請重新輸入'

  });

 

2.3 默認已實現的驗證規則

  (1)NotNull (非空驗證)

  參數:

  autoTrim 是否在驗證前執行Trim操作(去除文本兩端半角空格默認爲false

 

  (2)RegExp 正則表達式驗證

  參數

  autoTrim 是否在驗證前執行Trim操作(去除文本兩端半角空格默認爲false

  regex  正則表達式(字符串)

  attr  可選的字符串,包含屬性 "g""i" 和 "m",分別用於指定全局匹配、區分大小寫的匹配和多行匹配

 

  (3)Email 郵箱格式驗證

  參數:

  autoTrim 是否在驗證前執行Trim操作(去除文本兩端半角空格默認爲false

  errorMsg 默認:"電子郵箱格式錯誤"

  Regex 默認: "^[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)+$"

 

  (4)Length 長度校驗

  參數

  min最小長度(-1爲不限)

  max最大長度(-1爲不限)

  lable提示時的標識名稱(比如該值如果是用戶名,當元素值不滿足條件會提示:用戶名長度應大於或小於xx個字符)

 

  (5)Equals 對比校驗

  參數:

  eqElement: '', //比較的元素(優先級大於eqValue)

  eqValue: '', //比較的值(eqElement不爲空時不會比較該值)

 

  (6)URLValue URL資源對比(該校驗可以做頁面 驗證碼,用戶名是否存在等ajax校驗)

  參數:

  isSync: false, //是否同步模式

  url: "", //URL

  method: "post", //提交方式

  sendData: {}, //提交的值

  sendKey: "", //提交URL請求時,使用的數據name

  eqValue: "", //對比值-將請求URL得到的文本與該值對比

 

  (7)Attr 屬性校驗(校驗元素的屬性值)

  參數:

  attr: "value", //屬性名稱

  eqValue: null, //屬性對比值

  val: function(input){//默認的獲取屬性值的方法

  return $(input).attr(this.attr);

  }

 

  (8)Number 數值驗證(數值大小不能超出JS的數值範圍-1.7976931348623157e+308 ~ 1.7976931348623157e+308)

  參數:

  onlyInt: false, //是否驗證爲整數

  min: null, //最小值(默認null爲不限制)

  max: null, //最大值(默認null爲不限制)

 

  (9)Int 整數驗證(繼承至Number 驗證)

  屬性:

  onlyInt: true

 

  (10)Function Function驗證

  參數:

  func: "",字符串或function對象,該方法需要返回Booleantruefalse

  root: window,function屬性爲字符串的時候將會在該對象下根據func的值查找function,如果查找不到則提示:驗證方法(" + func + ")未找到

 

2.4 註冊驗證規則

  使用$.validation.regRules方法註冊驗證規則,該方法有三個參數:

  參數1:驗證規則名稱,比如:Email,NumberNotNull;

  參數2:驗證規則屬性,需要包含 doValidate: function(input, waitToDo){}的函數實現,該方法返回true,false,或'wait','again'表示驗證成功,驗證失敗,等待,重試,該方法包含兩個參數,參數input表示驗證的頁面元素,waitToDo是在異步驗證回調時使用;

  參數3(可選):該驗證規則繼承來源,表示該驗證規則繼承至另一個驗證規則,可以使用this.superDoValidate得到父驗證規則的驗證方法,並可以使用父驗證規則的屬性。

  舉例:URLValue驗證,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
$.validation.regRules('URLValue', {//URL資源,值驗證
  isSync: false, //非同步
  url: "", //URL
  method: "post", //提交方式
  sendData: {}, //提交的值
  sendKey: "", //表單元素名
  eqValue: "", //對比值
  doValidate: function(input, waitToDo){
      this.sendData[this.sendKey || $(input).attr('name') || $(input).attr('id')] = this.val(input);
      var ajaxSend = function(v, waitToDo){//ajax請求數據
          $.ajax({
              url: v.url,
              type: v.method,
              cache: false,
              data: v.sendData,
              success: function(data){
                  var result = false;
                  if (data === v.eqValue) {
                      result = true;
                  }
                  else {
                      result = false;
                  }
                  waitToDo(result);//獲取數據後執行waitToDo
              },
              error: function(xhr, text){//ajaxError處理
                  var errorMessage = "與服務器通信失敗,請稍候再試";
                  waitToDo("again", errorMessage);
              }
          });
      }(this, waitToDo);
      return "wait";//返回等待狀態
  }

 

2.5 頁面使用示例

  ZAS註冊頁面

<z:config type="zas" name="註冊模板"/>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<title>用戶註冊</title>
<link rel="stylesheet" href="css/style.css"/>
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/validate.js"></script>
<script>
$(function() {
var enableUserNameCN = $("#EnableUserNameCN").val();
var regex = '^[a-zA-Z0-9_]*$';
var errorMsg = '只能使用英文、數字、下劃線';
var focusMsg = '4~24位字符,可使用英文、數字、下劃線';
if(enableUserNameCN=='Y'){
regex = '^[a-zA-Z0-9_\u4e00-\u9fa5]*$';
errorMsg = '只能使用英文、數字、中文、下劃線';
focusMsg = '4~24位字符,可使用英文、數字、下劃線、中文';
}
$('#registerForm').initValidator({
autoSubmit:true,
});
$('#UserName').initValidator({
readyMsg : '必填',
focusMsg : focusMsg,
msgTarget : 'tipname'
}).addValidator('NotNull', {
errorMsg : '請輸入用戶名'
}).addValidator('Length', {
min : 4,
max : 24,
errorMsg : '至少使用4位字符'
}).addValidator('RegExp', {
regex : '^(?!_)(?!.*?_$)',
errorMsg : '不能以下劃線開頭或結尾'
}).addValidator('RegExp', {
regex : regex,
errorMsg : errorMsg
// regex : '^[a-zA-Z0-9_]*$',
// errorMsg : '只能使用英文、數字、下劃線'
}).addValidator('URLValue', {
url : 'validate',
eqValue : 'false',
sendData : {
'type' : 'username'
},
sendKey : 'UserName',
errorMsg : '該用戶名已被使用,請重新輸入。如果您擁有該用戶名,請立即<a href="${contextPath}${sso_login}" style="color:red;">登錄</a>'
});
 
$('#Password').initValidator({
readyMsg : '必填',
focusMsg : '6-16位字符,區分大小寫',
msgTarget : 'tippassword'
}).addValidator('NotNull', {
errorMsg : '請輸入密碼'
}).addValidator('Length', {
min : 6,
max : 16,
errorMsg : '密碼應爲6-16位字符,區分大小寫'
});
 
$('#pwdok').initValidator({
readyMsg : '必填',
focusMsg : '請再次輸入密碼',
msgTarget : 'tippwdok',
affected : '#Password',
affectState : 'focus'
}).addValidator('NotNull', {
errorMsg : '請輸入確認密碼'
}).addValidator('Equals', {
eqElement : '#Password',
errorMsg : '兩次輸入的密碼不一致,請重新輸入'
});
 
$('#Email').initValidator({
readyMsg : '必填',
focusMsg : '請輸入您的常用郵箱,以便密碼丟失時找回密碼',
msgTarget : 'tipemail'
}).addValidator('NotNull', {
errorMsg : '請輸入郵箱地址'
}).addValidator('Email', {
errorMsg : '郵箱格式錯誤,請重新輸入'
}).addValidator('URLValue', {
url : 'validate',
sendData : {
'type' : 'email'
},
sendKey : 'Email',
eqValue : 'false',
errorMsg : '該郵箱已被註冊,請重新輸入'
});
 
$('#AuthCode').initValidator({
readyMsg : '必填',
focusMsg : '請輸入驗證碼',
msgTarget : 'tipauthcode'
}).addValidator('NotNull', {
errorMsg : '請輸入驗證碼'
}).addValidator('URLValue', {
url : 'validate',
sendData : {
'type' : 'authcode'
},
sendKey : 'AuthCode',
eqValue : 'true',
errorMsg : '驗證碼錯誤,請重新輸入'
});
 
$("#Checkbox").initValidator({
readyClass:'',
focusClass:'',
validClass:'',
msgTarget : 'tipcheckbox'
}).addValidator("Attr",{
errorMsg : '請先閱讀並接受《用戶註冊協議》',
attr:'checked'
});
});
 
function initAuthCode() {
$('#AuthCode').attr('value', '');
}
 
</script>
</head>
<body>
 
<z:include file="${template}header.zhtml"/>
<div class="main pageWidth">
<input type="hidden" name="EnableUserNameCN" id="EnableUserNameCN" value="${EnableUserNameCN}" />
<form id="registerForm" name="registerForm" method="post">
<input type="hidden" name="Referer" id="Referer" value="${Referer}" />
<input type="hidden" name="Type" id="Type" value="register" />
<div class="mod_com">
<div class="mod_comtitle"><h2>用戶註冊</h2></div>
<div class="mod_mainbox">
<table width="740" border="0" cellspacing="0" cellpadding="0" class="registerWrap_mainboxtable">
<tbody>
<z:if condition="${EnableUserNameCN=='Y'}">
<tr>
<td width="96" align="right">用戶名:</td>
<td colspan="2" align="left"><input type="text" id=UserName name="UserName" class="logintext1" maxlength="24"></td>
<td width="500" align="left"><span id="tipname" class="validation-ready"></span></td>
</tr>
</z:if>
<z:else>
<tr>
<td width="96" align="right">用戶名:</td>
<td colspan="2" align="left"><input type="text" id=UserName name="UserName" class="logintext1" maxlength="24"></td>
<td width="420" align="left"><span id="tipname" class="validation-ready"></span></td>
</tr>
</z:else>
<tr>
<td align="right">密 碼:</td>
<td colspan="2" align="left"><input type="password" id="Password" name="Password" class="logintext1" maxlength="16"/></td>
<td align="left"><span id="tippassword" class="validation-ready"></span></td>
</tr>
<tr>
<td align="right">確認密碼:</td>
<td colspan="2" align="left"><input type="password" id="pwdok" name="pwdok" class="logintext1" maxlength="16"/></td>
<td align="left"><span id="tippwdok" class="validation-ready"></span></td>
</tr>
<tr>
<td align="right">郵 箱:</td>
<td colspan="2" align="left"><input type="text" id="Email" name="Email" class="logintext1" maxlength="80"/></td>
<td align="left"><span id="tipemail" class="validation-ready"></span></td>
</tr>
<tr>
<td width="200" align="right">工作(擴展):</td>
<td colspan="2" align="left"><input type="text" id=job name="MetaValue_job" class="logintext1" maxlength="24"></td>
<td width="420" align="left"><span id="tipname" class="validation-ready"></span></td>-->
</tr>
<tr>
<td align="right">驗證碼:</td>
<td width="157" align="left"><input type="text" id="AuthCode" name="AuthCode" class="logintext2" maxlength="10"/></td>
<td width="89" align="left"><img id="authcode" src="${contextPath}authCode.zhtml" οnclick="$('#authcode').attr('src','authCode.zhtml?'+new Date().getTime());initAuthCode();return false;" style="vertical-align:middle; margin-left:4px;"/></td>
<td align="left"><label for="authcode">看不清?換一張</label>&nbsp;&nbsp;&nbsp;<span id="tipauthcode" class="validation-ready"></span></td>
</tr>
<tr>
<td align="right">&nbsp;</td>
<td colspan="2" align="left" valign="bottom"><input type="checkbox" id="Checkbox" name="Checkbox">我已經閱讀並接受《<span><a href="${contextPath}protocal" class="blue" target="_blank">用戶註冊協議</a></span>》</td>
<td align="left"><span id="tipcheckbox"></span></td>
</tr>
<tr>
<td align="right">&nbsp;</td>
<td colspan="3" align="left" style="padding-top:20px;"><input type="submit" class="linkbtn" value="立即註冊"/></td>
</tr>
</tbody>
</table>
</div>
</div>
</form>
</div>
 
<z:include file="${template}footer.zhtml"/>
</body>
</html>
 
附(validate.js源碼):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
//創建命名空間
$ = $ || {};
$.validation = {
    Version: "20130830_Beta",
    Company: "www.zving.com",
    Author: "[email protected]",
    UseFrame: "JQuery(使用了JQuery的查找器及屬性/樣式/事件綁定方法)",
    OpenTags: ["from", "input", "select", "textarea", "button"]
};
/**
 * 複製對象屬性至指定對象,若未指定複製到的對象則返回一個新對象,包含原對象所有屬性
 * @param {Object} copyFrom 從該對象複製
 * @param {Object} copyTo 複製到的對象  若爲Null或不傳該參則返回copyFrom的拷貝
 */
$.validation.copy = function(copyFrom, copyTo){
    if (copyTo) {
        for (var i in copyFrom) {
            copyTo[i] = copyFrom[i];
        }
    }
    else {
        var p = function(){
        };
        p.prototype = copyFrom;
        return new p();
    }
};
/***
 * 判斷值是否存在數組或對象中
 * @param {Object} value 判斷的值
 * @param {Object} array 判斷所在數組或對象
 * @return {Boolean}
 */
$.validation.inArray = function(value, array){
    for (var i in array) {
        if (value === array[i]) {
            return true;
        }
    }
    return false;
};
/**
 * 註冊規則
 * @param {String} rule 規則名稱
 * @param {Object} options 選項
 * @param {String} extendRule 繼承至哪個規則
 */
$.validation.regRules = function(rule, options, extendRule){
    $.validation.ruleOptions = $.validation.ruleOptions || {};
    if (typeof(extendRule) === "string") {
        $.validation.ruleOptions[rule] = {};
        $.validation.ruleOptions[rule].superRule = $.validation.copy($.validation.ruleOptions[extendRule]);
        $.validation.copy($.validation.ruleOptions[rule].superRule, $.validation.ruleOptions[rule]);
        $.validation.copy(options, $.validation.ruleOptions[rule]);
    }
    else {
        $.validation.ruleOptions[rule] = $.validation.copy(options);
    }
    return this;
};
 
/**
 *驗證構造
 * @param paras {Object} 寄宿對象(一般爲InputValidator對象)
 * @param options {Object}參數  :
 * {
 *  isSync {Boolean} //是否爲同步驗證(默認爲true)
 *  errorMsg {String} //錯誤提示消息(默認爲"")
 *  doValidate(input, waitToDo) {Function} //驗證方法,如果要驗證生效必須重寫(返回true,false,或'wait','again')
 *                              異步驗證需在異步回調中調用waitToDo(result, message),result爲驗證狀態,message爲返回的消息
 *  val(input) {Function} //獲取元素值的方法,可重寫,默認採用jquery的val()方法,可重寫獲取其他要驗證的值
 * }
 */
$.validation.BaseValidator = function(paras, options){
    this.isSync = true;
    //是否同步驗證
    this.ruleName = '';
    //規則名稱
    this.errorMsg = '';
    //驗證錯誤時返回的消息
    this.cache = true;
    //是否緩存驗證結果(當表單元素值未改變時會使用緩存驗證值)
     
    /**
     *
     */
    this.doValidate = function(input, waitToDo){
        return true || false || "wait";
    };
    this.val = function(input){
        return $(input).val();
    };
    $.validation.copy(options, this);
    //支持覆蓋的自定義屬性 --結束
     
    this.lastResult = null;
    this.nextor = null;
    //驗證通過後要進行的下一個驗證
     
    //重置驗證狀態
    this.resetValiState = function(){
        this.lastResult = null;
        this.lastValue = null;
        if (this.nextor) {
            return this.nextor.resetValiState();
        }
    };
    /**
     *執行繼承源的 doValidate
     */
    this.superDoValidate = function(input, waitToDo){
        if (this.superRule && typeof(this.superRule.doValidate === 'function')) {
            return this.superRule.doValidate.apply(this, arguments);
        }
    };
     
    this.validate = function(input, CallBack, eventFrom){
        var result = false;
        if (this.cache && this.val(input) === this.lastValue) {
            if (this.lastResult) {
                if (this.lastResult.state === "again") {
                    var returnValue = this.lastResult;
                    this.lastResult = null;
                    return returnValue;
                }
                if (this.nextor && this.lastResult.state === "valid") {
                    return this.nextor.validate(input, CallBack, eventFrom);
                }
                else {
                    return this.lastResult;
                }
            }
        }
        var waitToDo = this.isSync ||
        function(validator, input, CallBack, eventFrom){
            return function(result, message){
                validator.lastResult = validator.buildResult(result, message);
                validator.lastValue = validator.val(validator.paras.input);
                if (result === true && eventFrom && eventFrom === "form") {
                    validator.paras.paras.validator.validate(CallBack);
                }
                else {
                    validator.paras.validate(input, CallBack);
                }
                return validator;
            };
        }(this, input, CallBack, eventFrom);
        result = this.doValidate(input, waitToDo);
        this.lastResult = this.buildResult(result);
        this.lastValue = this.val(input);
        if (result === true) {
            if (this.nextor) {
                return this.nextor.validate(input, CallBack, eventFrom);
            }
        }
        return this.lastResult;
    };
     
    this.buildResult = function(result, message){
        var vResult = {
            rule: this.ruleName
        };
        if (result === true) {
            vResult.state = "valid";
        }
        else
            if (result === false) {
                vResult.message = message || this.errorMessage || this.errorMsg;
                this.errorMessage = null;
                vResult.state = "error";
            }
            else
                if (typeof(result) === "string") {
                    vResult.state = result;
                    vResult.message = message || this[result + "Message"] || this[result + "Msg"];
                    if (this[result + "Message"]) {
                        this[result + "Message"] = null;
                    }
                }
                else {
                    vResult.state = "ready";
                    vResult.message = message || this["readyMessage"] || this["readyMsg"];
                    if (this["readyMessage"]) {
                        this["readyMessage"] = null;
                    }
                }
        return vResult;
    };
     
    this.paras = paras;
};
/***
 *
 * @param options {Object}參數  :
 * {
 *  msgTarget {Boolean} //是否爲同步驗證(默認爲true)
 *  readyMsg {String} //錯誤提示消息(默認爲"")
 *  focusMsg {String} //錯誤提示消息(默認爲"")
 *  validMsg {String} //錯誤提示消息(默認爲"")
 *  waitMsg {String} //錯誤提示消息(默認爲"")
 *  readyClass {String} //錯誤提示消息(默認爲"")
 *  errorClass {String} //錯誤提示消息(默認爲"")
 *  focusClass {String} //錯誤提示消息(默認爲"")
 *  validClass {String} //錯誤提示消息(默認爲"")
 *  focusMsg {Function} //驗證方法(返回true,false,或'wait')
 * }
 */
$.validation.InputValidator = function(paras, input, options){
    //支持覆蓋的自定義屬性 --開始
    this.autoBind = true;
    this.msgTarget = input.id + "_tip";
    this.readyMsg = "";
    this.focusMsg = "";
    this.validMsg = "";
    this.waitMsg = "";
    this.errorMsg = "";
    this.againMsg = "";
    this.readyClass = 'validation-ready';
    this.errorClass = 'validation-error';
    this.focusClass = 'validation-focus';
    this.validClass = 'validation-valid';
    this.waitClass = 'validation-wait';
    this.againClass = 'validation-error';
    this.allowEmpty = false;
    this.affected = null;
    this.affectState = "ready";
    this.queueElement = null;
    this.showMsg = function(state, message){
        message = message || this[state + "Msg"];
        var msgTarget = $("#" + this.msgTarget);
        msgTarget.removeClass().addClass(this[state + "Class"]).html(message);
    };
     
    //支持覆蓋的自定義屬性 --結束
    $.validation.copy(options, this);
    this.input = input;
    this.firstValidator = null;
    this.lastValidator = null;
    this.validate = function(callBack, eventFrom){
        if (this.queueElement != null) {
            var qElement = $(this.queueElement)[0];
            if (qElement && qElement.validator && qElement.validator.validate().state !== "valid") {
                this.showMsg("ready");
                return {
                    state: "ready"
                };
            }
        }
        if (this.allowEmpty === true && $(this.input).val() === '') {
            this.showMsg("ready");
            return {
                state: "valid"
            };
        }
        if (this.firstValidator) {
            var result = this.firstValidator.validate(this.getElement(), callBack, eventFrom);
            this.showMsg(result.state, result.message);
            return result;
        }
    };
     
    this.resetValiState = function(state){
        this.firstValidator.resetValiState();
        this.showMsg(state);
    };
     
    this.addValidator = function(rule, options){
        var ruleOptions = $.validation.copy($.validation.ruleOptions[rule]);
        $.validation.copy(options, ruleOptions);
        if (this.affected) {
            ruleOptions.cache = false;
        }
        var newValidator = new $.validation.BaseValidator(this, ruleOptions);
        newValidator.ruleName = rule;
        if (this.firstValidator == null) {
            this.firstValidator = newValidator;
        }
        else {
            this.lastValidator.nextor = newValidator;
        }
        this.lastValidator = newValidator;
    };
    if (this.autoBind) {
        $(input).bind("change", function(v){
            return function(){
                v.validate();
            };
        }(this)).bind("focus", function(v){
            return function(){
                v.showMsg("focus");
            };
        }(this)).bind("blur", function(v){
            return function(){
                v.validate();
            };
        }(this));
    }
    if (this.affected) {
        $(this.affected).bind("change", function(v, state){
            return function(){
                v.resetValiState(state);
                if ($(v.input).val() !== "") {
                    $(v.input).focus();
                }
            };
        }(this, this.affectState));
    }
    this.getElement = function(){
        return $(this.input)[0];
    };
    $(input)[0].validator = this;
    this.showMsg("ready");
    this.paras = paras;
    if (!this.paras) {
        this.paras = this.getElement().form;
    }
};
$.validation.FormValidator = function(form, options){
    this.autoSubmit = true;
    this.failStop = false;
    this.exceptionFail = true;
    this.onFail = function(callBack){
        return false;
    };
    this.onVali = function(callBack){
        return true;
    };
    this.beforeValidate = null;
    $.validation.copy(options, this);
    this.form = form;
    //支持覆蓋的自定義屬性 --結束
     
    this.validate = function(callback){
        if (this.beforeValidate && typeof(this.beforeValidate) === 'function') {
            if (!this.beforeValidate()) {
                return false;
            }
        }
        var elements = this.form.elements;
        var valid = true;
        try {
            for (var i = 0; i < elements.length; i++) {
                var element = elements[i];
                if (element.validator && typeof(element.validator.validate) === 'function') {
                    var result = element.validator.validate(callback, "form");
                    if (result.state !== 'valid') {
                        valid = false;
                        if (this.failStop) {
                            onFail(callback);
                            return valid;
                        }
                    }
                }
            };
                    }
        catch (e) {
            valid = (!exceptionFail) && valid;
        }
        if (valid) {
            this.onVali(callback);
        }
        else {
            this.onFail(callback);
        }
        if (this.autoSubmit === true) {
            return this.submit(valid);
        }
        return valid;
    };
    this.submit = function(valid){
        if (valid === true) {
            $(this.form)[0].submit();
        }
        return false;
    };
     
    $(this.form).bind("submit", function(validator){
        return function(){
            var valid = validator.validate(validator.callBack);
            return valid;
        };
    }(this));
    $(this.form)[0].validator = this;
};
 
$.fn.elementValidator = function(options){
    var element = this[0];
    if (!element) {
        return {
            addValidator: function(){
                return this;
            }
        };
    }
    if (element.validator) {
        $.validation.copy(options, element.validator);
    }
    else {
        var tagName = (element.tagName || element.nodeType).toLowerCase();
        if (tagName === 'form') {
            element.validator = new $.validation.FormValidator(element, options);
        }
        else {
            element.validator = new $.validation.InputValidator(null, element, options);
            return this;
        }
    }
};
$.fn.initValidator = $.fn.elementValidator;
$.fn.addValidator = function(rule, options){
    //alert(rule);
    var element = this[0];
    if (element.validator && typeof(element.validator.addValidator) === 'function') {
        element.validator.addValidator(rule, options);
        return this;
    }
};
 
$.validation.regRules("Base", {
    autoTrim: false, //是否自動去掉字符串兩端的空格
    trim: function(input){
        var value = $(input).val();
        if (typeof(value) === 'string') {
            value = value.replace(/(^\s*)|(\s*$)/g, "");
        }
        else {
            value = '';
        }
        $(input).val(value);
        return value;
    }
}).regRules("NotNull", {//非空驗證
    doValidate: function(input, waitToDo){
        var value = this.autoTrim ? this.trim(input) : $(input).val();
        if (value.length > 0) {
            return true;
        }
        return false;
    }
}, "Base").regRules("RegExp", {//正則驗證
    regex: "",
    attr: "",
    doValidate: function(input, waitToDo){
        var reg = this.regex;
        if (typeof(reg) === "string") {
            reg = new RegExp(reg, this.attr);
        }
        else
            if (!typeof(reg.test) === 'function') {
                return false;
            }
        return reg.test(this.val(input));
    }
}).regRules("Email", {//Email格式驗證
    errorMsg: "電子郵箱格式錯誤",
    regex: "^[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)+$"
}, "RegExp").regRules("Length", {//字符串長度驗證
    min: -1, //最短長度(-1爲不限)
    max: -1, //最大長度(-1爲不限)
    lable: "", //提示時的標識名稱
    doValidate: function(input, waitToDo){
        var value = this.autoTrim ? this.trim(input) : $(input).val();
        var result = true;
        var valStrLen = value.length;
        if (this.min !== -1) {
            if (valStrLen < this.min) {
                result = false;
            }
        }
        if (this.max > -1) {
            if (valStrLen > this.max) {
                result = false;
            }
        }
        if (result == false && this.errorMsg == "") {
            this.setMessage();
        }
        return result;
    },
    setMessage: function(){
        this.errorMsg = this.lable + "長度應";
        if (this.max === -1) {
            this.errorMsg += "大於" + this.min + "個字符";
        }
        else
            if (this.min === -1) {
                this.errorMsg += "小於" + this.max + "個字符";
            }
            else {
                this.errorMsg += "在" + this.min + "與" + this.max + "個字符之間";
            }
    }
}, "Base").regRules("Async", {//異步
    isSync: false
}).regRules("Equals", {//比較
    eqElement: '', //比較的元素(優先級大於eqValue)
    eqValue: '', //比較的值(當eqElement不爲空時不會比較該值)
    doValidate: function(input, waitToDo){
        if (this.eqElement) {
            return this.val(this.eqElement) === this.val(input);
        }
        else {
            return this.val(input) === this.eqValue;
        }
    }
}).regRules('URLValue', {//URL資源,值驗證
    isSync: false, //非同步
    url: "", //URL
    method: "post", //提交方式
    sendData: {}, //提交的值
    sendKey: "", //表單元素名
    eqValue: "", //對比值
    doValidate: function(input, waitToDo){
        this.sendData[this.sendKey || $(input).attr('name') || $(input).attr('id')] = this.val(input);
        var ajaxSend = function(v, waitToDo){
            $.ajax({
                url: v.url,
                type: v.method,
                cache: false,
                data: v.sendData,
                success: function(data){
                    var result = false;
                    if (data === v.eqValue) {
                        result = true;
                    }
                    else {
                        result = false;
                    }
                    waitToDo(result);
                },
                error: function(xhr, text){
                    var errorMessage = "與服務器通信失敗,請稍候再試";
                    waitToDo("again", errorMessage);
                }
            });
        }(this, waitToDo);
        return "wait";
    }
}).regRules("Attr", {//屬性驗證
    attr: "value", //屬性名稱
    eqValue: null, //屬性對比值
    val: function(input){
        return $(input).attr(this.attr);
    },
    doValidate: function(input, waitToDo){
        if (this.eqValue) {
            return this.val(input) === this.eqValue;
        }
        else {
            return this.val(input) ? true : false;
        }
    }
}).regRules("Number", {//數值驗證(數值大小不能超出JS的數值範圍-1.7976931348623157e+308 ~ 1.7976931348623157e+308)
    onlyInt: false, //是否驗證爲整數
    min: null, //最小值(默認null爲不限制)
    max: null, //最大值(默認null爲不限制)
    doValidate: function(input, waitToDo){
        var numberValue = null;
        if (onlyInt) {
            numberValue = parseInt(this.val(input));
            var notInt = (numberValue.toString() !== this.val(input));
            if (notInt) {
                return false;
            }
        }
        else {
            numberValue = parseFloat(this.val(input));
            if (v !== v) {
                return false;
            }
            else
                if (v === Infinity) {
                    this.errorMessage = "超出數值範圍最大值";
                    return false;
                }
                else
                    if (v === -Infinity) {
                        this.errorMessage = "超出數值範圍最小值";
                        return false;
                    }
        }
        if (min !== null) {
            if (numberValue < min) {
                return false;
            }
        }
        if (max !== null) {
            if (numberValue > max) {
                return false;
            }
        }
        return true;
    }
}).regRules("Int", {//整數驗證(繼承至數值驗證)
    onlyInt: true
}, "Number").regRules("Function", {
    func: "",
    root: window,
    doValidate: function(input, value){
        var func = this.func;
        var doFunction = null;
        if (func) {
            var tpFunc = typeof(func);
            if (tpFunc === "string") {
                var fname = this.func;
                var cmIndex = -1;
                var funObj = this.root;
                do {
                    cmIndex = fname.indexOf('.');
                    if (cmIndex === -1) {
                        if (funObj && funObj[fname]) {
                            doFunction = funObj[fname];
                            break;
                        }
                        else {
                            this.errorMessage = "驗證方法(" + this.func + ")未找到";
                            return false;
                        }
                    }
                    else {
                        var subName = fname.substring(0, cmIndex);
                        if (funObj && funObj[subName]) {
                            funObj = funObj[subName];
                            fname = fname.substring(cmIndex + 1);
                        }
                        else {
                            this.errorMessage = "驗證方法(" + this.func + ")未找到";
                            return false;
                        }
                    }
                }
                while (true);
            }
            else {
                doFunction = tpFunc;
            }
            if (doFunction && typeof(doFunction) === "function") {
                return doFunction(input) ? true : false;
            }
            else {
                this.errorMessage = "驗證方法(" + this.func + ")無效";
                return false;
            }
        }
        return false;
    }
});
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章