kuppayam 0.1.34 → 0.1.35

Sign up to get free protection for your applications and to get access to all the features.
Files changed (177) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/favicon.png +0 -0
  3. data/app/assets/javascripts/{jquery_with_ujs.js → jquery_and_family.js} +3 -2
  4. data/app/assets/javascripts/kuppayam.js +13 -0
  5. data/app/assets/javascripts/kuppayam/utilities.js +3 -3
  6. data/app/assets/stylesheets/jquery_and_family.css +14 -0
  7. data/app/assets/stylesheets/kuppayam/custom.css +73 -0
  8. data/app/helpers/kuppayam_helper.rb +6 -2
  9. data/app/helpers/render_helper.rb +6 -2
  10. data/app/helpers/resource_helper.rb +44 -5
  11. data/app/helpers/resource_view_helper.rb +123 -35
  12. data/app/models/concerns/publishable.rb +1 -0
  13. data/app/models/image/base.rb +3 -3
  14. data/app/views/kuppayam/images/_multiple_images.html.erb +6 -4
  15. data/app/views/kuppayam/workflows/default/create.js.erb +81 -0
  16. data/app/views/kuppayam/workflows/default/destroy.js.erb +32 -0
  17. data/app/views/kuppayam/workflows/default/edit.js.erb +21 -0
  18. data/app/views/kuppayam/workflows/default/index.js.erb +43 -0
  19. data/app/views/kuppayam/workflows/default/new.js.erb +21 -0
  20. data/app/views/kuppayam/workflows/default/row.js.erb +50 -0
  21. data/app/views/kuppayam/workflows/default/show.js.erb +17 -0
  22. data/app/views/kuppayam/workflows/default/update.js.erb +73 -0
  23. data/app/views/kuppayam/workflows/parrot/create.js.erb +8 -1
  24. data/app/views/kuppayam/workflows/parrot/index.js.erb +9 -1
  25. data/app/views/kuppayam/workflows/parrot/new.js.erb +1 -1
  26. data/app/views/kuppayam/workflows/parrot/row.js.erb +8 -1
  27. data/app/views/kuppayam/workflows/parrot/update.js.erb +8 -1
  28. data/app/views/kuppayam/workflows/peacock/create.js.erb +8 -1
  29. data/app/views/kuppayam/workflows/peacock/index.js.erb +9 -1
  30. data/app/views/kuppayam/workflows/peacock/row.js.erb +8 -1
  31. data/app/views/kuppayam/workflows/peacock/update.js.erb +8 -1
  32. data/app/views/layouts/dashboard/_items.html.erb +1 -1
  33. data/app/views/layouts/kuppayam/_head.html.erb +2 -2
  34. data/app/views/layouts/kuppayam/_sidebar.html.erb +1 -1
  35. data/app/views/layouts/kuppayam/admin.html.erb +1 -1
  36. data/app/views/layouts/kuppayam/document_upload.html.erb +1 -1
  37. data/app/views/layouts/kuppayam/image_upload.html.erb +1 -1
  38. data/lib/generators/kuppayam/templates/views/_index.html.erb +1 -1
  39. data/lib/generators/kuppayam/templates/views/_row.html.erb +1 -1
  40. data/lib/kuppayam/engine.rb +1 -1
  41. data/lib/kuppayam/version.rb +1 -1
  42. data/vendor/assets/jquery-ui/AUTHORS.txt +333 -0
  43. data/vendor/assets/jquery-ui/LICENSE.txt +43 -0
  44. data/vendor/assets/jquery-ui/external/jquery/jquery.js +11008 -0
  45. data/vendor/assets/jquery-ui/images/ui-icons_444444_256x240.png +0 -0
  46. data/vendor/assets/jquery-ui/images/ui-icons_555555_256x240.png +0 -0
  47. data/vendor/assets/jquery-ui/images/ui-icons_777620_256x240.png +0 -0
  48. data/vendor/assets/jquery-ui/images/ui-icons_777777_256x240.png +0 -0
  49. data/vendor/assets/jquery-ui/images/ui-icons_cc0000_256x240.png +0 -0
  50. data/vendor/assets/jquery-ui/images/ui-icons_ffffff_256x240.png +0 -0
  51. data/vendor/assets/jquery-ui/index.html +559 -0
  52. data/vendor/assets/jquery-ui/jquery-ui.css +1312 -0
  53. data/vendor/assets/jquery-ui/jquery-ui.js +18706 -0
  54. data/vendor/assets/jquery-ui/jquery-ui.min.css +7 -0
  55. data/vendor/assets/jquery-ui/jquery-ui.min.js +13 -0
  56. data/vendor/assets/jquery-ui/jquery-ui.structure.css +886 -0
  57. data/vendor/assets/jquery-ui/jquery-ui.structure.min.css +5 -0
  58. data/vendor/assets/jquery-ui/jquery-ui.theme.css +443 -0
  59. data/vendor/assets/jquery-ui/jquery-ui.theme.min.css +5 -0
  60. data/vendor/assets/jquery-ui/package.json +74 -0
  61. data/vendor/assets/jquery-validation/additional-methods.js +1158 -0
  62. data/vendor/assets/jquery-validation/additional-methods.min.js +8 -0
  63. data/vendor/assets/{javascripts/jquery-validate → jquery-validation}/jquery.validate.js +615 -371
  64. data/vendor/assets/jquery-validation/jquery.validate.min.js +4 -0
  65. data/vendor/assets/jquery/jquery-3.2.1.min.js +4 -0
  66. data/vendor/assets/stylesheets/xenon-core.css +16 -16
  67. metadata +45 -122
  68. data/vendor/assets/javascripts/jquery-validate/additional-methods.js +0 -928
  69. data/vendor/assets/javascripts/jquery-validate/additional-methods.min.js +0 -4
  70. data/vendor/assets/javascripts/jquery-validate/index.html +0 -0
  71. data/vendor/assets/javascripts/jquery-validate/jquery.validate.min.js +0 -4
  72. data/vendor/assets/javascripts/jquery-validate/localization/messages_ar.js +0 -33
  73. data/vendor/assets/javascripts/jquery-validate/localization/messages_ar.min.js +0 -4
  74. data/vendor/assets/javascripts/jquery-validate/localization/messages_bg.js +0 -33
  75. data/vendor/assets/javascripts/jquery-validate/localization/messages_bg.min.js +0 -4
  76. data/vendor/assets/javascripts/jquery-validate/localization/messages_ca.js +0 -33
  77. data/vendor/assets/javascripts/jquery-validate/localization/messages_ca.min.js +0 -4
  78. data/vendor/assets/javascripts/jquery-validate/localization/messages_cs.js +0 -33
  79. data/vendor/assets/javascripts/jquery-validate/localization/messages_cs.min.js +0 -4
  80. data/vendor/assets/javascripts/jquery-validate/localization/messages_da.js +0 -30
  81. data/vendor/assets/javascripts/jquery-validate/localization/messages_da.min.js +0 -4
  82. data/vendor/assets/javascripts/jquery-validate/localization/messages_de.js +0 -30
  83. data/vendor/assets/javascripts/jquery-validate/localization/messages_de.min.js +0 -4
  84. data/vendor/assets/javascripts/jquery-validate/localization/messages_el.js +0 -33
  85. data/vendor/assets/javascripts/jquery-validate/localization/messages_el.min.js +0 -4
  86. data/vendor/assets/javascripts/jquery-validate/localization/messages_es.js +0 -36
  87. data/vendor/assets/javascripts/jquery-validate/localization/messages_es.min.js +0 -4
  88. data/vendor/assets/javascripts/jquery-validate/localization/messages_es_AR.js +0 -37
  89. data/vendor/assets/javascripts/jquery-validate/localization/messages_es_AR.min.js +0 -4
  90. data/vendor/assets/javascripts/jquery-validate/localization/messages_et.js +0 -31
  91. data/vendor/assets/javascripts/jquery-validate/localization/messages_et.min.js +0 -4
  92. data/vendor/assets/javascripts/jquery-validate/localization/messages_eu.js +0 -33
  93. data/vendor/assets/javascripts/jquery-validate/localization/messages_eu.min.js +0 -4
  94. data/vendor/assets/javascripts/jquery-validate/localization/messages_fa.js +0 -36
  95. data/vendor/assets/javascripts/jquery-validate/localization/messages_fa.min.js +0 -4
  96. data/vendor/assets/javascripts/jquery-validate/localization/messages_fi.js +0 -31
  97. data/vendor/assets/javascripts/jquery-validate/localization/messages_fi.min.js +0 -4
  98. data/vendor/assets/javascripts/jquery-validate/localization/messages_fr.js +0 -59
  99. data/vendor/assets/javascripts/jquery-validate/localization/messages_fr.min.js +0 -4
  100. data/vendor/assets/javascripts/jquery-validate/localization/messages_gl.js +0 -38
  101. data/vendor/assets/javascripts/jquery-validate/localization/messages_gl.min.js +0 -4
  102. data/vendor/assets/javascripts/jquery-validate/localization/messages_he.js +0 -33
  103. data/vendor/assets/javascripts/jquery-validate/localization/messages_he.min.js +0 -4
  104. data/vendor/assets/javascripts/jquery-validate/localization/messages_hr.js +0 -33
  105. data/vendor/assets/javascripts/jquery-validate/localization/messages_hr.min.js +0 -4
  106. data/vendor/assets/javascripts/jquery-validate/localization/messages_hu.js +0 -32
  107. data/vendor/assets/javascripts/jquery-validate/localization/messages_hu.min.js +0 -4
  108. data/vendor/assets/javascripts/jquery-validate/localization/messages_id.js +0 -32
  109. data/vendor/assets/javascripts/jquery-validate/localization/messages_id.min.js +0 -4
  110. data/vendor/assets/javascripts/jquery-validate/localization/messages_is.js +0 -31
  111. data/vendor/assets/javascripts/jquery-validate/localization/messages_is.min.js +0 -4
  112. data/vendor/assets/javascripts/jquery-validate/localization/messages_it.js +0 -36
  113. data/vendor/assets/javascripts/jquery-validate/localization/messages_it.min.js +0 -4
  114. data/vendor/assets/javascripts/jquery-validate/localization/messages_ja.js +0 -33
  115. data/vendor/assets/javascripts/jquery-validate/localization/messages_ja.min.js +0 -4
  116. data/vendor/assets/javascripts/jquery-validate/localization/messages_ka.js +0 -33
  117. data/vendor/assets/javascripts/jquery-validate/localization/messages_ka.min.js +0 -4
  118. data/vendor/assets/javascripts/jquery-validate/localization/messages_kk.js +0 -33
  119. data/vendor/assets/javascripts/jquery-validate/localization/messages_kk.min.js +0 -4
  120. data/vendor/assets/javascripts/jquery-validate/localization/messages_ko.js +0 -33
  121. data/vendor/assets/javascripts/jquery-validate/localization/messages_ko.min.js +0 -4
  122. data/vendor/assets/javascripts/jquery-validate/localization/messages_lt.js +0 -33
  123. data/vendor/assets/javascripts/jquery-validate/localization/messages_lt.min.js +0 -4
  124. data/vendor/assets/javascripts/jquery-validate/localization/messages_lv.js +0 -33
  125. data/vendor/assets/javascripts/jquery-validate/localization/messages_lv.min.js +0 -4
  126. data/vendor/assets/javascripts/jquery-validate/localization/messages_my.js +0 -33
  127. data/vendor/assets/javascripts/jquery-validate/localization/messages_my.min.js +0 -4
  128. data/vendor/assets/javascripts/jquery-validate/localization/messages_nl.js +0 -43
  129. data/vendor/assets/javascripts/jquery-validate/localization/messages_nl.min.js +0 -4
  130. data/vendor/assets/javascripts/jquery-validate/localization/messages_no.js +0 -33
  131. data/vendor/assets/javascripts/jquery-validate/localization/messages_no.min.js +0 -4
  132. data/vendor/assets/javascripts/jquery-validate/localization/messages_pl.js +0 -33
  133. data/vendor/assets/javascripts/jquery-validate/localization/messages_pl.min.js +0 -4
  134. data/vendor/assets/javascripts/jquery-validate/localization/messages_pt_BR.js +0 -37
  135. data/vendor/assets/javascripts/jquery-validate/localization/messages_pt_BR.min.js +0 -4
  136. data/vendor/assets/javascripts/jquery-validate/localization/messages_pt_PT.js +0 -37
  137. data/vendor/assets/javascripts/jquery-validate/localization/messages_pt_PT.min.js +0 -4
  138. data/vendor/assets/javascripts/jquery-validate/localization/messages_ro.js +0 -33
  139. data/vendor/assets/javascripts/jquery-validate/localization/messages_ro.min.js +0 -4
  140. data/vendor/assets/javascripts/jquery-validate/localization/messages_ru.js +0 -33
  141. data/vendor/assets/javascripts/jquery-validate/localization/messages_ru.min.js +0 -4
  142. data/vendor/assets/javascripts/jquery-validate/localization/messages_si.js +0 -33
  143. data/vendor/assets/javascripts/jquery-validate/localization/messages_si.min.js +0 -4
  144. data/vendor/assets/javascripts/jquery-validate/localization/messages_sk.js +0 -30
  145. data/vendor/assets/javascripts/jquery-validate/localization/messages_sk.min.js +0 -4
  146. data/vendor/assets/javascripts/jquery-validate/localization/messages_sl.js +0 -33
  147. data/vendor/assets/javascripts/jquery-validate/localization/messages_sl.min.js +0 -4
  148. data/vendor/assets/javascripts/jquery-validate/localization/messages_sr.js +0 -33
  149. data/vendor/assets/javascripts/jquery-validate/localization/messages_sr.min.js +0 -4
  150. data/vendor/assets/javascripts/jquery-validate/localization/messages_sr_lat.js +0 -33
  151. data/vendor/assets/javascripts/jquery-validate/localization/messages_sr_lat.min.js +0 -4
  152. data/vendor/assets/javascripts/jquery-validate/localization/messages_sv.js +0 -31
  153. data/vendor/assets/javascripts/jquery-validate/localization/messages_sv.min.js +0 -4
  154. data/vendor/assets/javascripts/jquery-validate/localization/messages_th.js +0 -33
  155. data/vendor/assets/javascripts/jquery-validate/localization/messages_th.min.js +0 -4
  156. data/vendor/assets/javascripts/jquery-validate/localization/messages_tj.js +0 -33
  157. data/vendor/assets/javascripts/jquery-validate/localization/messages_tj.min.js +0 -4
  158. data/vendor/assets/javascripts/jquery-validate/localization/messages_tr.js +0 -33
  159. data/vendor/assets/javascripts/jquery-validate/localization/messages_tr.min.js +0 -4
  160. data/vendor/assets/javascripts/jquery-validate/localization/messages_uk.js +0 -33
  161. data/vendor/assets/javascripts/jquery-validate/localization/messages_uk.min.js +0 -4
  162. data/vendor/assets/javascripts/jquery-validate/localization/messages_vi.js +0 -33
  163. data/vendor/assets/javascripts/jquery-validate/localization/messages_vi.min.js +0 -4
  164. data/vendor/assets/javascripts/jquery-validate/localization/messages_zh.js +0 -33
  165. data/vendor/assets/javascripts/jquery-validate/localization/messages_zh.min.js +0 -4
  166. data/vendor/assets/javascripts/jquery-validate/localization/messages_zh_TW.js +0 -34
  167. data/vendor/assets/javascripts/jquery-validate/localization/messages_zh_TW.min.js +0 -4
  168. data/vendor/assets/javascripts/jquery-validate/localization/methods_de.js +0 -22
  169. data/vendor/assets/javascripts/jquery-validate/localization/methods_de.min.js +0 -4
  170. data/vendor/assets/javascripts/jquery-validate/localization/methods_es_CL.js +0 -22
  171. data/vendor/assets/javascripts/jquery-validate/localization/methods_es_CL.min.js +0 -4
  172. data/vendor/assets/javascripts/jquery-validate/localization/methods_fi.js +0 -22
  173. data/vendor/assets/javascripts/jquery-validate/localization/methods_fi.min.js +0 -4
  174. data/vendor/assets/javascripts/jquery-validate/localization/methods_nl.js +0 -19
  175. data/vendor/assets/javascripts/jquery-validate/localization/methods_nl.min.js +0 -4
  176. data/vendor/assets/javascripts/jquery-validate/localization/methods_pt.js +0 -19
  177. data/vendor/assets/javascripts/jquery-validate/localization/methods_pt.min.js +0 -4
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Minified by jsDelivr using UglifyJS v3.0.24.
3
+ * Original file: /npm/jquery-validation@1.17.0/dist/additional-methods.js
4
+ *
5
+ * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
6
+ */
7
+ !function(t){"function"==typeof define&&define.amd?define(["jquery","./jquery.validate"],t):"object"==typeof module&&module.exports?module.exports=t(require("jquery")):t(jQuery)}(function(t){return function(){function e(t){return t.replace(/<.[^<>]*?>/g," ").replace(/&nbsp;|&#160;/gi," ").replace(/[.(),;:!?%#$'\"_+=\/\-“”’]*/g,"")}t.validator.addMethod("maxWords",function(t,a,d){return this.optional(a)||e(t).match(/\b\w+\b/g).length<=d},t.validator.format("Please enter {0} words or less.")),t.validator.addMethod("minWords",function(t,a,d){return this.optional(a)||e(t).match(/\b\w+\b/g).length>=d},t.validator.format("Please enter at least {0} words.")),t.validator.addMethod("rangeWords",function(t,a,d){var i=e(t),n=/\b\w+\b/g;return this.optional(a)||i.match(n).length>=d[0]&&i.match(n).length<=d[1]},t.validator.format("Please enter between {0} and {1} words."))}(),t.validator.addMethod("accept",function(e,a,d){var i,n,r="string"==typeof d?d.replace(/\s/g,""):"image/*",o=this.optional(a);if(o)return o;if("file"===t(a).attr("type")&&(r=r.replace(/[\-\[\]\/\{\}\(\)\+\?\.\\\^\$\|]/g,"\\$&").replace(/,/g,"|").replace(/\/\*/g,"/.*"),a.files&&a.files.length))for(n=new RegExp(".?("+r+")$","i"),i=0;i<a.files.length;i++)if(!a.files[i].type.match(n))return!1;return!0},t.validator.format("Please enter a value with a valid mimetype.")),t.validator.addMethod("alphanumeric",function(t,e){return this.optional(e)||/^\w+$/i.test(t)},"Letters, numbers, and underscores only please"),t.validator.addMethod("bankaccountNL",function(t,e){if(this.optional(e))return!0;if(!/^[0-9]{9}|([0-9]{2} ){3}[0-9]{3}$/.test(t))return!1;var a,d=t.replace(/ /g,""),i=0,n=d.length;for(a=0;a<n;a++)i+=(n-a)*d.substring(a,a+1);return i%11==0},"Please specify a valid bank account number"),t.validator.addMethod("bankorgiroaccountNL",function(e,a){return this.optional(a)||t.validator.methods.bankaccountNL.call(this,e,a)||t.validator.methods.giroaccountNL.call(this,e,a)},"Please specify a valid bank or giro account number"),t.validator.addMethod("bic",function(t,e){return this.optional(e)||/^([A-Z]{6}[A-Z2-9][A-NP-Z1-9])(X{3}|[A-WY-Z0-9][A-Z0-9]{2})?$/.test(t.toUpperCase())},"Please specify a valid BIC code"),t.validator.addMethod("cifES",function(t,e){"use strict";if(this.optional(e))return!0;var a,d,i,n,r=new RegExp(/^([ABCDEFGHJKLMNPQRSUVW])(\d{7})([0-9A-J])$/gi),o=t.substring(0,1),s=t.substring(1,8),l=t.substring(8,9),u=0,c=0,h=0;if(9!==t.length||!r.test(t))return!1;for(a=0;a<s.length;a++)d=parseInt(s[a],10),!function(t){return t%2==0}(a)?c+=d:h+=(d*=2)<10?d:d-9;return u=c+h,i=(10-u.toString().substr(-1)).toString(),i=parseInt(i,10)>9?"0":i,n="JABCDEFGHI".substr(i,1).toString(),o.match(/[ABEH]/)?l===i:o.match(/[KPQS]/)?l===n:l===i||l===n},"Please specify a valid CIF number."),t.validator.addMethod("cpfBR",function(t){if(11!==(t=t.replace(/([~!@#$%^&*()_+=`{}\[\]\-|\\:;'<>,.\/? ])+/g,"")).length)return!1;var e,a,d,i,n=0;if(e=parseInt(t.substring(9,10),10),a=parseInt(t.substring(10,11),10),d=function(t,e){var a=10*t%11;return 10!==a&&11!==a||(a=0),a===e},""===t||"00000000000"===t||"11111111111"===t||"22222222222"===t||"33333333333"===t||"44444444444"===t||"55555555555"===t||"66666666666"===t||"77777777777"===t||"88888888888"===t||"99999999999"===t)return!1;for(i=1;i<=9;i++)n+=parseInt(t.substring(i-1,i),10)*(11-i);if(d(n,e)){for(n=0,i=1;i<=10;i++)n+=parseInt(t.substring(i-1,i),10)*(12-i);return d(n,a)}return!1},"Please specify a valid CPF number"),t.validator.addMethod("creditcard",function(t,e){if(this.optional(e))return"dependency-mismatch";if(/[^0-9 \-]+/.test(t))return!1;var a,d,i=0,n=0,r=!1;if((t=t.replace(/\D/g,"")).length<13||t.length>19)return!1;for(a=t.length-1;a>=0;a--)d=t.charAt(a),n=parseInt(d,10),r&&(n*=2)>9&&(n-=9),i+=n,r=!r;return i%10==0},"Please enter a valid credit card number."),t.validator.addMethod("creditcardtypes",function(t,e,a){if(/[^0-9\-]+/.test(t))return!1;t=t.replace(/\D/g,"");var d=0;return a.mastercard&&(d|=1),a.visa&&(d|=2),a.amex&&(d|=4),a.dinersclub&&(d|=8),a.enroute&&(d|=16),a.discover&&(d|=32),a.jcb&&(d|=64),a.unknown&&(d|=128),a.all&&(d=255),1&d&&/^(5[12345])/.test(t)?16===t.length:2&d&&/^(4)/.test(t)?16===t.length:4&d&&/^(3[47])/.test(t)?15===t.length:8&d&&/^(3(0[012345]|[68]))/.test(t)?14===t.length:16&d&&/^(2(014|149))/.test(t)?15===t.length:32&d&&/^(6011)/.test(t)?16===t.length:64&d&&/^(3)/.test(t)?16===t.length:64&d&&/^(2131|1800)/.test(t)?15===t.length:!!(128&d)},"Please enter a valid credit card number."),t.validator.addMethod("currency",function(t,e,a){var d,i="string"==typeof a,n=i?a:a[0],r=!!i||a[1];return n=n.replace(/,/g,""),n=r?n+"]":n+"]?",d="^["+n+"([1-9]{1}[0-9]{0,2}(\\,[0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)$",d=new RegExp(d),this.optional(e)||d.test(t)},"Please specify a valid currency"),t.validator.addMethod("dateFA",function(t,e){return this.optional(e)||/^[1-4]\d{3}\/((0?[1-6]\/((3[0-1])|([1-2][0-9])|(0?[1-9])))|((1[0-2]|(0?[7-9]))\/(30|([1-2][0-9])|(0?[1-9]))))$/.test(t)},t.validator.messages.date),t.validator.addMethod("dateITA",function(t,e){var a,d,i,n,r,o=!1;return/^\d{1,2}\/\d{1,2}\/\d{4}$/.test(t)?(a=t.split("/"),d=parseInt(a[0],10),i=parseInt(a[1],10),n=parseInt(a[2],10),o=(r=new Date(Date.UTC(n,i-1,d,12,0,0,0))).getUTCFullYear()===n&&r.getUTCMonth()===i-1&&r.getUTCDate()===d):o=!1,this.optional(e)||o},t.validator.messages.date),t.validator.addMethod("dateNL",function(t,e){return this.optional(e)||/^(0?[1-9]|[12]\d|3[01])[\.\/\-](0?[1-9]|1[012])[\.\/\-]([12]\d)?(\d\d)$/.test(t)},t.validator.messages.date),t.validator.addMethod("extension",function(t,e,a){return a="string"==typeof a?a.replace(/,/g,"|"):"png|jpe?g|gif",this.optional(e)||t.match(new RegExp("\\.("+a+")$","i"))},t.validator.format("Please enter a value with a valid extension.")),t.validator.addMethod("giroaccountNL",function(t,e){return this.optional(e)||/^[0-9]{1,7}$/.test(t)},"Please specify a valid giro account number"),t.validator.addMethod("iban",function(t,e){if(this.optional(e))return!0;var a,d,i,n,r,o,s,l=t.replace(/ /g,"").toUpperCase(),u="",c=!0,h="";if(l.length<5)return!1;if(a=l.substring(0,2),r={AL:"\\d{8}[\\dA-Z]{16}",AD:"\\d{8}[\\dA-Z]{12}",AT:"\\d{16}",AZ:"[\\dA-Z]{4}\\d{20}",BE:"\\d{12}",BH:"[A-Z]{4}[\\dA-Z]{14}",BA:"\\d{16}",BR:"\\d{23}[A-Z][\\dA-Z]",BG:"[A-Z]{4}\\d{6}[\\dA-Z]{8}",CR:"\\d{17}",HR:"\\d{17}",CY:"\\d{8}[\\dA-Z]{16}",CZ:"\\d{20}",DK:"\\d{14}",DO:"[A-Z]{4}\\d{20}",EE:"\\d{16}",FO:"\\d{14}",FI:"\\d{14}",FR:"\\d{10}[\\dA-Z]{11}\\d{2}",GE:"[\\dA-Z]{2}\\d{16}",DE:"\\d{18}",GI:"[A-Z]{4}[\\dA-Z]{15}",GR:"\\d{7}[\\dA-Z]{16}",GL:"\\d{14}",GT:"[\\dA-Z]{4}[\\dA-Z]{20}",HU:"\\d{24}",IS:"\\d{22}",IE:"[\\dA-Z]{4}\\d{14}",IL:"\\d{19}",IT:"[A-Z]\\d{10}[\\dA-Z]{12}",KZ:"\\d{3}[\\dA-Z]{13}",KW:"[A-Z]{4}[\\dA-Z]{22}",LV:"[A-Z]{4}[\\dA-Z]{13}",LB:"\\d{4}[\\dA-Z]{20}",LI:"\\d{5}[\\dA-Z]{12}",LT:"\\d{16}",LU:"\\d{3}[\\dA-Z]{13}",MK:"\\d{3}[\\dA-Z]{10}\\d{2}",MT:"[A-Z]{4}\\d{5}[\\dA-Z]{18}",MR:"\\d{23}",MU:"[A-Z]{4}\\d{19}[A-Z]{3}",MC:"\\d{10}[\\dA-Z]{11}\\d{2}",MD:"[\\dA-Z]{2}\\d{18}",ME:"\\d{18}",NL:"[A-Z]{4}\\d{10}",NO:"\\d{11}",PK:"[\\dA-Z]{4}\\d{16}",PS:"[\\dA-Z]{4}\\d{21}",PL:"\\d{24}",PT:"\\d{21}",RO:"[A-Z]{4}[\\dA-Z]{16}",SM:"[A-Z]\\d{10}[\\dA-Z]{12}",SA:"\\d{2}[\\dA-Z]{18}",RS:"\\d{18}",SK:"\\d{20}",SI:"\\d{15}",ES:"\\d{20}",SE:"\\d{20}",CH:"\\d{5}[\\dA-Z]{12}",TN:"\\d{20}",TR:"\\d{5}[\\dA-Z]{17}",AE:"\\d{3}\\d{16}",GB:"[A-Z]{4}\\d{14}",VG:"[\\dA-Z]{4}\\d{16}"},void 0!==(n=r[a])&&!new RegExp("^[A-Z]{2}\\d{2}"+n+"$","").test(l))return!1;for(d=l.substring(4,l.length)+l.substring(0,4),o=0;o<d.length;o++)"0"!==(i=d.charAt(o))&&(c=!1),c||(u+="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".indexOf(i));for(s=0;s<u.length;s++)h=(""+h+u.charAt(s))%97;return 1===h},"Please specify a valid IBAN"),t.validator.addMethod("integer",function(t,e){return this.optional(e)||/^-?\d+$/.test(t)},"A positive or negative non-decimal number please"),t.validator.addMethod("ipv4",function(t,e){return this.optional(e)||/^(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)$/i.test(t)},"Please enter a valid IP v4 address."),t.validator.addMethod("ipv6",function(t,e){return this.optional(e)||/^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test(t)},"Please enter a valid IP v6 address."),t.validator.addMethod("lettersonly",function(t,e){return this.optional(e)||/^[a-z]+$/i.test(t)},"Letters only please"),t.validator.addMethod("letterswithbasicpunc",function(t,e){return this.optional(e)||/^[a-z\-.,()'"\s]+$/i.test(t)},"Letters or punctuation only please"),t.validator.addMethod("mobileNL",function(t,e){return this.optional(e)||/^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)6((\s|\s?\-\s?)?[0-9]){8}$/.test(t)},"Please specify a valid mobile number"),t.validator.addMethod("mobileUK",function(t,e){return t=t.replace(/\(|\)|\s+|-/g,""),this.optional(e)||t.length>9&&t.match(/^(?:(?:(?:00\s?|\+)44\s?|0)7(?:[1345789]\d{2}|624)\s?\d{3}\s?\d{3})$/)},"Please specify a valid mobile number"),t.validator.addMethod("netmask",function(t,e){return this.optional(e)||/^(254|252|248|240|224|192|128)\.0\.0\.0|255\.(254|252|248|240|224|192|128|0)\.0\.0|255\.255\.(254|252|248|240|224|192|128|0)\.0|255\.255\.255\.(254|252|248|240|224|192|128|0)/i.test(t)},"Please enter a valid netmask."),t.validator.addMethod("nieES",function(t,e){"use strict";if(this.optional(e))return!0;var a,d=new RegExp(/^[MXYZ]{1}[0-9]{7,8}[TRWAGMYFPDXBNJZSQVHLCKET]{1}$/gi),i=t.substr(t.length-1).toUpperCase();return!((t=t.toString().toUpperCase()).length>10||t.length<9||!d.test(t))&&(t=t.replace(/^[X]/,"0").replace(/^[Y]/,"1").replace(/^[Z]/,"2"),a=9===t.length?t.substr(0,8):t.substr(0,9),"TRWAGMYFPDXBNJZSQVHLCKET".charAt(parseInt(a,10)%23)===i)},"Please specify a valid NIE number."),t.validator.addMethod("nifES",function(t,e){"use strict";return!!this.optional(e)||!!(t=t.toUpperCase()).match("((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)")&&(/^[0-9]{8}[A-Z]{1}$/.test(t)?"TRWAGMYFPDXBNJZSQVHLCKE".charAt(t.substring(8,0)%23)===t.charAt(8):!!/^[KLM]{1}/.test(t)&&t[8]==="TRWAGMYFPDXBNJZSQVHLCKE".charAt(t.substring(8,1)%23))},"Please specify a valid NIF number."),t.validator.addMethod("nipPL",function(t){"use strict";if(10!==(t=t.replace(/[^0-9]/g,"")).length)return!1;for(var e=[6,5,7,2,3,4,5,6,7],a=0,d=0;d<9;d++)a+=e[d]*t[d];var i=a%11;return(10===i?0:i)===parseInt(t[9],10)},"Please specify a valid NIP number."),t.validator.addMethod("notEqualTo",function(e,a,d){return this.optional(a)||!t.validator.methods.equalTo.call(this,e,a,d)},"Please enter a different value, values must not be the same."),t.validator.addMethod("nowhitespace",function(t,e){return this.optional(e)||/^\S+$/i.test(t)},"No white space please"),t.validator.addMethod("pattern",function(t,e,a){return!!this.optional(e)||("string"==typeof a&&(a=new RegExp("^(?:"+a+")$")),a.test(t))},"Invalid format."),t.validator.addMethod("phoneNL",function(t,e){return this.optional(e)||/^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)[1-9]((\s|\s?\-\s?)?[0-9]){8}$/.test(t)},"Please specify a valid phone number."),t.validator.addMethod("phonesUK",function(t,e){return t=t.replace(/\(|\)|\s+|-/g,""),this.optional(e)||t.length>9&&t.match(/^(?:(?:(?:00\s?|\+)44\s?|0)(?:1\d{8,9}|[23]\d{9}|7(?:[1345789]\d{8}|624\d{6})))$/)},"Please specify a valid uk phone number"),t.validator.addMethod("phoneUK",function(t,e){return t=t.replace(/\(|\)|\s+|-/g,""),this.optional(e)||t.length>9&&t.match(/^(?:(?:(?:00\s?|\+)44\s?)|(?:\(?0))(?:\d{2}\)?\s?\d{4}\s?\d{4}|\d{3}\)?\s?\d{3}\s?\d{3,4}|\d{4}\)?\s?(?:\d{5}|\d{3}\s?\d{3})|\d{5}\)?\s?\d{4,5})$/)},"Please specify a valid phone number"),t.validator.addMethod("phoneUS",function(t,e){return t=t.replace(/\s+/g,""),this.optional(e)||t.length>9&&t.match(/^(\+?1-?)?(\([2-9]([02-9]\d|1[02-9])\)|[2-9]([02-9]\d|1[02-9]))-?[2-9]([02-9]\d|1[02-9])-?\d{4}$/)},"Please specify a valid phone number"),t.validator.addMethod("postalcodeBR",function(t,e){return this.optional(e)||/^\d{2}.\d{3}-\d{3}?$|^\d{5}-?\d{3}?$/.test(t)},"Informe um CEP válido."),t.validator.addMethod("postalCodeCA",function(t,e){return this.optional(e)||/^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ] *\d[ABCEGHJKLMNPRSTVWXYZ]\d$/i.test(t)},"Please specify a valid postal code"),t.validator.addMethod("postalcodeIT",function(t,e){return this.optional(e)||/^\d{5}$/.test(t)},"Please specify a valid postal code"),t.validator.addMethod("postalcodeNL",function(t,e){return this.optional(e)||/^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/.test(t)},"Please specify a valid postal code"),t.validator.addMethod("postcodeUK",function(t,e){return this.optional(e)||/^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))\s?([0-9][ABD-HJLNP-UW-Z]{2})|(GIR)\s?(0AA))$/i.test(t)},"Please specify a valid UK postcode"),t.validator.addMethod("require_from_group",function(e,a,d){var i=t(d[1],a.form),n=i.eq(0),r=n.data("valid_req_grp")?n.data("valid_req_grp"):t.extend({},this),o=i.filter(function(){return r.elementValue(this)}).length>=d[0];return n.data("valid_req_grp",r),t(a).data("being_validated")||(i.data("being_validated",!0),i.each(function(){r.element(this)}),i.data("being_validated",!1)),o},t.validator.format("Please fill at least {0} of these fields.")),t.validator.addMethod("skip_or_fill_minimum",function(e,a,d){var i=t(d[1],a.form),n=i.eq(0),r=n.data("valid_skip")?n.data("valid_skip"):t.extend({},this),o=i.filter(function(){return r.elementValue(this)}).length,s=0===o||o>=d[0];return n.data("valid_skip",r),t(a).data("being_validated")||(i.data("being_validated",!0),i.each(function(){r.element(this)}),i.data("being_validated",!1)),s},t.validator.format("Please either skip these fields or fill at least {0} of them.")),t.validator.addMethod("stateUS",function(t,e,a){var d,i=void 0===a,n=!i&&void 0!==a.caseSensitive&&a.caseSensitive,r=!i&&void 0!==a.includeTerritories&&a.includeTerritories,o=!i&&void 0!==a.includeMilitary&&a.includeMilitary;return d=r||o?r&&o?"^(A[AEKLPRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$":r?"^(A[KLRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$":"^(A[AEKLPRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$":"^(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$",d=n?new RegExp(d):new RegExp(d,"i"),this.optional(e)||d.test(t)},"Please specify a valid state"),t.validator.addMethod("strippedminlength",function(e,a,d){return t(e).text().length>=d},t.validator.format("Please enter at least {0} characters")),t.validator.addMethod("time",function(t,e){return this.optional(e)||/^([01]\d|2[0-3]|[0-9])(:[0-5]\d){1,2}$/.test(t)},"Please enter a valid time, between 00:00 and 23:59"),t.validator.addMethod("time12h",function(t,e){return this.optional(e)||/^((0?[1-9]|1[012])(:[0-5]\d){1,2}(\ ?[AP]M))$/i.test(t)},"Please enter a valid time in 12-hour am/pm format"),t.validator.addMethod("url2",function(t,e){return this.optional(e)||/^(https?|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(t)},t.validator.messages.url),t.validator.addMethod("vinUS",function(t){if(17!==t.length)return!1;var e,a,d,i,n,r,o=["A","B","C","D","E","F","G","H","J","K","L","M","N","P","R","S","T","U","V","W","X","Y","Z"],s=[1,2,3,4,5,6,7,8,1,2,3,4,5,7,9,2,3,4,5,6,7,8,9],l=[8,7,6,5,4,3,2,10,0,9,8,7,6,5,4,3,2],u=0;for(e=0;e<17;e++){if(i=l[e],d=t.slice(e,e+1),8===e&&(r=d),isNaN(d)){for(a=0;a<o.length;a++)if(d.toUpperCase()===o[a]){d=s[a],d*=i,isNaN(r)&&8===a&&(r=o[a]);break}}else d*=i;u+=d}return 10===(n=u%11)&&(n="X"),n===r},"The specified vehicle identification number (VIN) is invalid."),t.validator.addMethod("zipcodeUS",function(t,e){return this.optional(e)||/^\d{5}(-\d{4})?$/.test(t)},"The specified US ZIP Code is invalid"),t.validator.addMethod("ziprange",function(t,e){return this.optional(e)||/^90[2-5]\d\{2\}-\d{4}$/.test(t)},"Your ZIP-code must be in the range 902xx-xxxx to 905xx-xxxx"),t});
8
+ //# sourceMappingURL=/sm/3da7bc48b8583d62db3b65cfac5b7f5ab4b3f33d2689cabc7c9d832cf14a006e.map
@@ -1,24 +1,27 @@
1
- /*!
2
- * jQuery Validation Plugin v1.13.0
3
- *
4
- * http://jqueryvalidation.org/
5
- *
6
- * Copyright (c) 2014 Jörn Zaefferer
7
- * Released under the MIT license
8
- */
9
- (function( factory ) {
10
- if ( typeof define === "function" && define.amd ) {
11
- define( ["jquery"], factory );
12
- } else {
13
- factory( jQuery );
14
- }
15
- }(function( $ ) {
16
-
17
- $.extend($.fn, {
18
- // http://jqueryvalidation.org/validate/
1
+ /*!
2
+ * jQuery Validation Plugin v1.17.0
3
+ *
4
+ * https://jqueryvalidation.org/
5
+ *
6
+ * Copyright (c) 2017 Jörn Zaefferer
7
+ * Released under the MIT license
8
+ */
9
+ (function( factory ) {
10
+ if ( typeof define === "function" && define.amd ) {
11
+ define( ["jquery"], factory );
12
+ } else if (typeof module === "object" && module.exports) {
13
+ module.exports = factory( require( "jquery" ) );
14
+ } else {
15
+ factory( jQuery );
16
+ }
17
+ }(function( $ ) {
18
+
19
+ $.extend( $.fn, {
20
+
21
+ // https://jqueryvalidation.org/validate/
19
22
  validate: function( options ) {
20
23
 
21
- // if nothing is selected, return nothing; can't chain anyway
24
+ // If nothing is selected, return nothing; can't chain anyway
22
25
  if ( !this.length ) {
23
26
  if ( options && options.debug && window.console ) {
24
27
  console.warn( "Nothing selected, can't validate, returning nothing." );
@@ -26,7 +29,7 @@ $.extend($.fn, {
26
29
  return;
27
30
  }
28
31
 
29
- // check if a validator for this form was already created
32
+ // Check if a validator for this form was already created
30
33
  var validator = $.data( this[ 0 ], "validator" );
31
34
  if ( validator ) {
32
35
  return validator;
@@ -40,48 +43,61 @@ $.extend($.fn, {
40
43
 
41
44
  if ( validator.settings.onsubmit ) {
42
45
 
43
- this.validateDelegate( ":submit", "click", function( event ) {
44
- if ( validator.settings.submitHandler ) {
45
- validator.submitButton = event.target;
46
- }
47
- // allow suppressing validation by adding a cancel class to the submit button
48
- if ( $( event.target ).hasClass( "cancel" ) ) {
46
+ this.on( "click.validate", ":submit", function( event ) {
47
+
48
+ // Track the used submit button to properly handle scripted
49
+ // submits later.
50
+ validator.submitButton = event.currentTarget;
51
+
52
+ // Allow suppressing validation by adding a cancel class to the submit button
53
+ if ( $( this ).hasClass( "cancel" ) ) {
49
54
  validator.cancelSubmit = true;
50
55
  }
51
56
 
52
- // allow suppressing validation by adding the html5 formnovalidate attribute to the submit button
53
- if ( $( event.target ).attr( "formnovalidate" ) !== undefined ) {
57
+ // Allow suppressing validation by adding the html5 formnovalidate attribute to the submit button
58
+ if ( $( this ).attr( "formnovalidate" ) !== undefined ) {
54
59
  validator.cancelSubmit = true;
55
60
  }
56
- });
61
+ } );
57
62
 
58
- // validate the form on submit
59
- this.submit( function( event ) {
63
+ // Validate the form on submit
64
+ this.on( "submit.validate", function( event ) {
60
65
  if ( validator.settings.debug ) {
61
- // prevent form submit to be able to see console output
66
+
67
+ // Prevent form submit to be able to see console output
62
68
  event.preventDefault();
63
69
  }
64
70
  function handle() {
65
- var hidden;
71
+ var hidden, result;
72
+
73
+ // Insert a hidden input as a replacement for the missing submit button
74
+ // The hidden input is inserted in two cases:
75
+ // - A user defined a `submitHandler`
76
+ // - There was a pending request due to `remote` method and `stopRequest()`
77
+ // was called to submit the form in case it's valid
78
+ if ( validator.submitButton && ( validator.settings.submitHandler || validator.formSubmitted ) ) {
79
+ hidden = $( "<input type='hidden'/>" )
80
+ .attr( "name", validator.submitButton.name )
81
+ .val( $( validator.submitButton ).val() )
82
+ .appendTo( validator.currentForm );
83
+ }
84
+
66
85
  if ( validator.settings.submitHandler ) {
67
- if ( validator.submitButton ) {
68
- // insert a hidden input as a replacement for the missing submit button
69
- hidden = $( "<input type='hidden'/>" )
70
- .attr( "name", validator.submitButton.name )
71
- .val( $( validator.submitButton ).val() )
72
- .appendTo( validator.currentForm );
73
- }
74
- validator.settings.submitHandler.call( validator, validator.currentForm, event );
75
- if ( validator.submitButton ) {
76
- // and clean up afterwards; thanks to no-block-scope, hidden can be referenced
86
+ result = validator.settings.submitHandler.call( validator, validator.currentForm, event );
87
+ if ( hidden ) {
88
+
89
+ // And clean up afterwards; thanks to no-block-scope, hidden can be referenced
77
90
  hidden.remove();
78
91
  }
92
+ if ( result !== undefined ) {
93
+ return result;
94
+ }
79
95
  return false;
80
96
  }
81
97
  return true;
82
98
  }
83
99
 
84
- // prevent submit for invalid forms or custom submit handlers
100
+ // Prevent submit for invalid forms or custom submit handlers
85
101
  if ( validator.cancelSubmit ) {
86
102
  validator.cancelSubmit = false;
87
103
  return handle();
@@ -96,41 +112,52 @@ $.extend($.fn, {
96
112
  validator.focusInvalid();
97
113
  return false;
98
114
  }
99
- });
115
+ } );
100
116
  }
101
117
 
102
118
  return validator;
103
119
  },
104
- // http://jqueryvalidation.org/valid/
120
+
121
+ // https://jqueryvalidation.org/valid/
105
122
  valid: function() {
106
- var valid, validator;
123
+ var valid, validator, errorList;
107
124
 
108
125
  if ( $( this[ 0 ] ).is( "form" ) ) {
109
126
  valid = this.validate().form();
110
127
  } else {
128
+ errorList = [];
111
129
  valid = true;
112
130
  validator = $( this[ 0 ].form ).validate();
113
131
  this.each( function() {
114
132
  valid = validator.element( this ) && valid;
115
- });
133
+ if ( !valid ) {
134
+ errorList = errorList.concat( validator.errorList );
135
+ }
136
+ } );
137
+ validator.errorList = errorList;
116
138
  }
117
139
  return valid;
118
140
  },
119
- // attributes: space separated list of attributes to retrieve and remove
120
- removeAttrs: function( attributes ) {
121
- var result = {},
122
- $element = this;
123
- $.each( attributes.split( /\s/ ), function( index, value ) {
124
- result[ value ] = $element.attr( value );
125
- $element.removeAttr( value );
126
- });
127
- return result;
128
- },
129
- // http://jqueryvalidation.org/rules/
141
+
142
+ // https://jqueryvalidation.org/rules/
130
143
  rules: function( command, argument ) {
131
144
  var element = this[ 0 ],
132
145
  settings, staticRules, existingRules, data, param, filtered;
133
146
 
147
+ // If nothing is selected, return empty object; can't chain anyway
148
+ if ( element == null ) {
149
+ return;
150
+ }
151
+
152
+ if ( !element.form && element.hasAttribute( "contenteditable" ) ) {
153
+ element.form = this.closest( "form" )[ 0 ];
154
+ element.name = this.attr( "name" );
155
+ }
156
+
157
+ if ( element.form == null ) {
158
+ return;
159
+ }
160
+
134
161
  if ( command ) {
135
162
  settings = $.data( element.form, "validator" ).settings;
136
163
  staticRules = settings.rules;
@@ -138,7 +165,8 @@ $.extend($.fn, {
138
165
  switch ( command ) {
139
166
  case "add":
140
167
  $.extend( existingRules, $.validator.normalizeRule( argument ) );
141
- // remove messages from rules, but allow them to be set separately
168
+
169
+ // Remove messages from rules, but allow them to be set separately
142
170
  delete existingRules.messages;
143
171
  staticRules[ element.name ] = existingRules;
144
172
  if ( argument.messages ) {
@@ -154,10 +182,7 @@ $.extend($.fn, {
154
182
  $.each( argument.split( /\s/ ), function( index, method ) {
155
183
  filtered[ method ] = existingRules[ method ];
156
184
  delete existingRules[ method ];
157
- if ( method === "required" ) {
158
- $( element ).removeAttr( "aria-required" );
159
- }
160
- });
185
+ } );
161
186
  return filtered;
162
187
  }
163
188
  }
@@ -171,49 +196,52 @@ $.extend($.fn, {
171
196
  $.validator.staticRules( element )
172
197
  ), element );
173
198
 
174
- // make sure required is at front
199
+ // Make sure required is at front
175
200
  if ( data.required ) {
176
201
  param = data.required;
177
202
  delete data.required;
178
203
  data = $.extend( { required: param }, data );
179
- $( element ).attr( "aria-required", "true" );
180
204
  }
181
205
 
182
- // make sure remote is at back
206
+ // Make sure remote is at back
183
207
  if ( data.remote ) {
184
208
  param = data.remote;
185
209
  delete data.remote;
186
- data = $.extend( data, { remote: param });
210
+ data = $.extend( data, { remote: param } );
187
211
  }
188
212
 
189
213
  return data;
190
214
  }
191
- });
215
+ } );
192
216
 
193
217
  // Custom selectors
194
- $.extend( $.expr[ ":" ], {
195
- // http://jqueryvalidation.org/blank-selector/
218
+ $.extend( $.expr.pseudos || $.expr[ ":" ], { // '|| $.expr[ ":" ]' here enables backwards compatibility to jQuery 1.7. Can be removed when dropping jQ 1.7.x support
219
+
220
+ // https://jqueryvalidation.org/blank-selector/
196
221
  blank: function( a ) {
197
222
  return !$.trim( "" + $( a ).val() );
198
223
  },
199
- // http://jqueryvalidation.org/filled-selector/
224
+
225
+ // https://jqueryvalidation.org/filled-selector/
200
226
  filled: function( a ) {
201
- return !!$.trim( "" + $( a ).val() );
227
+ var val = $( a ).val();
228
+ return val !== null && !!$.trim( "" + val );
202
229
  },
203
- // http://jqueryvalidation.org/unchecked-selector/
230
+
231
+ // https://jqueryvalidation.org/unchecked-selector/
204
232
  unchecked: function( a ) {
205
233
  return !$( a ).prop( "checked" );
206
234
  }
207
- });
235
+ } );
208
236
 
209
- // constructor for validator
237
+ // Constructor for validator
210
238
  $.validator = function( options, form ) {
211
239
  this.settings = $.extend( true, {}, $.validator.defaults, options );
212
240
  this.currentForm = form;
213
241
  this.init();
214
242
  };
215
243
 
216
- // http://jqueryvalidation.org/jQuery.validator.format/
244
+ // https://jqueryvalidation.org/jQuery.validator.format/
217
245
  $.validator.format = function( source, params ) {
218
246
  if ( arguments.length === 1 ) {
219
247
  return function() {
@@ -222,6 +250,9 @@ $.validator.format = function( source, params ) {
222
250
  return $.validator.format.apply( this, args );
223
251
  };
224
252
  }
253
+ if ( params === undefined ) {
254
+ return source;
255
+ }
225
256
  if ( arguments.length > 2 && params.constructor !== Array ) {
226
257
  params = $.makeArray( arguments ).slice( 1 );
227
258
  }
@@ -231,8 +262,8 @@ $.validator.format = function( source, params ) {
231
262
  $.each( params, function( i, n ) {
232
263
  source = source.replace( new RegExp( "\\{" + i + "\\}", "g" ), function() {
233
264
  return n;
234
- });
235
- });
265
+ } );
266
+ } );
236
267
  return source;
237
268
  };
238
269
 
@@ -243,8 +274,10 @@ $.extend( $.validator, {
243
274
  groups: {},
244
275
  rules: {},
245
276
  errorClass: "error",
277
+ pendingClass: "pending",
246
278
  validClass: "valid",
247
279
  errorElement: "label",
280
+ focusCleanup: false,
248
281
  focusInvalid: true,
249
282
  errorContainer: $( [] ),
250
283
  errorLabelContainer: $( [] ),
@@ -254,8 +287,8 @@ $.extend( $.validator, {
254
287
  onfocusin: function( element ) {
255
288
  this.lastActive = element;
256
289
 
257
- // hide error label and remove error class on focus if enabled
258
- if ( this.settings.focusCleanup && !this.blockFocusCleanup ) {
290
+ // Hide error label and remove error class on focus if enabled
291
+ if ( this.settings.focusCleanup ) {
259
292
  if ( this.settings.unhighlight ) {
260
293
  this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );
261
294
  }
@@ -268,18 +301,39 @@ $.extend( $.validator, {
268
301
  }
269
302
  },
270
303
  onkeyup: function( element, event ) {
271
- if ( event.which === 9 && this.elementValue( element ) === "" ) {
304
+
305
+ // Avoid revalidate the field when pressing one of the following keys
306
+ // Shift => 16
307
+ // Ctrl => 17
308
+ // Alt => 18
309
+ // Caps lock => 20
310
+ // End => 35
311
+ // Home => 36
312
+ // Left arrow => 37
313
+ // Up arrow => 38
314
+ // Right arrow => 39
315
+ // Down arrow => 40
316
+ // Insert => 45
317
+ // Num lock => 144
318
+ // AltGr key => 225
319
+ var excludedKeys = [
320
+ 16, 17, 18, 20, 35, 36, 37,
321
+ 38, 39, 40, 45, 144, 225
322
+ ];
323
+
324
+ if ( event.which === 9 && this.elementValue( element ) === "" || $.inArray( event.keyCode, excludedKeys ) !== -1 ) {
272
325
  return;
273
- } else if ( element.name in this.submitted || element === this.lastElement ) {
326
+ } else if ( element.name in this.submitted || element.name in this.invalid ) {
274
327
  this.element( element );
275
328
  }
276
329
  },
277
330
  onclick: function( element ) {
278
- // click on selects, radiobuttons and checkboxes
331
+
332
+ // Click on selects, radiobuttons and checkboxes
279
333
  if ( element.name in this.submitted ) {
280
334
  this.element( element );
281
335
 
282
- // or option elements, check parent select in that case
336
+ // Or option elements, check parent select in that case
283
337
  } else if ( element.parentNode.name in this.submitted ) {
284
338
  this.element( element.parentNode );
285
339
  }
@@ -300,7 +354,7 @@ $.extend( $.validator, {
300
354
  }
301
355
  },
302
356
 
303
- // http://jqueryvalidation.org/jQuery.validator.setDefaults/
357
+ // https://jqueryvalidation.org/jQuery.validator.setDefaults/
304
358
  setDefaults: function( settings ) {
305
359
  $.extend( $.validator.defaults, settings );
306
360
  },
@@ -311,17 +365,17 @@ $.extend( $.validator, {
311
365
  email: "Please enter a valid email address.",
312
366
  url: "Please enter a valid URL.",
313
367
  date: "Please enter a valid date.",
314
- dateISO: "Please enter a valid date ( ISO ).",
368
+ dateISO: "Please enter a valid date (ISO).",
315
369
  number: "Please enter a valid number.",
316
370
  digits: "Please enter only digits.",
317
- creditcard: "Please enter a valid credit card number.",
318
371
  equalTo: "Please enter the same value again.",
319
372
  maxlength: $.validator.format( "Please enter no more than {0} characters." ),
320
373
  minlength: $.validator.format( "Please enter at least {0} characters." ),
321
374
  rangelength: $.validator.format( "Please enter a value between {0} and {1} characters long." ),
322
375
  range: $.validator.format( "Please enter a value between {0} and {1}." ),
323
376
  max: $.validator.format( "Please enter a value less than or equal to {0}." ),
324
- min: $.validator.format( "Please enter a value greater than or equal to {0}." )
377
+ min: $.validator.format( "Please enter a value greater than or equal to {0}." ),
378
+ step: $.validator.format( "Please enter a multiple of {0}." )
325
379
  },
326
380
 
327
381
  autoCreateRanges: false,
@@ -347,48 +401,52 @@ $.extend( $.validator, {
347
401
  }
348
402
  $.each( value, function( index, name ) {
349
403
  groups[ name ] = key;
350
- });
351
- });
404
+ } );
405
+ } );
352
406
  rules = this.settings.rules;
353
407
  $.each( rules, function( key, value ) {
354
408
  rules[ key ] = $.validator.normalizeRule( value );
355
- });
409
+ } );
356
410
 
357
411
  function delegate( event ) {
358
- var validator = $.data( this[ 0 ].form, "validator" ),
412
+
413
+ // Set form expando on contenteditable
414
+ if ( !this.form && this.hasAttribute( "contenteditable" ) ) {
415
+ this.form = $( this ).closest( "form" )[ 0 ];
416
+ this.name = $( this ).attr( "name" );
417
+ }
418
+
419
+ var validator = $.data( this.form, "validator" ),
359
420
  eventType = "on" + event.type.replace( /^validate/, "" ),
360
421
  settings = validator.settings;
361
- if ( settings[ eventType ] && !this.is( settings.ignore ) ) {
362
- settings[ eventType ].call( validator, this[ 0 ], event );
422
+ if ( settings[ eventType ] && !$( this ).is( settings.ignore ) ) {
423
+ settings[ eventType ].call( validator, this, event );
363
424
  }
364
425
  }
426
+
365
427
  $( this.currentForm )
366
- .validateDelegate( ":text, [type='password'], [type='file'], select, textarea, " +
367
- "[type='number'], [type='search'] ,[type='tel'], [type='url'], " +
368
- "[type='email'], [type='datetime'], [type='date'], [type='month'], " +
369
- "[type='week'], [type='time'], [type='datetime-local'], " +
370
- "[type='range'], [type='color'], [type='radio'], [type='checkbox']",
371
- "focusin focusout keyup", delegate)
428
+ .on( "focusin.validate focusout.validate keyup.validate",
429
+ ":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], " +
430
+ "[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], " +
431
+ "[type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], " +
432
+ "[type='radio'], [type='checkbox'], [contenteditable], [type='button']", delegate )
433
+
372
434
  // Support: Chrome, oldIE
373
435
  // "select" is provided as event.target when clicking a option
374
- .validateDelegate("select, option, [type='radio'], [type='checkbox']", "click", delegate);
436
+ .on( "click.validate", "select, option, [type='radio'], [type='checkbox']", delegate );
375
437
 
376
438
  if ( this.settings.invalidHandler ) {
377
- $( this.currentForm ).bind( "invalid-form.validate", this.settings.invalidHandler );
439
+ $( this.currentForm ).on( "invalid-form.validate", this.settings.invalidHandler );
378
440
  }
379
-
380
- // Add aria-required to any Static/Data/Class required fields before first validation
381
- // Screen readers require this attribute to be present before the initial submission http://www.w3.org/TR/WCAG-TECHS/ARIA2.html
382
- $( this.currentForm ).find( "[required], [data-rule-required], .required" ).attr( "aria-required", "true" );
383
441
  },
384
442
 
385
- // http://jqueryvalidation.org/Validator.form/
443
+ // https://jqueryvalidation.org/Validator.form/
386
444
  form: function() {
387
445
  this.checkForm();
388
446
  $.extend( this.submitted, this.errorMap );
389
- this.invalid = $.extend({}, this.errorMap );
447
+ this.invalid = $.extend( {}, this.errorMap );
390
448
  if ( !this.valid() ) {
391
- $( this.currentForm ).triggerHandler( "invalid-form", [ this ]);
449
+ $( this.currentForm ).triggerHandler( "invalid-form", [ this ] );
392
450
  }
393
451
  this.showErrors();
394
452
  return this.valid();
@@ -402,13 +460,13 @@ $.extend( $.validator, {
402
460
  return this.valid();
403
461
  },
404
462
 
405
- // http://jqueryvalidation.org/Validator.element/
463
+ // https://jqueryvalidation.org/Validator.element/
406
464
  element: function( element ) {
407
465
  var cleanElement = this.clean( element ),
408
466
  checkElement = this.validationTargetFor( cleanElement ),
409
- result = true;
410
-
411
- this.lastElement = checkElement;
467
+ v = this,
468
+ result = true,
469
+ rs, group;
412
470
 
413
471
  if ( checkElement === undefined ) {
414
472
  delete this.invalid[ cleanElement.name ];
@@ -416,40 +474,61 @@ $.extend( $.validator, {
416
474
  this.prepareElement( checkElement );
417
475
  this.currentElements = $( checkElement );
418
476
 
419
- result = this.check( checkElement ) !== false;
420
- if ( result ) {
421
- delete this.invalid[ checkElement.name ];
477
+ // If this element is grouped, then validate all group elements already
478
+ // containing a value
479
+ group = this.groups[ checkElement.name ];
480
+ if ( group ) {
481
+ $.each( this.groups, function( name, testgroup ) {
482
+ if ( testgroup === group && name !== checkElement.name ) {
483
+ cleanElement = v.validationTargetFor( v.clean( v.findByName( name ) ) );
484
+ if ( cleanElement && cleanElement.name in v.invalid ) {
485
+ v.currentElements.push( cleanElement );
486
+ result = v.check( cleanElement ) && result;
487
+ }
488
+ }
489
+ } );
490
+ }
491
+
492
+ rs = this.check( checkElement ) !== false;
493
+ result = result && rs;
494
+ if ( rs ) {
495
+ this.invalid[ checkElement.name ] = false;
422
496
  } else {
423
497
  this.invalid[ checkElement.name ] = true;
424
498
  }
425
- }
426
- // Add aria-invalid status for screen readers
427
- $( element ).attr( "aria-invalid", !result );
428
499
 
429
- if ( !this.numberOfInvalids() ) {
430
- // Hide error containers on last error
431
- this.toHide = this.toHide.add( this.containers );
500
+ if ( !this.numberOfInvalids() ) {
501
+
502
+ // Hide error containers on last error
503
+ this.toHide = this.toHide.add( this.containers );
504
+ }
505
+ this.showErrors();
506
+
507
+ // Add aria-invalid status for screen readers
508
+ $( element ).attr( "aria-invalid", !rs );
432
509
  }
433
- this.showErrors();
510
+
434
511
  return result;
435
512
  },
436
513
 
437
- // http://jqueryvalidation.org/Validator.showErrors/
514
+ // https://jqueryvalidation.org/Validator.showErrors/
438
515
  showErrors: function( errors ) {
439
516
  if ( errors ) {
440
- // add items to error list and map
517
+ var validator = this;
518
+
519
+ // Add items to error list and map
441
520
  $.extend( this.errorMap, errors );
442
- this.errorList = [];
443
- for ( var name in errors ) {
444
- this.errorList.push({
445
- message: errors[ name ],
446
- element: this.findByName( name )[ 0 ]
447
- });
448
- }
449
- // remove items from success list
521
+ this.errorList = $.map( this.errorMap, function( message, name ) {
522
+ return {
523
+ message: message,
524
+ element: validator.findByName( name )[ 0 ]
525
+ };
526
+ } );
527
+
528
+ // Remove items from success list
450
529
  this.successList = $.grep( this.successList, function( element ) {
451
530
  return !( element.name in errors );
452
- });
531
+ } );
453
532
  }
454
533
  if ( this.settings.showErrors ) {
455
534
  this.settings.showErrors.call( this, this.errorMap, this.errorList );
@@ -458,19 +537,36 @@ $.extend( $.validator, {
458
537
  }
459
538
  },
460
539
 
461
- // http://jqueryvalidation.org/Validator.resetForm/
540
+ // https://jqueryvalidation.org/Validator.resetForm/
462
541
  resetForm: function() {
463
542
  if ( $.fn.resetForm ) {
464
543
  $( this.currentForm ).resetForm();
465
544
  }
545
+ this.invalid = {};
466
546
  this.submitted = {};
467
- this.lastElement = null;
468
547
  this.prepareForm();
469
548
  this.hideErrors();
470
- this.elements()
549
+ var elements = this.elements()
550
+ .removeData( "previousValue" )
551
+ .removeAttr( "aria-invalid" );
552
+
553
+ this.resetElements( elements );
554
+ },
555
+
556
+ resetElements: function( elements ) {
557
+ var i;
558
+
559
+ if ( this.settings.unhighlight ) {
560
+ for ( i = 0; elements[ i ]; i++ ) {
561
+ this.settings.unhighlight.call( this, elements[ i ],
562
+ this.settings.errorClass, "" );
563
+ this.findByName( elements[ i ].name ).removeClass( this.settings.validClass );
564
+ }
565
+ } else {
566
+ elements
471
567
  .removeClass( this.settings.errorClass )
472
- .removeData( "previousValue" )
473
- .removeAttr( "aria-invalid" );
568
+ .removeClass( this.settings.validClass );
569
+ }
474
570
  },
475
571
 
476
572
  numberOfInvalids: function() {
@@ -482,7 +578,12 @@ $.extend( $.validator, {
482
578
  var count = 0,
483
579
  i;
484
580
  for ( i in obj ) {
485
- count++;
581
+
582
+ // This check allows counting elements with empty error
583
+ // message as invalid elements
584
+ if ( obj[ i ] !== undefined && obj[ i ] !== null && obj[ i ] !== false ) {
585
+ count++;
586
+ }
486
587
  }
487
588
  return count;
488
589
  },
@@ -507,13 +608,15 @@ $.extend( $.validator, {
507
608
  focusInvalid: function() {
508
609
  if ( this.settings.focusInvalid ) {
509
610
  try {
510
- $( this.findLastActive() || this.errorList.length && this.errorList[ 0 ].element || [])
611
+ $( this.findLastActive() || this.errorList.length && this.errorList[ 0 ].element || [] )
511
612
  .filter( ":visible" )
512
613
  .focus()
513
- // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
614
+
615
+ // Manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
514
616
  .trigger( "focusin" );
515
617
  } catch ( e ) {
516
- // ignore IE throwing errors when focusing hidden elements
618
+
619
+ // Ignore IE throwing errors when focusing hidden elements
517
620
  }
518
621
  }
519
622
  },
@@ -522,31 +625,38 @@ $.extend( $.validator, {
522
625
  var lastActive = this.lastActive;
523
626
  return lastActive && $.grep( this.errorList, function( n ) {
524
627
  return n.element.name === lastActive.name;
525
- }).length === 1 && lastActive;
628
+ } ).length === 1 && lastActive;
526
629
  },
527
630
 
528
631
  elements: function() {
529
632
  var validator = this,
530
633
  rulesCache = {};
531
634
 
532
- // select all valid inputs inside the form (no submit or reset buttons)
635
+ // Select all valid inputs inside the form (no submit or reset buttons)
533
636
  return $( this.currentForm )
534
- .find( "input, select, textarea" )
535
- .not( ":submit, :reset, :image, [disabled]" )
637
+ .find( "input, select, textarea, [contenteditable]" )
638
+ .not( ":submit, :reset, :image, :disabled" )
536
639
  .not( this.settings.ignore )
537
640
  .filter( function() {
538
- if ( !this.name && validator.settings.debug && window.console ) {
641
+ var name = this.name || $( this ).attr( "name" ); // For contenteditable
642
+ if ( !name && validator.settings.debug && window.console ) {
539
643
  console.error( "%o has no name assigned", this );
540
644
  }
541
645
 
542
- // select only the first element for each name, and only those with rules specified
543
- if ( this.name in rulesCache || !validator.objectLength( $( this ).rules() ) ) {
646
+ // Set form expando on contenteditable
647
+ if ( this.hasAttribute( "contenteditable" ) ) {
648
+ this.form = $( this ).closest( "form" )[ 0 ];
649
+ this.name = name;
650
+ }
651
+
652
+ // Select only the first element for each name, and only those with rules specified
653
+ if ( name in rulesCache || !validator.objectLength( $( this ).rules() ) ) {
544
654
  return false;
545
655
  }
546
656
 
547
- rulesCache[ this.name ] = true;
657
+ rulesCache[ name ] = true;
548
658
  return true;
549
- });
659
+ } );
550
660
  },
551
661
 
552
662
  clean: function( selector ) {
@@ -558,12 +668,16 @@ $.extend( $.validator, {
558
668
  return $( this.settings.errorElement + "." + errorClass, this.errorContext );
559
669
  },
560
670
 
561
- reset: function() {
671
+ resetInternals: function() {
562
672
  this.successList = [];
563
673
  this.errorList = [];
564
674
  this.errorMap = {};
565
675
  this.toShow = $( [] );
566
676
  this.toHide = $( [] );
677
+ },
678
+
679
+ reset: function() {
680
+ this.resetInternals();
567
681
  this.currentElements = $( [] );
568
682
  },
569
683
 
@@ -578,19 +692,48 @@ $.extend( $.validator, {
578
692
  },
579
693
 
580
694
  elementValue: function( element ) {
581
- var val,
582
- $element = $( element ),
583
- type = element.type;
695
+ var $element = $( element ),
696
+ type = element.type,
697
+ val, idx;
584
698
 
585
699
  if ( type === "radio" || type === "checkbox" ) {
586
- return $( "input[name='" + element.name + "']:checked" ).val();
700
+ return this.findByName( element.name ).filter( ":checked" ).val();
587
701
  } else if ( type === "number" && typeof element.validity !== "undefined" ) {
588
- return element.validity.badInput ? false : $element.val();
702
+ return element.validity.badInput ? "NaN" : $element.val();
703
+ }
704
+
705
+ if ( element.hasAttribute( "contenteditable" ) ) {
706
+ val = $element.text();
707
+ } else {
708
+ val = $element.val();
709
+ }
710
+
711
+ if ( type === "file" ) {
712
+
713
+ // Modern browser (chrome & safari)
714
+ if ( val.substr( 0, 12 ) === "C:\\fakepath\\" ) {
715
+ return val.substr( 12 );
716
+ }
717
+
718
+ // Legacy browsers
719
+ // Unix-based path
720
+ idx = val.lastIndexOf( "/" );
721
+ if ( idx >= 0 ) {
722
+ return val.substr( idx + 1 );
723
+ }
724
+
725
+ // Windows-based path
726
+ idx = val.lastIndexOf( "\\" );
727
+ if ( idx >= 0 ) {
728
+ return val.substr( idx + 1 );
729
+ }
730
+
731
+ // Just the file name
732
+ return val;
589
733
  }
590
734
 
591
- val = $element.val();
592
735
  if ( typeof val === "string" ) {
593
- return val.replace(/\r/g, "" );
736
+ return val.replace( /\r/g, "" );
594
737
  }
595
738
  return val;
596
739
  },
@@ -601,18 +744,39 @@ $.extend( $.validator, {
601
744
  var rules = $( element ).rules(),
602
745
  rulesCount = $.map( rules, function( n, i ) {
603
746
  return i;
604
- }).length,
747
+ } ).length,
605
748
  dependencyMismatch = false,
606
749
  val = this.elementValue( element ),
607
- result, method, rule;
750
+ result, method, rule, normalizer;
751
+
752
+ // Prioritize the local normalizer defined for this element over the global one
753
+ // if the former exists, otherwise user the global one in case it exists.
754
+ if ( typeof rules.normalizer === "function" ) {
755
+ normalizer = rules.normalizer;
756
+ } else if ( typeof this.settings.normalizer === "function" ) {
757
+ normalizer = this.settings.normalizer;
758
+ }
759
+
760
+ // If normalizer is defined, then call it to retreive the changed value instead
761
+ // of using the real one.
762
+ // Note that `this` in the normalizer is `element`.
763
+ if ( normalizer ) {
764
+ val = normalizer.call( element, val );
765
+
766
+ if ( typeof val !== "string" ) {
767
+ throw new TypeError( "The normalizer should return a string value." );
768
+ }
769
+
770
+ // Delete the normalizer from rules to avoid treating it as a pre-defined method.
771
+ delete rules.normalizer;
772
+ }
608
773
 
609
774
  for ( method in rules ) {
610
775
  rule = { method: method, parameters: rules[ method ] };
611
776
  try {
612
-
613
777
  result = $.validator.methods[ method ].call( this, val, element, rule.parameters );
614
778
 
615
- // if a method indicates that the field is optional and therefore valid,
779
+ // If a method indicates that the field is optional and therefore valid,
616
780
  // don't mark it as valid when there are no other rules
617
781
  if ( result === "dependency-mismatch" && rulesCount === 1 ) {
618
782
  dependencyMismatch = true;
@@ -633,6 +797,10 @@ $.extend( $.validator, {
633
797
  if ( this.settings.debug && window.console ) {
634
798
  console.log( "Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e );
635
799
  }
800
+ if ( e instanceof TypeError ) {
801
+ e.message += ". Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.";
802
+ }
803
+
636
804
  throw e;
637
805
  }
638
806
  }
@@ -645,7 +813,7 @@ $.extend( $.validator, {
645
813
  return true;
646
814
  },
647
815
 
648
- // return the custom message for the given element and validation method
816
+ // Return the custom message for the given element and validation method
649
817
  // specified in the element's HTML5 data attribute
650
818
  // return the generic message if present and no method specific message is present
651
819
  customDataMessage: function( element, method ) {
@@ -653,15 +821,15 @@ $.extend( $.validator, {
653
821
  method.substring( 1 ).toLowerCase() ) || $( element ).data( "msg" );
654
822
  },
655
823
 
656
- // return the custom message for the given element name and validation method
824
+ // Return the custom message for the given element name and validation method
657
825
  customMessage: function( name, method ) {
658
826
  var m = this.settings.messages[ name ];
659
- return m && ( m.constructor === String ? m : m[ method ]);
827
+ return m && ( m.constructor === String ? m : m[ method ] );
660
828
  },
661
829
 
662
- // return the first defined argument, allowing empty strings
830
+ // Return the first defined argument, allowing empty strings
663
831
  findDefined: function() {
664
- for ( var i = 0; i < arguments.length; i++) {
832
+ for ( var i = 0; i < arguments.length; i++ ) {
665
833
  if ( arguments[ i ] !== undefined ) {
666
834
  return arguments[ i ];
667
835
  }
@@ -669,30 +837,47 @@ $.extend( $.validator, {
669
837
  return undefined;
670
838
  },
671
839
 
672
- defaultMessage: function( element, method ) {
673
- return this.findDefined(
674
- this.customMessage( element.name, method ),
675
- this.customDataMessage( element, method ),
676
- // title is never undefined, so handle empty string as undefined
677
- !this.settings.ignoreTitle && element.title || undefined,
678
- $.validator.messages[ method ],
679
- "<strong>Warning: No message defined for " + element.name + "</strong>"
680
- );
681
- },
682
-
683
- formatAndAdd: function( element, rule ) {
684
- var message = this.defaultMessage( element, rule.method ),
840
+ // The second parameter 'rule' used to be a string, and extended to an object literal
841
+ // of the following form:
842
+ // rule = {
843
+ // method: "method name",
844
+ // parameters: "the given method parameters"
845
+ // }
846
+ //
847
+ // The old behavior still supported, kept to maintain backward compatibility with
848
+ // old code, and will be removed in the next major release.
849
+ defaultMessage: function( element, rule ) {
850
+ if ( typeof rule === "string" ) {
851
+ rule = { method: rule };
852
+ }
853
+
854
+ var message = this.findDefined(
855
+ this.customMessage( element.name, rule.method ),
856
+ this.customDataMessage( element, rule.method ),
857
+
858
+ // 'title' is never undefined, so handle empty string as undefined
859
+ !this.settings.ignoreTitle && element.title || undefined,
860
+ $.validator.messages[ rule.method ],
861
+ "<strong>Warning: No message defined for " + element.name + "</strong>"
862
+ ),
685
863
  theregex = /\$?\{(\d+)\}/g;
686
864
  if ( typeof message === "function" ) {
687
865
  message = message.call( this, rule.parameters, element );
688
866
  } else if ( theregex.test( message ) ) {
689
867
  message = $.validator.format( message.replace( theregex, "{$1}" ), rule.parameters );
690
868
  }
691
- this.errorList.push({
869
+
870
+ return message;
871
+ },
872
+
873
+ formatAndAdd: function( element, rule ) {
874
+ var message = this.defaultMessage( element, rule );
875
+
876
+ this.errorList.push( {
692
877
  message: message,
693
878
  element: element,
694
879
  method: rule.method
695
- });
880
+ } );
696
881
 
697
882
  this.errorMap[ element.name ] = message;
698
883
  this.submitted[ element.name ] = message;
@@ -737,23 +922,27 @@ $.extend( $.validator, {
737
922
  },
738
923
 
739
924
  invalidElements: function() {
740
- return $( this.errorList ).map(function() {
925
+ return $( this.errorList ).map( function() {
741
926
  return this.element;
742
- });
927
+ } );
743
928
  },
744
929
 
745
930
  showLabel: function( element, message ) {
746
- var place, group, errorID,
931
+ var place, group, errorID, v,
747
932
  error = this.errorsFor( element ),
748
933
  elementID = this.idOrName( element ),
749
934
  describedBy = $( element ).attr( "aria-describedby" );
935
+
750
936
  if ( error.length ) {
751
- // refresh error/success class
937
+
938
+ // Refresh error/success class
752
939
  error.removeClass( this.settings.validClass ).addClass( this.settings.errorClass );
753
- // replace message on existing label
940
+
941
+ // Replace message on existing label
754
942
  error.html( message );
755
943
  } else {
756
- // create error element
944
+
945
+ // Create error element
757
946
  error = $( "<" + this.settings.errorElement + ">" )
758
947
  .attr( "id", elementID + "-error" )
759
948
  .addClass( this.settings.errorClass )
@@ -762,31 +951,35 @@ $.extend( $.validator, {
762
951
  // Maintain reference to the element to be placed into the DOM
763
952
  place = error;
764
953
  if ( this.settings.wrapper ) {
765
- // make sure the element is visible, even in IE
954
+
955
+ // Make sure the element is visible, even in IE
766
956
  // actually showing the wrapped element is handled elsewhere
767
957
  place = error.hide().show().wrap( "<" + this.settings.wrapper + "/>" ).parent();
768
958
  }
769
959
  if ( this.labelContainer.length ) {
770
960
  this.labelContainer.append( place );
771
961
  } else if ( this.settings.errorPlacement ) {
772
- this.settings.errorPlacement( place, $( element ) );
962
+ this.settings.errorPlacement.call( this, place, $( element ) );
773
963
  } else {
774
964
  place.insertAfter( element );
775
965
  }
776
966
 
777
967
  // Link error back to the element
778
968
  if ( error.is( "label" ) ) {
969
+
779
970
  // If the error is a label, then associate using 'for'
780
971
  error.attr( "for", elementID );
781
- } else if ( error.parents( "label[for='" + elementID + "']" ).length === 0 ) {
972
+
782
973
  // If the element is not a child of an associated label, then it's necessary
783
974
  // to explicitly apply aria-describedby
784
-
975
+ } else if ( error.parents( "label[for='" + this.escapeCssMeta( elementID ) + "']" ).length === 0 ) {
785
976
  errorID = error.attr( "id" );
977
+
786
978
  // Respect existing non-error aria-describedby
787
979
  if ( !describedBy ) {
788
980
  describedBy = errorID;
789
- } else if ( !describedBy.match( new RegExp( "\b" + errorID + "\b" ) ) ) {
981
+ } else if ( !describedBy.match( new RegExp( "\\b" + this.escapeCssMeta( errorID ) + "\\b" ) ) ) {
982
+
790
983
  // Add to end of list if not already present
791
984
  describedBy += " " + errorID;
792
985
  }
@@ -795,12 +988,13 @@ $.extend( $.validator, {
795
988
  // If this element is grouped, then assign to all elements in the same group
796
989
  group = this.groups[ element.name ];
797
990
  if ( group ) {
798
- $.each( this.groups, function( name, testgroup ) {
991
+ v = this;
992
+ $.each( v.groups, function( name, testgroup ) {
799
993
  if ( testgroup === group ) {
800
- $( "[name='" + name + "']", this.currentForm )
994
+ $( "[name='" + v.escapeCssMeta( name ) + "']", v.currentForm )
801
995
  .attr( "aria-describedby", error.attr( "id" ) );
802
996
  }
803
- });
997
+ } );
804
998
  }
805
999
  }
806
1000
  }
@@ -816,28 +1010,41 @@ $.extend( $.validator, {
816
1010
  },
817
1011
 
818
1012
  errorsFor: function( element ) {
819
- var name = this.idOrName( element ),
1013
+ var name = this.escapeCssMeta( this.idOrName( element ) ),
820
1014
  describer = $( element ).attr( "aria-describedby" ),
821
1015
  selector = "label[for='" + name + "'], label[for='" + name + "'] *";
822
- // aria-describedby should directly reference the error element
1016
+
1017
+ // 'aria-describedby' should directly reference the error element
823
1018
  if ( describer ) {
824
- selector = selector + ", #" + describer.replace( /\s+/g, ", #" );
1019
+ selector = selector + ", #" + this.escapeCssMeta( describer )
1020
+ .replace( /\s+/g, ", #" );
825
1021
  }
1022
+
826
1023
  return this
827
1024
  .errors()
828
1025
  .filter( selector );
829
1026
  },
830
1027
 
1028
+ // See https://api.jquery.com/category/selectors/, for CSS
1029
+ // meta-characters that should be escaped in order to be used with JQuery
1030
+ // as a literal part of a name/id or any selector.
1031
+ escapeCssMeta: function( string ) {
1032
+ return string.replace( /([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g, "\\$1" );
1033
+ },
1034
+
831
1035
  idOrName: function( element ) {
832
1036
  return this.groups[ element.name ] || ( this.checkable( element ) ? element.name : element.id || element.name );
833
1037
  },
834
1038
 
835
1039
  validationTargetFor: function( element ) {
836
- // if radio/checkbox, validate first element in group instead
1040
+
1041
+ // If radio/checkbox, validate first element in group instead
837
1042
  if ( this.checkable( element ) ) {
838
- element = this.findByName( element.name ).not( this.settings.ignore )[ 0 ];
1043
+ element = this.findByName( element.name );
839
1044
  }
840
- return element;
1045
+
1046
+ // Always apply ignore filter
1047
+ return $( element ).not( this.settings.ignore )[ 0 ];
841
1048
  },
842
1049
 
843
1050
  checkable: function( element ) {
@@ -845,7 +1052,7 @@ $.extend( $.validator, {
845
1052
  },
846
1053
 
847
1054
  findByName: function( name ) {
848
- return $( this.currentForm ).find( "[name='" + name + "']" );
1055
+ return $( this.currentForm ).find( "[name='" + this.escapeCssMeta( name ) + "']" );
849
1056
  },
850
1057
 
851
1058
  getLength: function( value, element ) {
@@ -861,7 +1068,7 @@ $.extend( $.validator, {
861
1068
  },
862
1069
 
863
1070
  depend: function( param, element ) {
864
- return this.dependTypes[typeof param] ? this.dependTypes[typeof param]( param, element ) : true;
1071
+ return this.dependTypes[ typeof param ] ? this.dependTypes[ typeof param ]( param, element ) : true;
865
1072
  },
866
1073
 
867
1074
  dependTypes: {
@@ -884,32 +1091,58 @@ $.extend( $.validator, {
884
1091
  startRequest: function( element ) {
885
1092
  if ( !this.pending[ element.name ] ) {
886
1093
  this.pendingRequest++;
1094
+ $( element ).addClass( this.settings.pendingClass );
887
1095
  this.pending[ element.name ] = true;
888
1096
  }
889
1097
  },
890
1098
 
891
1099
  stopRequest: function( element, valid ) {
892
1100
  this.pendingRequest--;
893
- // sometimes synchronization fails, make sure pendingRequest is never < 0
1101
+
1102
+ // Sometimes synchronization fails, make sure pendingRequest is never < 0
894
1103
  if ( this.pendingRequest < 0 ) {
895
1104
  this.pendingRequest = 0;
896
1105
  }
897
1106
  delete this.pending[ element.name ];
1107
+ $( element ).removeClass( this.settings.pendingClass );
898
1108
  if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) {
899
1109
  $( this.currentForm ).submit();
1110
+
1111
+ // Remove the hidden input that was used as a replacement for the
1112
+ // missing submit button. The hidden input is added by `handle()`
1113
+ // to ensure that the value of the used submit button is passed on
1114
+ // for scripted submits triggered by this method
1115
+ if ( this.submitButton ) {
1116
+ $( "input:hidden[name='" + this.submitButton.name + "']", this.currentForm ).remove();
1117
+ }
1118
+
900
1119
  this.formSubmitted = false;
901
- } else if (!valid && this.pendingRequest === 0 && this.formSubmitted ) {
902
- $( this.currentForm ).triggerHandler( "invalid-form", [ this ]);
1120
+ } else if ( !valid && this.pendingRequest === 0 && this.formSubmitted ) {
1121
+ $( this.currentForm ).triggerHandler( "invalid-form", [ this ] );
903
1122
  this.formSubmitted = false;
904
1123
  }
905
1124
  },
906
1125
 
907
- previousValue: function( element ) {
1126
+ previousValue: function( element, method ) {
1127
+ method = typeof method === "string" && method || "remote";
1128
+
908
1129
  return $.data( element, "previousValue" ) || $.data( element, "previousValue", {
909
1130
  old: null,
910
1131
  valid: true,
911
- message: this.defaultMessage( element, "remote" )
912
- });
1132
+ message: this.defaultMessage( element, { method: method } )
1133
+ } );
1134
+ },
1135
+
1136
+ // Cleans up all forms and elements, removes validator-specific events
1137
+ destroy: function() {
1138
+ this.resetForm();
1139
+
1140
+ $( this.currentForm )
1141
+ .off( ".validate" )
1142
+ .removeData( "validator" )
1143
+ .find( ".validate-equalTo-blur" )
1144
+ .off( ".validate-equalTo" )
1145
+ .removeClass( "validate-equalTo-blur" );
913
1146
  }
914
1147
 
915
1148
  },
@@ -940,13 +1173,36 @@ $.extend( $.validator, {
940
1173
  if ( classes ) {
941
1174
  $.each( classes.split( " " ), function() {
942
1175
  if ( this in $.validator.classRuleSettings ) {
943
- $.extend( rules, $.validator.classRuleSettings[ this ]);
1176
+ $.extend( rules, $.validator.classRuleSettings[ this ] );
944
1177
  }
945
- });
1178
+ } );
946
1179
  }
947
1180
  return rules;
948
1181
  },
949
1182
 
1183
+ normalizeAttributeRule: function( rules, type, method, value ) {
1184
+
1185
+ // Convert the value to a number for number inputs, and for text for backwards compability
1186
+ // allows type="date" and others to be compared as strings
1187
+ if ( /min|max|step/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) {
1188
+ value = Number( value );
1189
+
1190
+ // Support Opera Mini, which returns NaN for undefined minlength
1191
+ if ( isNaN( value ) ) {
1192
+ value = undefined;
1193
+ }
1194
+ }
1195
+
1196
+ if ( value || value === 0 ) {
1197
+ rules[ method ] = value;
1198
+ } else if ( type === method && type !== "range" ) {
1199
+
1200
+ // Exception: the jquery validate 'range' method
1201
+ // does not test for the html5 'range' type
1202
+ rules[ method ] = true;
1203
+ }
1204
+ },
1205
+
950
1206
  attributeRules: function( element ) {
951
1207
  var rules = {},
952
1208
  $element = $( element ),
@@ -955,36 +1211,26 @@ $.extend( $.validator, {
955
1211
 
956
1212
  for ( method in $.validator.methods ) {
957
1213
 
958
- // support for <input required> in both html5 and older browsers
1214
+ // Support for <input required> in both html5 and older browsers
959
1215
  if ( method === "required" ) {
960
1216
  value = element.getAttribute( method );
1217
+
961
1218
  // Some browsers return an empty string for the required attribute
962
1219
  // and non-HTML5 browsers might have required="" markup
963
1220
  if ( value === "" ) {
964
1221
  value = true;
965
1222
  }
966
- // force non-HTML5 browsers to return bool
1223
+
1224
+ // Force non-HTML5 browsers to return bool
967
1225
  value = !!value;
968
1226
  } else {
969
1227
  value = $element.attr( method );
970
1228
  }
971
1229
 
972
- // convert the value to a number for number inputs, and for text for backwards compability
973
- // allows type="date" and others to be compared as strings
974
- if ( /min|max/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) {
975
- value = Number( value );
976
- }
977
-
978
- if ( value || value === 0 ) {
979
- rules[ method ] = value;
980
- } else if ( type === method && type !== "range" ) {
981
- // exception: the jquery validate 'range' method
982
- // does not test for the html5 'range' type
983
- rules[ method ] = true;
984
- }
1230
+ this.normalizeAttributeRule( rules, type, method, value );
985
1231
  }
986
1232
 
987
- // maxlength may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs
1233
+ // 'maxlength' may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs
988
1234
  if ( rules.maxlength && /-1|2147483647|524288/.test( rules.maxlength ) ) {
989
1235
  delete rules.maxlength;
990
1236
  }
@@ -993,13 +1239,14 @@ $.extend( $.validator, {
993
1239
  },
994
1240
 
995
1241
  dataRules: function( element ) {
996
- var method, value,
997
- rules = {}, $element = $( element );
1242
+ var rules = {},
1243
+ $element = $( element ),
1244
+ type = element.getAttribute( "type" ),
1245
+ method, value;
1246
+
998
1247
  for ( method in $.validator.methods ) {
999
1248
  value = $element.data( "rule" + method.charAt( 0 ).toUpperCase() + method.substring( 1 ).toLowerCase() );
1000
- if ( value !== undefined ) {
1001
- rules[ method ] = value;
1002
- }
1249
+ this.normalizeAttributeRule( rules, type, method, value );
1003
1250
  }
1004
1251
  return rules;
1005
1252
  },
@@ -1015,9 +1262,11 @@ $.extend( $.validator, {
1015
1262
  },
1016
1263
 
1017
1264
  normalizeRules: function( rules, element ) {
1018
- // handle dependency check
1265
+
1266
+ // Handle dependency check
1019
1267
  $.each( rules, function( prop, val ) {
1020
- // ignore rule when param is explicitly false, eg. required:false
1268
+
1269
+ // Ignore rule when param is explicitly false, eg. required:false
1021
1270
  if ( val === false ) {
1022
1271
  delete rules[ prop ];
1023
1272
  return;
@@ -1035,42 +1284,44 @@ $.extend( $.validator, {
1035
1284
  if ( keepRule ) {
1036
1285
  rules[ prop ] = val.param !== undefined ? val.param : true;
1037
1286
  } else {
1287
+ $.data( element.form, "validator" ).resetElements( $( element ) );
1038
1288
  delete rules[ prop ];
1039
1289
  }
1040
1290
  }
1041
- });
1291
+ } );
1042
1292
 
1043
- // evaluate parameters
1293
+ // Evaluate parameters
1044
1294
  $.each( rules, function( rule, parameter ) {
1045
- rules[ rule ] = $.isFunction( parameter ) ? parameter( element ) : parameter;
1046
- });
1295
+ rules[ rule ] = $.isFunction( parameter ) && rule !== "normalizer" ? parameter( element ) : parameter;
1296
+ } );
1047
1297
 
1048
- // clean number parameters
1049
- $.each([ "minlength", "maxlength" ], function() {
1298
+ // Clean number parameters
1299
+ $.each( [ "minlength", "maxlength" ], function() {
1050
1300
  if ( rules[ this ] ) {
1051
1301
  rules[ this ] = Number( rules[ this ] );
1052
1302
  }
1053
- });
1054
- $.each([ "rangelength", "range" ], function() {
1303
+ } );
1304
+ $.each( [ "rangelength", "range" ], function() {
1055
1305
  var parts;
1056
1306
  if ( rules[ this ] ) {
1057
1307
  if ( $.isArray( rules[ this ] ) ) {
1058
- rules[ this ] = [ Number( rules[ this ][ 0 ]), Number( rules[ this ][ 1 ] ) ];
1308
+ rules[ this ] = [ Number( rules[ this ][ 0 ] ), Number( rules[ this ][ 1 ] ) ];
1059
1309
  } else if ( typeof rules[ this ] === "string" ) {
1060
- parts = rules[ this ].replace(/[\[\]]/g, "" ).split( /[\s,]+/ );
1061
- rules[ this ] = [ Number( parts[ 0 ]), Number( parts[ 1 ] ) ];
1310
+ parts = rules[ this ].replace( /[\[\]]/g, "" ).split( /[\s,]+/ );
1311
+ rules[ this ] = [ Number( parts[ 0 ] ), Number( parts[ 1 ] ) ];
1062
1312
  }
1063
1313
  }
1064
- });
1314
+ } );
1065
1315
 
1066
1316
  if ( $.validator.autoCreateRanges ) {
1067
- // auto-create ranges
1068
- if ( rules.min && rules.max ) {
1317
+
1318
+ // Auto-create ranges
1319
+ if ( rules.min != null && rules.max != null ) {
1069
1320
  rules.range = [ rules.min, rules.max ];
1070
1321
  delete rules.min;
1071
1322
  delete rules.max;
1072
1323
  }
1073
- if ( rules.minlength && rules.maxlength ) {
1324
+ if ( rules.minlength != null && rules.maxlength != null ) {
1074
1325
  rules.rangelength = [ rules.minlength, rules.maxlength ];
1075
1326
  delete rules.minlength;
1076
1327
  delete rules.maxlength;
@@ -1086,13 +1337,13 @@ $.extend( $.validator, {
1086
1337
  var transformed = {};
1087
1338
  $.each( data.split( /\s/ ), function() {
1088
1339
  transformed[ this ] = true;
1089
- });
1340
+ } );
1090
1341
  data = transformed;
1091
1342
  }
1092
1343
  return data;
1093
1344
  },
1094
1345
 
1095
- // http://jqueryvalidation.org/jQuery.validator.addMethod/
1346
+ // https://jqueryvalidation.org/jQuery.validator.addMethod/
1096
1347
  addMethod: function( name, method, message ) {
1097
1348
  $.validator.methods[ name ] = method;
1098
1349
  $.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ];
@@ -1101,172 +1352,181 @@ $.extend( $.validator, {
1101
1352
  }
1102
1353
  },
1103
1354
 
1355
+ // https://jqueryvalidation.org/jQuery.validator.methods/
1104
1356
  methods: {
1105
1357
 
1106
- // http://jqueryvalidation.org/required-method/
1358
+ // https://jqueryvalidation.org/required-method/
1107
1359
  required: function( value, element, param ) {
1108
- // check if dependency is met
1360
+
1361
+ // Check if dependency is met
1109
1362
  if ( !this.depend( param, element ) ) {
1110
1363
  return "dependency-mismatch";
1111
1364
  }
1112
1365
  if ( element.nodeName.toLowerCase() === "select" ) {
1113
- // could be an array for select-multiple or a string, both are fine this way
1366
+
1367
+ // Could be an array for select-multiple or a string, both are fine this way
1114
1368
  var val = $( element ).val();
1115
1369
  return val && val.length > 0;
1116
1370
  }
1117
1371
  if ( this.checkable( element ) ) {
1118
1372
  return this.getLength( value, element ) > 0;
1119
1373
  }
1120
- return $.trim( value ).length > 0;
1374
+ return value.length > 0;
1121
1375
  },
1122
1376
 
1123
- // http://jqueryvalidation.org/email-method/
1377
+ // https://jqueryvalidation.org/email-method/
1124
1378
  email: function( value, element ) {
1125
- // From http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#e-mail-state-%28type=email%29
1379
+
1380
+ // From https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address
1126
1381
  // Retrieved 2014-01-14
1127
1382
  // If you have a problem with this implementation, report a bug against the above spec
1128
1383
  // Or use custom methods to implement your own email validation
1129
1384
  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 );
1130
1385
  },
1131
1386
 
1132
- // http://jqueryvalidation.org/url-method/
1387
+ // https://jqueryvalidation.org/url-method/
1133
1388
  url: function( value, element ) {
1134
- // contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/
1135
- 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 );
1389
+
1390
+ // Copyright (c) 2010-2013 Diego Perini, MIT licensed
1391
+ // https://gist.github.com/dperini/729294
1392
+ // see also https://mathiasbynens.be/demo/url-regex
1393
+ // modified to allow protocol-relative URLs
1394
+ return this.optional( element ) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test( value );
1136
1395
  },
1137
1396
 
1138
- // http://jqueryvalidation.org/date-method/
1397
+ // https://jqueryvalidation.org/date-method/
1139
1398
  date: function( value, element ) {
1140
1399
  return this.optional( element ) || !/Invalid|NaN/.test( new Date( value ).toString() );
1141
1400
  },
1142
1401
 
1143
- // http://jqueryvalidation.org/dateISO-method/
1402
+ // https://jqueryvalidation.org/dateISO-method/
1144
1403
  dateISO: function( value, element ) {
1145
1404
  return this.optional( element ) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test( value );
1146
1405
  },
1147
1406
 
1148
- // http://jqueryvalidation.org/number-method/
1407
+ // https://jqueryvalidation.org/number-method/
1149
1408
  number: function( value, element ) {
1150
- return this.optional( element ) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test( value );
1409
+ return this.optional( element ) || /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test( value );
1151
1410
  },
1152
1411
 
1153
- // http://jqueryvalidation.org/digits-method/
1412
+ // https://jqueryvalidation.org/digits-method/
1154
1413
  digits: function( value, element ) {
1155
1414
  return this.optional( element ) || /^\d+$/.test( value );
1156
1415
  },
1157
1416
 
1158
- // http://jqueryvalidation.org/creditcard-method/
1159
- // based on http://en.wikipedia.org/wiki/Luhn/
1160
- creditcard: function( value, element ) {
1161
- if ( this.optional( element ) ) {
1162
- return "dependency-mismatch";
1163
- }
1164
- // accept only spaces, digits and dashes
1165
- if ( /[^0-9 \-]+/.test( value ) ) {
1166
- return false;
1167
- }
1168
- var nCheck = 0,
1169
- nDigit = 0,
1170
- bEven = false,
1171
- n, cDigit;
1172
-
1173
- value = value.replace( /\D/g, "" );
1174
-
1175
- // Basing min and max length on
1176
- // http://developer.ean.com/general_info/Valid_Credit_Card_Types
1177
- if ( value.length < 13 || value.length > 19 ) {
1178
- return false;
1179
- }
1180
-
1181
- for ( n = value.length - 1; n >= 0; n--) {
1182
- cDigit = value.charAt( n );
1183
- nDigit = parseInt( cDigit, 10 );
1184
- if ( bEven ) {
1185
- if ( ( nDigit *= 2 ) > 9 ) {
1186
- nDigit -= 9;
1187
- }
1188
- }
1189
- nCheck += nDigit;
1190
- bEven = !bEven;
1191
- }
1192
-
1193
- return ( nCheck % 10 ) === 0;
1194
- },
1195
-
1196
- // http://jqueryvalidation.org/minlength-method/
1417
+ // https://jqueryvalidation.org/minlength-method/
1197
1418
  minlength: function( value, element, param ) {
1198
- var length = $.isArray( value ) ? value.length : this.getLength( $.trim( value ), element );
1419
+ var length = $.isArray( value ) ? value.length : this.getLength( value, element );
1199
1420
  return this.optional( element ) || length >= param;
1200
1421
  },
1201
1422
 
1202
- // http://jqueryvalidation.org/maxlength-method/
1423
+ // https://jqueryvalidation.org/maxlength-method/
1203
1424
  maxlength: function( value, element, param ) {
1204
- var length = $.isArray( value ) ? value.length : this.getLength( $.trim( value ), element );
1425
+ var length = $.isArray( value ) ? value.length : this.getLength( value, element );
1205
1426
  return this.optional( element ) || length <= param;
1206
1427
  },
1207
1428
 
1208
- // http://jqueryvalidation.org/rangelength-method/
1429
+ // https://jqueryvalidation.org/rangelength-method/
1209
1430
  rangelength: function( value, element, param ) {
1210
- var length = $.isArray( value ) ? value.length : this.getLength( $.trim( value ), element );
1431
+ var length = $.isArray( value ) ? value.length : this.getLength( value, element );
1211
1432
  return this.optional( element ) || ( length >= param[ 0 ] && length <= param[ 1 ] );
1212
1433
  },
1213
1434
 
1214
- // http://jqueryvalidation.org/min-method/
1435
+ // https://jqueryvalidation.org/min-method/
1215
1436
  min: function( value, element, param ) {
1216
1437
  return this.optional( element ) || value >= param;
1217
1438
  },
1218
1439
 
1219
- // http://jqueryvalidation.org/max-method/
1440
+ // https://jqueryvalidation.org/max-method/
1220
1441
  max: function( value, element, param ) {
1221
1442
  return this.optional( element ) || value <= param;
1222
1443
  },
1223
1444
 
1224
- // http://jqueryvalidation.org/range-method/
1445
+ // https://jqueryvalidation.org/range-method/
1225
1446
  range: function( value, element, param ) {
1226
1447
  return this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] );
1227
1448
  },
1228
1449
 
1229
- // http://jqueryvalidation.org/equalTo-method/
1450
+ // https://jqueryvalidation.org/step-method/
1451
+ step: function( value, element, param ) {
1452
+ var type = $( element ).attr( "type" ),
1453
+ errorMessage = "Step attribute on input type " + type + " is not supported.",
1454
+ supportedTypes = [ "text", "number", "range" ],
1455
+ re = new RegExp( "\\b" + type + "\\b" ),
1456
+ notSupported = type && !re.test( supportedTypes.join() ),
1457
+ decimalPlaces = function( num ) {
1458
+ var match = ( "" + num ).match( /(?:\.(\d+))?$/ );
1459
+ if ( !match ) {
1460
+ return 0;
1461
+ }
1462
+
1463
+ // Number of digits right of decimal point.
1464
+ return match[ 1 ] ? match[ 1 ].length : 0;
1465
+ },
1466
+ toInt = function( num ) {
1467
+ return Math.round( num * Math.pow( 10, decimals ) );
1468
+ },
1469
+ valid = true,
1470
+ decimals;
1471
+
1472
+ // Works only for text, number and range input types
1473
+ // TODO find a way to support input types date, datetime, datetime-local, month, time and week
1474
+ if ( notSupported ) {
1475
+ throw new Error( errorMessage );
1476
+ }
1477
+
1478
+ decimals = decimalPlaces( param );
1479
+
1480
+ // Value can't have too many decimals
1481
+ if ( decimalPlaces( value ) > decimals || toInt( value ) % toInt( param ) !== 0 ) {
1482
+ valid = false;
1483
+ }
1484
+
1485
+ return this.optional( element ) || valid;
1486
+ },
1487
+
1488
+ // https://jqueryvalidation.org/equalTo-method/
1230
1489
  equalTo: function( value, element, param ) {
1231
- // bind to the blur event of the target in order to revalidate whenever the target field is updated
1232
- // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead
1490
+
1491
+ // Bind to the blur event of the target in order to revalidate whenever the target field is updated
1233
1492
  var target = $( param );
1234
- if ( this.settings.onfocusout ) {
1235
- target.unbind( ".validate-equalTo" ).bind( "blur.validate-equalTo", function() {
1493
+ if ( this.settings.onfocusout && target.not( ".validate-equalTo-blur" ).length ) {
1494
+ target.addClass( "validate-equalTo-blur" ).on( "blur.validate-equalTo", function() {
1236
1495
  $( element ).valid();
1237
- });
1496
+ } );
1238
1497
  }
1239
1498
  return value === target.val();
1240
1499
  },
1241
1500
 
1242
- // http://jqueryvalidation.org/remote-method/
1243
- remote: function( value, element, param ) {
1501
+ // https://jqueryvalidation.org/remote-method/
1502
+ remote: function( value, element, param, method ) {
1244
1503
  if ( this.optional( element ) ) {
1245
1504
  return "dependency-mismatch";
1246
1505
  }
1247
1506
 
1248
- var previous = this.previousValue( element ),
1249
- validator, data;
1507
+ method = typeof method === "string" && method || "remote";
1508
+
1509
+ var previous = this.previousValue( element, method ),
1510
+ validator, data, optionDataString;
1250
1511
 
1251
- if (!this.settings.messages[ element.name ] ) {
1512
+ if ( !this.settings.messages[ element.name ] ) {
1252
1513
  this.settings.messages[ element.name ] = {};
1253
1514
  }
1254
- previous.originalMessage = this.settings.messages[ element.name ].remote;
1255
- this.settings.messages[ element.name ].remote = previous.message;
1515
+ previous.originalMessage = previous.originalMessage || this.settings.messages[ element.name ][ method ];
1516
+ this.settings.messages[ element.name ][ method ] = previous.message;
1256
1517
 
1257
1518
  param = typeof param === "string" && { url: param } || param;
1258
-
1259
- if ( previous.old === value ) {
1519
+ optionDataString = $.param( $.extend( { data: value }, param.data ) );
1520
+ if ( previous.old === optionDataString ) {
1260
1521
  return previous.valid;
1261
1522
  }
1262
1523
 
1263
- previous.old = value;
1524
+ previous.old = optionDataString;
1264
1525
  validator = this;
1265
1526
  this.startRequest( element );
1266
1527
  data = {};
1267
1528
  data[ element.name ] = value;
1268
1529
  $.ajax( $.extend( true, {
1269
- url: param,
1270
1530
  mode: "abort",
1271
1531
  port: "validate" + element.name,
1272
1532
  dataType: "json",
@@ -1276,18 +1536,19 @@ $.extend( $.validator, {
1276
1536
  var valid = response === true || response === "true",
1277
1537
  errors, message, submitted;
1278
1538
 
1279
- validator.settings.messages[ element.name ].remote = previous.originalMessage;
1539
+ validator.settings.messages[ element.name ][ method ] = previous.originalMessage;
1280
1540
  if ( valid ) {
1281
1541
  submitted = validator.formSubmitted;
1282
- validator.prepareElement( element );
1542
+ validator.resetInternals();
1543
+ validator.toHide = validator.errorsFor( element );
1283
1544
  validator.formSubmitted = submitted;
1284
1545
  validator.successList.push( element );
1285
- delete validator.invalid[ element.name ];
1546
+ validator.invalid[ element.name ] = false;
1286
1547
  validator.showErrors();
1287
1548
  } else {
1288
1549
  errors = {};
1289
- message = response || validator.defaultMessage( element, "remote" );
1290
- errors[ element.name ] = previous.message = $.isFunction( message ) ? message( value ) : message;
1550
+ message = response || validator.defaultMessage( element, { method: method, parameters: value } );
1551
+ errors[ element.name ] = previous.message = message;
1291
1552
  validator.invalid[ element.name ] = true;
1292
1553
  validator.showErrors( errors );
1293
1554
  }
@@ -1297,61 +1558,44 @@ $.extend( $.validator, {
1297
1558
  }, param ) );
1298
1559
  return "pending";
1299
1560
  }
1300
-
1301
1561
  }
1302
1562
 
1303
- });
1304
-
1305
- $.format = function deprecated() {
1306
- throw "$.format has been deprecated. Please use $.validator.format instead.";
1307
- };
1308
-
1309
- // ajax mode: abort
1563
+ } );
1564
+
1565
+ // Ajax mode: abort
1310
1566
  // usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
1311
1567
  // if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
1312
1568
 
1313
1569
  var pendingRequests = {},
1314
1570
  ajax;
1571
+
1315
1572
  // Use a prefilter if available (1.5+)
1316
1573
  if ( $.ajaxPrefilter ) {
1317
- $.ajaxPrefilter(function( settings, _, xhr ) {
1574
+ $.ajaxPrefilter( function( settings, _, xhr ) {
1318
1575
  var port = settings.port;
1319
1576
  if ( settings.mode === "abort" ) {
1320
- if ( pendingRequests[port] ) {
1321
- pendingRequests[port].abort();
1577
+ if ( pendingRequests[ port ] ) {
1578
+ pendingRequests[ port ].abort();
1322
1579
  }
1323
- pendingRequests[port] = xhr;
1580
+ pendingRequests[ port ] = xhr;
1324
1581
  }
1325
- });
1582
+ } );
1326
1583
  } else {
1584
+
1327
1585
  // Proxy ajax
1328
1586
  ajax = $.ajax;
1329
1587
  $.ajax = function( settings ) {
1330
1588
  var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
1331
1589
  port = ( "port" in settings ? settings : $.ajaxSettings ).port;
1332
1590
  if ( mode === "abort" ) {
1333
- if ( pendingRequests[port] ) {
1334
- pendingRequests[port].abort();
1591
+ if ( pendingRequests[ port ] ) {
1592
+ pendingRequests[ port ].abort();
1335
1593
  }
1336
- pendingRequests[port] = ajax.apply(this, arguments);
1337
- return pendingRequests[port];
1594
+ pendingRequests[ port ] = ajax.apply( this, arguments );
1595
+ return pendingRequests[ port ];
1338
1596
  }
1339
- return ajax.apply(this, arguments);
1597
+ return ajax.apply( this, arguments );
1340
1598
  };
1341
1599
  }
1342
-
1343
- // provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation
1344
- // handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target
1345
-
1346
- $.extend($.fn, {
1347
- validateDelegate: function( delegate, type, handler ) {
1348
- return this.bind(type, function( event ) {
1349
- var target = $(event.target);
1350
- if ( target.is(delegate) ) {
1351
- return handler.apply(target, arguments);
1352
- }
1353
- });
1354
- }
1355
- });
1356
-
1600
+ return $;
1357
1601
  }));