jquery-validation-rails 1.11.1.1 → 1.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/app/assets/javascripts/jquery.validate.additional-methods.js +634 -418
  4. data/app/assets/javascripts/jquery.validate.js +202 -140
  5. data/app/assets/javascripts/jquery.validate.localization/messages_ar.js +3 -3
  6. data/app/assets/javascripts/jquery.validate.localization/messages_bg.js +4 -4
  7. data/app/assets/javascripts/jquery.validate.localization/messages_ca.js +3 -3
  8. data/app/assets/javascripts/jquery.validate.localization/messages_cs.js +3 -3
  9. data/app/assets/javascripts/jquery.validate.localization/messages_da.js +2 -2
  10. data/app/assets/javascripts/jquery.validate.localization/messages_de.js +2 -2
  11. data/app/assets/javascripts/jquery.validate.localization/messages_el.js +3 -3
  12. data/app/assets/javascripts/jquery.validate.localization/messages_es.js +8 -5
  13. data/app/assets/javascripts/jquery.validate.localization/messages_es_AR.js +29 -0
  14. data/app/assets/javascripts/jquery.validate.localization/messages_et.js +2 -2
  15. data/app/assets/javascripts/jquery.validate.localization/messages_eu.js +3 -3
  16. data/app/assets/javascripts/jquery.validate.localization/messages_fa.js +3 -3
  17. data/app/assets/javascripts/jquery.validate.localization/messages_fi.js +1 -1
  18. data/app/assets/javascripts/jquery.validate.localization/messages_fr.js +8 -5
  19. data/app/assets/javascripts/jquery.validate.localization/messages_he.js +3 -3
  20. data/app/assets/javascripts/jquery.validate.localization/messages_hr.js +3 -3
  21. data/app/assets/javascripts/jquery.validate.localization/messages_hu.js +2 -2
  22. data/app/assets/javascripts/jquery.validate.localization/messages_id.js +24 -0
  23. data/app/assets/javascripts/jquery.validate.localization/messages_is.js +23 -0
  24. data/app/assets/javascripts/jquery.validate.localization/messages_it.js +7 -4
  25. data/app/assets/javascripts/jquery.validate.localization/messages_ja.js +9 -9
  26. data/app/assets/javascripts/jquery.validate.localization/messages_ka.js +3 -3
  27. data/app/assets/javascripts/jquery.validate.localization/messages_kk.js +9 -9
  28. data/app/assets/javascripts/jquery.validate.localization/messages_ko.js +13 -13
  29. data/app/assets/javascripts/jquery.validate.localization/messages_lt.js +9 -9
  30. data/app/assets/javascripts/jquery.validate.localization/messages_lv.js +3 -3
  31. data/app/assets/javascripts/jquery.validate.localization/messages_my.js +3 -3
  32. data/app/assets/javascripts/jquery.validate.localization/messages_nl.js +3 -3
  33. data/app/assets/javascripts/jquery.validate.localization/messages_no.js +2 -2
  34. data/app/assets/javascripts/jquery.validate.localization/messages_pl.js +3 -3
  35. data/app/assets/javascripts/jquery.validate.localization/messages_pt_BR.js +8 -5
  36. data/app/assets/javascripts/jquery.validate.localization/messages_pt_PT.js +6 -3
  37. data/app/assets/javascripts/jquery.validate.localization/messages_ro.js +3 -3
  38. data/app/assets/javascripts/jquery.validate.localization/messages_ru.js +3 -3
  39. data/app/assets/javascripts/jquery.validate.localization/messages_si.js +2 -2
  40. data/app/assets/javascripts/jquery.validate.localization/messages_sk.js +2 -2
  41. data/app/assets/javascripts/jquery.validate.localization/messages_sl.js +3 -3
  42. data/app/assets/javascripts/jquery.validate.localization/messages_sr.js +5 -5
  43. data/app/assets/javascripts/jquery.validate.localization/messages_sr_lat.js +25 -0
  44. data/app/assets/javascripts/jquery.validate.localization/messages_sv.js +1 -1
  45. data/app/assets/javascripts/jquery.validate.localization/messages_th.js +3 -3
  46. data/app/assets/javascripts/jquery.validate.localization/messages_tj.js +25 -0
  47. data/app/assets/javascripts/jquery.validate.localization/messages_tr.js +3 -3
  48. data/app/assets/javascripts/jquery.validate.localization/messages_uk.js +3 -3
  49. data/app/assets/javascripts/jquery.validate.localization/messages_vi.js +9 -9
  50. data/app/assets/javascripts/jquery.validate.localization/messages_zh.js +19 -19
  51. data/app/assets/javascripts/jquery.validate.localization/messages_zh_TW.js +15 -15
  52. data/app/assets/javascripts/jquery.validate.localization/methods_de.js +1 -1
  53. data/app/assets/javascripts/jquery.validate.localization/methods_es_CL.js +12 -0
  54. data/app/assets/javascripts/jquery.validate.localization/methods_nl.js +1 -1
  55. data/app/assets/javascripts/jquery.validate.localization/methods_pt.js +1 -1
  56. data/lib/jquery/validation/rails/version.rb +1 -1
  57. metadata +20 -15
@@ -1,18 +1,15 @@
1
1
  /*!
2
- * jQuery Validation Plugin 1.11.1
2
+ * jQuery Validation Plugin v1.12.0
3
3
  *
4
- * http://bassistance.de/jquery-plugins/jquery-plugin-validation/
5
- * http://docs.jquery.com/Plugins/Validation
4
+ * http://jqueryvalidation.org/
6
5
  *
7
- * Copyright 2013 Jörn Zaefferer
8
- * Released under the MIT license:
9
- * http://www.opensource.org/licenses/mit-license.php
6
+ * Copyright (c) 2014 Jörn Zaefferer
7
+ * Released under the MIT license
10
8
  */
11
-
12
9
  (function($) {
13
10
 
14
11
  $.extend($.fn, {
15
- // http://docs.jquery.com/Plugins/Validation/validate
12
+ // http://jqueryvalidation.org/validate/
16
13
  validate: function( options ) {
17
14
 
18
15
  // if nothing is selected, return nothing; can't chain anyway
@@ -95,20 +92,22 @@ $.extend($.fn, {
95
92
 
96
93
  return validator;
97
94
  },
98
- // http://docs.jquery.com/Plugins/Validation/valid
95
+ // http://jqueryvalidation.org/valid/
99
96
  valid: function() {
97
+ var valid, validator;
98
+
100
99
  if ( $(this[0]).is("form")) {
101
- return this.validate().form();
100
+ valid = this.validate().form();
102
101
  } else {
103
- var valid = true;
104
- var validator = $(this[0].form).validate();
102
+ valid = true;
103
+ validator = $(this[0].form).validate();
105
104
  this.each(function() {
106
- valid = valid && validator.element(this);
105
+ valid = validator.element(this) && valid;
107
106
  });
108
- return valid;
109
107
  }
108
+ return valid;
110
109
  },
111
- // attributes: space seperated list of attributes to retrieve and remove
110
+ // attributes: space separated list of attributes to retrieve and remove
112
111
  removeAttrs: function( attributes ) {
113
112
  var result = {},
114
113
  $element = this;
@@ -118,18 +117,19 @@ $.extend($.fn, {
118
117
  });
119
118
  return result;
120
119
  },
121
- // http://docs.jquery.com/Plugins/Validation/rules
120
+ // http://jqueryvalidation.org/rules/
122
121
  rules: function( command, argument ) {
123
- var element = this[0];
122
+ var element = this[0],
123
+ settings, staticRules, existingRules, data, param, filtered;
124
124
 
125
125
  if ( command ) {
126
- var settings = $.data(element.form, "validator").settings;
127
- var staticRules = settings.rules;
128
- var existingRules = $.validator.staticRules(element);
129
- switch(command) {
126
+ settings = $.data(element.form, "validator").settings;
127
+ staticRules = settings.rules;
128
+ existingRules = $.validator.staticRules(element);
129
+ switch (command) {
130
130
  case "add":
131
131
  $.extend(existingRules, $.validator.normalizeRule(argument));
132
- // remove messages from rules, but allow them to be set separetely
132
+ // remove messages from rules, but allow them to be set separately
133
133
  delete existingRules.messages;
134
134
  staticRules[element.name] = existingRules;
135
135
  if ( argument.messages ) {
@@ -141,16 +141,19 @@ $.extend($.fn, {
141
141
  delete staticRules[element.name];
142
142
  return existingRules;
143
143
  }
144
- var filtered = {};
144
+ filtered = {};
145
145
  $.each(argument.split(/\s/), function( index, method ) {
146
146
  filtered[method] = existingRules[method];
147
147
  delete existingRules[method];
148
+ if ( method === "required" ) {
149
+ $(element).removeAttr("aria-required");
150
+ }
148
151
  });
149
152
  return filtered;
150
153
  }
151
154
  }
152
155
 
153
- var data = $.validator.normalizeRules(
156
+ data = $.validator.normalizeRules(
154
157
  $.extend(
155
158
  {},
156
159
  $.validator.classRules(element),
@@ -161,9 +164,17 @@ $.extend($.fn, {
161
164
 
162
165
  // make sure required is at front
163
166
  if ( data.required ) {
164
- var param = data.required;
167
+ param = data.required;
165
168
  delete data.required;
166
- data = $.extend({required: param}, data);
169
+ data = $.extend({ required: param }, data );
170
+ $(element).attr( "aria-required", "true" );
171
+ }
172
+
173
+ // make sure remote is at back
174
+ if ( data.remote ) {
175
+ param = data.remote;
176
+ delete data.remote;
177
+ data = $.extend( data, { remote: param });
167
178
  }
168
179
 
169
180
  return data;
@@ -172,11 +183,11 @@ $.extend($.fn, {
172
183
 
173
184
  // Custom selectors
174
185
  $.extend($.expr[":"], {
175
- // http://docs.jquery.com/Plugins/Validation/blank
186
+ // http://jqueryvalidation.org/blank-selector/
176
187
  blank: function( a ) { return !$.trim("" + $(a).val()); },
177
- // http://docs.jquery.com/Plugins/Validation/filled
188
+ // http://jqueryvalidation.org/filled-selector/
178
189
  filled: function( a ) { return !!$.trim("" + $(a).val()); },
179
- // http://docs.jquery.com/Plugins/Validation/unchecked
190
+ // http://jqueryvalidation.org/unchecked-selector/
180
191
  unchecked: function( a ) { return !$(a).prop("checked"); }
181
192
  });
182
193
 
@@ -187,6 +198,7 @@ $.validator = function( options, form ) {
187
198
  this.init();
188
199
  };
189
200
 
201
+ // http://jqueryvalidation.org/jQuery.validator.format/
190
202
  $.validator.format = function( source, params ) {
191
203
  if ( arguments.length === 1 ) {
192
204
  return function() {
@@ -224,7 +236,7 @@ $.extend($.validator, {
224
236
  onsubmit: true,
225
237
  ignore: ":hidden",
226
238
  ignoreTitle: false,
227
- onfocusin: function( element, event ) {
239
+ onfocusin: function( element ) {
228
240
  this.lastActive = element;
229
241
 
230
242
  // hide error label and remove error class on focus if enabled
@@ -235,7 +247,7 @@ $.extend($.validator, {
235
247
  this.addWrapper(this.errorsFor(element)).hide();
236
248
  }
237
249
  },
238
- onfocusout: function( element, event ) {
250
+ onfocusout: function( element ) {
239
251
  if ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) {
240
252
  this.element(element);
241
253
  }
@@ -247,13 +259,13 @@ $.extend($.validator, {
247
259
  this.element(element);
248
260
  }
249
261
  },
250
- onclick: function( element, event ) {
262
+ onclick: function( element ) {
251
263
  // click on selects, radiobuttons and checkboxes
252
264
  if ( element.name in this.submitted ) {
253
265
  this.element(element);
254
- }
266
+
255
267
  // or option elements, check parent select in that case
256
- else if ( element.parentNode.name in this.submitted ) {
268
+ } else if ( element.parentNode.name in this.submitted ) {
257
269
  this.element(element.parentNode);
258
270
  }
259
271
  },
@@ -273,7 +285,7 @@ $.extend($.validator, {
273
285
  }
274
286
  },
275
287
 
276
- // http://docs.jquery.com/Plugins/Validation/Validator/setDefaults
288
+ // http://jqueryvalidation.org/jQuery.validator.setDefaults/
277
289
  setDefaults: function( settings ) {
278
290
  $.extend( $.validator.defaults, settings );
279
291
  },
@@ -312,7 +324,8 @@ $.extend($.validator, {
312
324
  this.invalid = {};
313
325
  this.reset();
314
326
 
315
- var groups = (this.groups = {});
327
+ var groups = (this.groups = {}),
328
+ rules;
316
329
  $.each(this.settings.groups, function( key, value ) {
317
330
  if ( typeof value === "string" ) {
318
331
  value = value.split(/\s/);
@@ -321,16 +334,17 @@ $.extend($.validator, {
321
334
  groups[name] = key;
322
335
  });
323
336
  });
324
- var rules = this.settings.rules;
337
+ rules = this.settings.rules;
325
338
  $.each(rules, function( key, value ) {
326
339
  rules[key] = $.validator.normalizeRule(value);
327
340
  });
328
341
 
329
342
  function delegate(event) {
330
343
  var validator = $.data(this[0].form, "validator"),
331
- eventType = "on" + event.type.replace(/^validate/, "");
332
- if ( validator.settings[eventType] ) {
333
- validator.settings[eventType].call(validator, this[0], event);
344
+ eventType = "on" + event.type.replace(/^validate/, ""),
345
+ settings = validator.settings;
346
+ if ( settings[eventType] && !this.is( settings.ignore ) ) {
347
+ settings[eventType].call(validator, this[0], event);
334
348
  }
335
349
  }
336
350
  $(this.currentForm)
@@ -345,15 +359,19 @@ $.extend($.validator, {
345
359
  if ( this.settings.invalidHandler ) {
346
360
  $(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler);
347
361
  }
362
+
363
+ // Add aria-required to any Static/Data/Class required fields before first validation
364
+ // Screen readers require this attribute to be present before the initial submission http://www.w3.org/TR/WCAG-TECHS/ARIA2.html
365
+ $(this.currentForm).find("[required], [data-rule-required], .required").attr("aria-required", "true");
348
366
  },
349
367
 
350
- // http://docs.jquery.com/Plugins/Validation/Validator/form
368
+ // http://jqueryvalidation.org/Validator.form/
351
369
  form: function() {
352
370
  this.checkForm();
353
371
  $.extend(this.submitted, this.errorMap);
354
372
  this.invalid = $.extend({}, this.errorMap);
355
373
  if ( !this.valid() ) {
356
- $(this.currentForm).triggerHandler("invalid-form", [this]);
374
+ $(this.currentForm).triggerHandler("invalid-form", [ this ]);
357
375
  }
358
376
  this.showErrors();
359
377
  return this.valid();
@@ -367,18 +385,30 @@ $.extend($.validator, {
367
385
  return this.valid();
368
386
  },
369
387
 
370
- // http://docs.jquery.com/Plugins/Validation/Validator/element
388
+ // http://jqueryvalidation.org/Validator.element/
371
389
  element: function( element ) {
372
- element = this.validationTargetFor( this.clean( element ) );
373
- this.lastElement = element;
374
- this.prepareElement( element );
375
- this.currentElements = $(element);
376
- var result = this.check( element ) !== false;
377
- if ( result ) {
378
- delete this.invalid[element.name];
390
+ var cleanElement = this.clean( element ),
391
+ checkElement = this.validationTargetFor( cleanElement ),
392
+ result = true;
393
+
394
+ this.lastElement = checkElement;
395
+
396
+ if ( checkElement === undefined ) {
397
+ delete this.invalid[ cleanElement.name ];
379
398
  } else {
380
- this.invalid[element.name] = true;
399
+ this.prepareElement( checkElement );
400
+ this.currentElements = $( checkElement );
401
+
402
+ result = this.check( checkElement ) !== false;
403
+ if (result) {
404
+ delete this.invalid[checkElement.name];
405
+ } else {
406
+ this.invalid[checkElement.name] = true;
407
+ }
381
408
  }
409
+ // Add aria-invalid status for screen readers
410
+ $( element ).attr( "aria-invalid", !result );
411
+
382
412
  if ( !this.numberOfInvalids() ) {
383
413
  // Hide error containers on last error
384
414
  this.toHide = this.toHide.add( this.containers );
@@ -387,7 +417,7 @@ $.extend($.validator, {
387
417
  return result;
388
418
  },
389
419
 
390
- // http://docs.jquery.com/Plugins/Validation/Validator/showErrors
420
+ // http://jqueryvalidation.org/Validator.showErrors/
391
421
  showErrors: function( errors ) {
392
422
  if ( errors ) {
393
423
  // add items to error list and map
@@ -411,7 +441,7 @@ $.extend($.validator, {
411
441
  }
412
442
  },
413
443
 
414
- // http://docs.jquery.com/Plugins/Validation/Validator/resetForm
444
+ // http://jqueryvalidation.org/Validator.resetForm/
415
445
  resetForm: function() {
416
446
  if ( $.fn.resetForm ) {
417
447
  $(this.currentForm).resetForm();
@@ -420,7 +450,10 @@ $.extend($.validator, {
420
450
  this.lastElement = null;
421
451
  this.prepareForm();
422
452
  this.hideErrors();
423
- this.elements().removeClass( this.settings.errorClass ).removeData( "previousValue" );
453
+ this.elements()
454
+ .removeClass( this.settings.errorClass )
455
+ .removeData( "previousValue" )
456
+ .removeAttr( "aria-invalid" );
424
457
  },
425
458
 
426
459
  numberOfInvalids: function() {
@@ -428,8 +461,10 @@ $.extend($.validator, {
428
461
  },
429
462
 
430
463
  objectLength: function( obj ) {
431
- var count = 0;
432
- for ( var i in obj ) {
464
+ /* jshint unused: false */
465
+ var count = 0,
466
+ i;
467
+ for ( i in obj ) {
433
468
  count++;
434
469
  }
435
470
  return count;
@@ -497,7 +532,7 @@ $.extend($.validator, {
497
532
  },
498
533
 
499
534
  errors: function() {
500
- var errorClass = this.settings.errorClass.replace(" ", ".");
535
+ var errorClass = this.settings.errorClass.split(" ").join(".");
501
536
  return $(this.settings.errorElement + "." + errorClass, this.errorContext);
502
537
  },
503
538
 
@@ -521,13 +556,15 @@ $.extend($.validator, {
521
556
  },
522
557
 
523
558
  elementValue: function( element ) {
524
- var type = $(element).attr("type"),
525
- val = $(element).val();
559
+ var val,
560
+ $element = $(element),
561
+ type = $element.attr("type");
526
562
 
527
563
  if ( type === "radio" || type === "checkbox" ) {
528
- return $("input[name='" + $(element).attr("name") + "']:checked").val();
564
+ return $("input[name='" + $element.attr("name") + "']:checked").val();
529
565
  }
530
566
 
567
+ val = $element.val();
531
568
  if ( typeof val === "string" ) {
532
569
  return val.replace(/\r/g, "");
533
570
  }
@@ -537,20 +574,23 @@ $.extend($.validator, {
537
574
  check: function( element ) {
538
575
  element = this.validationTargetFor( this.clean( element ) );
539
576
 
540
- var rules = $(element).rules();
541
- var dependencyMismatch = false;
542
- var val = this.elementValue(element);
543
- var result;
577
+ var rules = $(element).rules(),
578
+ rulesCount = $.map( rules, function(n, i) {
579
+ return i;
580
+ }).length,
581
+ dependencyMismatch = false,
582
+ val = this.elementValue(element),
583
+ result, method, rule;
544
584
 
545
- for (var method in rules ) {
546
- var rule = { method: method, parameters: rules[method] };
585
+ for (method in rules ) {
586
+ rule = { method: method, parameters: rules[method] };
547
587
  try {
548
588
 
549
589
  result = $.validator.methods[method].call( this, val, element, rule.parameters );
550
590
 
551
591
  // if a method indicates that the field is optional and therefore valid,
552
592
  // don't mark it as valid when there are no other rules
553
- if ( result === "dependency-mismatch" ) {
593
+ if ( result === "dependency-mismatch" && rulesCount === 1 ) {
554
594
  dependencyMismatch = true;
555
595
  continue;
556
596
  }
@@ -583,8 +623,10 @@ $.extend($.validator, {
583
623
 
584
624
  // return the custom message for the given element and validation method
585
625
  // specified in the element's HTML5 data attribute
626
+ // return the generic message if present and no method specific message is present
586
627
  customDataMessage: function( element, method ) {
587
- return $(element).data("msg-" + method.toLowerCase()) || (element.attributes && $(element).attr("data-msg-" + method.toLowerCase()));
628
+ return $( element ).data( "msg" + method[ 0 ].toUpperCase() +
629
+ method.substring( 1 ).toLowerCase() ) || $( element ).data("msg");
588
630
  },
589
631
 
590
632
  // return the custom message for the given element name and validation method
@@ -595,7 +637,7 @@ $.extend($.validator, {
595
637
 
596
638
  // return the first defined argument, allowing empty strings
597
639
  findDefined: function() {
598
- for(var i = 0; i < arguments.length; i++) {
640
+ for (var i = 0; i < arguments.length; i++) {
599
641
  if ( arguments[i] !== undefined ) {
600
642
  return arguments[i];
601
643
  }
@@ -624,7 +666,8 @@ $.extend($.validator, {
624
666
  }
625
667
  this.errorList.push({
626
668
  message: message,
627
- element: element
669
+ element: element,
670
+ method: rule.method
628
671
  });
629
672
 
630
673
  this.errorMap[element.name] = message;
@@ -639,9 +682,9 @@ $.extend($.validator, {
639
682
  },
640
683
 
641
684
  defaultShowErrors: function() {
642
- var i, elements;
685
+ var i, elements, error;
643
686
  for ( i = 0; this.errorList[i]; i++ ) {
644
- var error = this.errorList[i];
687
+ error = this.errorList[i];
645
688
  if ( this.settings.highlight ) {
646
689
  this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );
647
690
  }
@@ -740,7 +783,7 @@ $.extend($.validator, {
740
783
  },
741
784
 
742
785
  getLength: function( value, element ) {
743
- switch( element.nodeName.toLowerCase() ) {
786
+ switch ( element.nodeName.toLowerCase() ) {
744
787
  case "select":
745
788
  return $("option:selected", element).length;
746
789
  case "input":
@@ -756,7 +799,7 @@ $.extend($.validator, {
756
799
  },
757
800
 
758
801
  dependTypes: {
759
- "boolean": function( param, element ) {
802
+ "boolean": function( param ) {
760
803
  return param;
761
804
  },
762
805
  "string": function( param, element ) {
@@ -790,7 +833,7 @@ $.extend($.validator, {
790
833
  $(this.currentForm).submit();
791
834
  this.formSubmitted = false;
792
835
  } else if (!valid && this.pendingRequest === 0 && this.formSubmitted) {
793
- $(this.currentForm).triggerHandler("invalid-form", [this]);
836
+ $(this.currentForm).triggerHandler("invalid-form", [ this ]);
794
837
  this.formSubmitted = false;
795
838
  }
796
839
  },
@@ -806,14 +849,14 @@ $.extend($.validator, {
806
849
  },
807
850
 
808
851
  classRuleSettings: {
809
- required: {required: true},
810
- email: {email: true},
811
- url: {url: true},
812
- date: {date: true},
813
- dateISO: {dateISO: true},
814
- number: {number: true},
815
- digits: {digits: true},
816
- creditcard: {creditcard: true}
852
+ required: { required: true },
853
+ email: { email: true },
854
+ url: { url: true },
855
+ date: { date: true },
856
+ dateISO: { dateISO: true },
857
+ number: { number: true },
858
+ digits: { digits: true },
859
+ creditcard: { creditcard: true }
817
860
  },
818
861
 
819
862
  addClassRules: function( className, rules ) {
@@ -825,8 +868,9 @@ $.extend($.validator, {
825
868
  },
826
869
 
827
870
  classRules: function( element ) {
828
- var rules = {};
829
- var classes = $(element).attr("class");
871
+ var rules = {},
872
+ classes = $(element).attr("class");
873
+
830
874
  if ( classes ) {
831
875
  $.each(classes.split(" "), function() {
832
876
  if ( this in $.validator.classRuleSettings ) {
@@ -838,16 +882,16 @@ $.extend($.validator, {
838
882
  },
839
883
 
840
884
  attributeRules: function( element ) {
841
- var rules = {};
842
- var $element = $(element);
843
- var type = $element[0].getAttribute("type");
885
+ var rules = {},
886
+ $element = $(element),
887
+ type = element.getAttribute("type"),
888
+ method, value;
844
889
 
845
- for (var method in $.validator.methods) {
846
- var value;
890
+ for (method in $.validator.methods) {
847
891
 
848
892
  // support for <input required> in both html5 and older browsers
849
893
  if ( method === "required" ) {
850
- value = $element.get(0).getAttribute(method);
894
+ value = element.getAttribute(method);
851
895
  // Some browsers return an empty string for the required attribute
852
896
  // and non-HTML5 browsers might have required="" markup
853
897
  if ( value === "" ) {
@@ -865,9 +909,9 @@ $.extend($.validator, {
865
909
  value = Number(value);
866
910
  }
867
911
 
868
- if ( value ) {
912
+ if ( value || value === 0 ) {
869
913
  rules[method] = value;
870
- } else if ( type === method && type !== 'range' ) {
914
+ } else if ( type === method && type !== "range" ) {
871
915
  // exception: the jquery validate 'range' method
872
916
  // does not test for the html5 'range' type
873
917
  rules[method] = true;
@@ -884,19 +928,20 @@ $.extend($.validator, {
884
928
 
885
929
  dataRules: function( element ) {
886
930
  var method, value,
887
- rules = {}, $element = $(element);
888
- for (method in $.validator.methods) {
889
- value = $element.data("rule-" + method.toLowerCase());
931
+ rules = {}, $element = $( element );
932
+ for ( method in $.validator.methods ) {
933
+ value = $element.data( "rule" + method[ 0 ].toUpperCase() + method.substring( 1 ).toLowerCase() );
890
934
  if ( value !== undefined ) {
891
- rules[method] = value;
935
+ rules[ method ] = value;
892
936
  }
893
937
  }
894
938
  return rules;
895
939
  },
896
940
 
897
941
  staticRules: function( element ) {
898
- var rules = {};
899
- var validator = $.data(element.form, "validator");
942
+ var rules = {},
943
+ validator = $.data(element.form, "validator");
944
+
900
945
  if ( validator.settings.rules ) {
901
946
  rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {};
902
947
  }
@@ -935,19 +980,19 @@ $.extend($.validator, {
935
980
  });
936
981
 
937
982
  // clean number parameters
938
- $.each(['minlength', 'maxlength'], function() {
983
+ $.each([ "minlength", "maxlength" ], function() {
939
984
  if ( rules[this] ) {
940
985
  rules[this] = Number(rules[this]);
941
986
  }
942
987
  });
943
- $.each(['rangelength', 'range'], function() {
988
+ $.each([ "rangelength", "range" ], function() {
944
989
  var parts;
945
990
  if ( rules[this] ) {
946
991
  if ( $.isArray(rules[this]) ) {
947
- rules[this] = [Number(rules[this][0]), Number(rules[this][1])];
992
+ rules[this] = [ Number(rules[this][0]), Number(rules[this][1]) ];
948
993
  } else if ( typeof rules[this] === "string" ) {
949
994
  parts = rules[this].split(/[\s,]+/);
950
- rules[this] = [Number(parts[0]), Number(parts[1])];
995
+ rules[this] = [ Number(parts[0]), Number(parts[1]) ];
951
996
  }
952
997
  }
953
998
  });
@@ -955,12 +1000,12 @@ $.extend($.validator, {
955
1000
  if ( $.validator.autoCreateRanges ) {
956
1001
  // auto-create ranges
957
1002
  if ( rules.min && rules.max ) {
958
- rules.range = [rules.min, rules.max];
1003
+ rules.range = [ rules.min, rules.max ];
959
1004
  delete rules.min;
960
1005
  delete rules.max;
961
1006
  }
962
1007
  if ( rules.minlength && rules.maxlength ) {
963
- rules.rangelength = [rules.minlength, rules.maxlength];
1008
+ rules.rangelength = [ rules.minlength, rules.maxlength ];
964
1009
  delete rules.minlength;
965
1010
  delete rules.maxlength;
966
1011
  }
@@ -981,7 +1026,7 @@ $.extend($.validator, {
981
1026
  return data;
982
1027
  },
983
1028
 
984
- // http://docs.jquery.com/Plugins/Validation/Validator/addMethod
1029
+ // http://jqueryvalidation.org/jQuery.validator.addMethod/
985
1030
  addMethod: function( name, method, message ) {
986
1031
  $.validator.methods[name] = method;
987
1032
  $.validator.messages[name] = message !== undefined ? message : $.validator.messages[name];
@@ -992,7 +1037,7 @@ $.extend($.validator, {
992
1037
 
993
1038
  methods: {
994
1039
 
995
- // http://docs.jquery.com/Plugins/Validation/Methods/required
1040
+ // http://jqueryvalidation.org/required-method/
996
1041
  required: function( value, element, param ) {
997
1042
  // check if dependency is met
998
1043
  if ( !this.depend(param, element) ) {
@@ -1009,40 +1054,43 @@ $.extend($.validator, {
1009
1054
  return $.trim(value).length > 0;
1010
1055
  },
1011
1056
 
1012
- // http://docs.jquery.com/Plugins/Validation/Methods/email
1057
+ // http://jqueryvalidation.org/email-method/
1013
1058
  email: function( value, element ) {
1014
- // contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/
1015
- return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(value);
1059
+ // From http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#e-mail-state-%28type=email%29
1060
+ // Retrieved 2014-01-14
1061
+ // If you have a problem with this implementation, report a bug against the above spec
1062
+ // Or use custom methods to implement your own email validation
1063
+ return this.optional(element) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(value);
1016
1064
  },
1017
1065
 
1018
- // http://docs.jquery.com/Plugins/Validation/Methods/url
1066
+ // http://jqueryvalidation.org/url-method/
1019
1067
  url: function( value, element ) {
1020
1068
  // contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/
1021
1069
  return this.optional(element) || /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);
1022
1070
  },
1023
1071
 
1024
- // http://docs.jquery.com/Plugins/Validation/Methods/date
1072
+ // http://jqueryvalidation.org/date-method/
1025
1073
  date: function( value, element ) {
1026
1074
  return this.optional(element) || !/Invalid|NaN/.test(new Date(value).toString());
1027
1075
  },
1028
1076
 
1029
- // http://docs.jquery.com/Plugins/Validation/Methods/dateISO
1077
+ // http://jqueryvalidation.org/dateISO-method/
1030
1078
  dateISO: function( value, element ) {
1031
1079
  return this.optional(element) || /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/.test(value);
1032
1080
  },
1033
1081
 
1034
- // http://docs.jquery.com/Plugins/Validation/Methods/number
1082
+ // http://jqueryvalidation.org/number-method/
1035
1083
  number: function( value, element ) {
1036
1084
  return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value);
1037
1085
  },
1038
1086
 
1039
- // http://docs.jquery.com/Plugins/Validation/Methods/digits
1087
+ // http://jqueryvalidation.org/digits-method/
1040
1088
  digits: function( value, element ) {
1041
1089
  return this.optional(element) || /^\d+$/.test(value);
1042
1090
  },
1043
1091
 
1044
- // http://docs.jquery.com/Plugins/Validation/Methods/creditcard
1045
- // based on http://en.wikipedia.org/wiki/Luhn
1092
+ // http://jqueryvalidation.org/creditcard-method/
1093
+ // based on http://en.wikipedia.org/wiki/Luhn/
1046
1094
  creditcard: function( value, element ) {
1047
1095
  if ( this.optional(element) ) {
1048
1096
  return "dependency-mismatch";
@@ -1053,12 +1101,19 @@ $.extend($.validator, {
1053
1101
  }
1054
1102
  var nCheck = 0,
1055
1103
  nDigit = 0,
1056
- bEven = false;
1104
+ bEven = false,
1105
+ n, cDigit;
1057
1106
 
1058
1107
  value = value.replace(/\D/g, "");
1059
1108
 
1060
- for (var n = value.length - 1; n >= 0; n--) {
1061
- var cDigit = value.charAt(n);
1109
+ // Basing min and max length on
1110
+ // http://developer.ean.com/general_info/Valid_Credit_Card_Types
1111
+ if ( value.length < 13 || value.length > 19 ) {
1112
+ return false;
1113
+ }
1114
+
1115
+ for ( n = value.length - 1; n >= 0; n--) {
1116
+ cDigit = value.charAt(n);
1062
1117
  nDigit = parseInt(cDigit, 10);
1063
1118
  if ( bEven ) {
1064
1119
  if ( (nDigit *= 2) > 9 ) {
@@ -1072,40 +1127,40 @@ $.extend($.validator, {
1072
1127
  return (nCheck % 10) === 0;
1073
1128
  },
1074
1129
 
1075
- // http://docs.jquery.com/Plugins/Validation/Methods/minlength
1130
+ // http://jqueryvalidation.org/minlength-method/
1076
1131
  minlength: function( value, element, param ) {
1077
1132
  var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element);
1078
1133
  return this.optional(element) || length >= param;
1079
1134
  },
1080
1135
 
1081
- // http://docs.jquery.com/Plugins/Validation/Methods/maxlength
1136
+ // http://jqueryvalidation.org/maxlength-method/
1082
1137
  maxlength: function( value, element, param ) {
1083
1138
  var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element);
1084
1139
  return this.optional(element) || length <= param;
1085
1140
  },
1086
1141
 
1087
- // http://docs.jquery.com/Plugins/Validation/Methods/rangelength
1142
+ // http://jqueryvalidation.org/rangelength-method/
1088
1143
  rangelength: function( value, element, param ) {
1089
1144
  var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element);
1090
1145
  return this.optional(element) || ( length >= param[0] && length <= param[1] );
1091
1146
  },
1092
1147
 
1093
- // http://docs.jquery.com/Plugins/Validation/Methods/min
1148
+ // http://jqueryvalidation.org/min-method/
1094
1149
  min: function( value, element, param ) {
1095
1150
  return this.optional(element) || value >= param;
1096
1151
  },
1097
1152
 
1098
- // http://docs.jquery.com/Plugins/Validation/Methods/max
1153
+ // http://jqueryvalidation.org/max-method/
1099
1154
  max: function( value, element, param ) {
1100
1155
  return this.optional(element) || value <= param;
1101
1156
  },
1102
1157
 
1103
- // http://docs.jquery.com/Plugins/Validation/Methods/range
1158
+ // http://jqueryvalidation.org/range-method/
1104
1159
  range: function( value, element, param ) {
1105
1160
  return this.optional(element) || ( value >= param[0] && value <= param[1] );
1106
1161
  },
1107
1162
 
1108
- // http://docs.jquery.com/Plugins/Validation/Methods/equalTo
1163
+ // http://jqueryvalidation.org/equalTo-method/
1109
1164
  equalTo: function( value, element, param ) {
1110
1165
  // bind to the blur event of the target in order to revalidate whenever the target field is updated
1111
1166
  // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead
@@ -1118,29 +1173,31 @@ $.extend($.validator, {
1118
1173
  return value === target.val();
1119
1174
  },
1120
1175
 
1121
- // http://docs.jquery.com/Plugins/Validation/Methods/remote
1176
+ // http://jqueryvalidation.org/remote-method/
1122
1177
  remote: function( value, element, param ) {
1123
1178
  if ( this.optional(element) ) {
1124
1179
  return "dependency-mismatch";
1125
1180
  }
1126
1181
 
1127
- var previous = this.previousValue(element);
1182
+ var previous = this.previousValue(element),
1183
+ validator, data;
1184
+
1128
1185
  if (!this.settings.messages[element.name] ) {
1129
1186
  this.settings.messages[element.name] = {};
1130
1187
  }
1131
1188
  previous.originalMessage = this.settings.messages[element.name].remote;
1132
1189
  this.settings.messages[element.name].remote = previous.message;
1133
1190
 
1134
- param = typeof param === "string" && {url:param} || param;
1191
+ param = typeof param === "string" && { url: param } || param;
1135
1192
 
1136
1193
  if ( previous.old === value ) {
1137
1194
  return previous.valid;
1138
1195
  }
1139
1196
 
1140
1197
  previous.old = value;
1141
- var validator = this;
1198
+ validator = this;
1142
1199
  this.startRequest(element);
1143
- var data = {};
1200
+ data = {};
1144
1201
  data[element.name] = value;
1145
1202
  $.ajax($.extend(true, {
1146
1203
  url: param,
@@ -1148,19 +1205,22 @@ $.extend($.validator, {
1148
1205
  port: "validate" + element.name,
1149
1206
  dataType: "json",
1150
1207
  data: data,
1208
+ context: validator.currentForm,
1151
1209
  success: function( response ) {
1210
+ var valid = response === true || response === "true",
1211
+ errors, message, submitted;
1212
+
1152
1213
  validator.settings.messages[element.name].remote = previous.originalMessage;
1153
- var valid = response === true || response === "true";
1154
1214
  if ( valid ) {
1155
- var submitted = validator.formSubmitted;
1215
+ submitted = validator.formSubmitted;
1156
1216
  validator.prepareElement(element);
1157
1217
  validator.formSubmitted = submitted;
1158
1218
  validator.successList.push(element);
1159
1219
  delete validator.invalid[element.name];
1160
1220
  validator.showErrors();
1161
1221
  } else {
1162
- var errors = {};
1163
- var message = response || validator.defaultMessage( element, "remote" );
1222
+ errors = {};
1223
+ message = response || validator.defaultMessage( element, "remote" );
1164
1224
  errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message;
1165
1225
  validator.invalid[element.name] = true;
1166
1226
  validator.showErrors(errors);
@@ -1176,8 +1236,9 @@ $.extend($.validator, {
1176
1236
 
1177
1237
  });
1178
1238
 
1179
- // deprecated, use $.validator.format instead
1180
- $.format = $.validator.format;
1239
+ $.format = function deprecated() {
1240
+ throw "$.format has been deprecated. Please use $.validator.format instead.";
1241
+ };
1181
1242
 
1182
1243
  }(jQuery));
1183
1244
 
@@ -1185,7 +1246,8 @@ $.format = $.validator.format;
1185
1246
  // usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
1186
1247
  // if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
1187
1248
  (function($) {
1188
- var pendingRequests = {};
1249
+ var pendingRequests = {},
1250
+ ajax;
1189
1251
  // Use a prefilter if available (1.5+)
1190
1252
  if ( $.ajaxPrefilter ) {
1191
1253
  $.ajaxPrefilter(function( settings, _, xhr ) {
@@ -1199,7 +1261,7 @@ $.format = $.validator.format;
1199
1261
  });
1200
1262
  } else {
1201
1263
  // Proxy ajax
1202
- var ajax = $.ajax;
1264
+ ajax = $.ajax;
1203
1265
  $.ajax = function( settings ) {
1204
1266
  var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
1205
1267
  port = ( "port" in settings ? settings : $.ajaxSettings ).port;