rademade_admin 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (186) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +5 -12
  3. data/app/assets/javascripts/rademade_admin/app/common/related-index.coffee +5 -24
  4. data/app/assets/javascripts/rademade_admin/form/form-ajax-submit.coffee +4 -0
  5. data/app/assets/javascripts/rademade_admin.coffee +28 -7
  6. data/app/assets/stylesheets/rademade_admin/detail_admin/icons.scss.erb +1 -1
  7. data/app/assets/stylesheets/rademade_admin.scss.erb +19 -0
  8. data/app/controllers/rademade_admin/abstract_controller.rb +2 -0
  9. data/app/controllers/rademade_admin/admin_users_controller.rb +2 -1
  10. data/app/controllers/rademade_admin/application_controller.rb +3 -0
  11. data/app/controllers/rademade_admin/dashboard_controller.rb +1 -1
  12. data/app/controllers/rademade_admin/model_controller.rb +48 -25
  13. data/app/controllers/rademade_admin/sessions_controller.rb +2 -1
  14. data/app/helpers/rademade_admin/field_helper.rb +30 -3
  15. data/app/helpers/rademade_admin/form_helper.rb +12 -18
  16. data/app/helpers/rademade_admin/menu_helper.rb +2 -1
  17. data/app/helpers/rademade_admin/name_helper.rb +2 -1
  18. data/app/helpers/rademade_admin/upload_preview_helper.rb +2 -1
  19. data/app/helpers/rademade_admin/uri_helper.rb +16 -0
  20. data/app/inputs/rademade_admin/admin_file_input.rb +2 -1
  21. data/app/inputs/rademade_admin/admin_select_input.rb +2 -1
  22. data/app/inputs/rademade_admin/admin_textarea_input.rb +2 -1
  23. data/app/inputs/rademade_admin/boolean_input.rb +2 -1
  24. data/app/models/rademade_admin/ability.rb +1 -1
  25. data/app/serializers/autocomplete/base_serializer.rb +49 -0
  26. data/app/serializers/autocomplete/link_serializer.rb +20 -0
  27. data/app/services/form_builder.rb +2 -1
  28. data/app/services/linker.rb +34 -0
  29. data/app/services/loader_service.rb +2 -1
  30. data/app/services/login/error.rb +2 -1
  31. data/app/services/login.rb +2 -1
  32. data/app/services/model_controller/instance_options.rb +1 -0
  33. data/app/services/model_controller/model_options.rb +2 -1
  34. data/app/services/model_controller/notifier.rb +2 -1
  35. data/app/services/model_controller/templates.rb +10 -12
  36. data/app/services/saver.rb +2 -1
  37. data/app/services/search/conditions/abstract.rb +42 -38
  38. data/app/services/search/conditions/autocomplete.rb +34 -28
  39. data/app/services/search/conditions/list.rb +30 -23
  40. data/app/services/search/conditions/part/where.rb +28 -0
  41. data/app/services/search/conditions/related_list.rb +54 -0
  42. data/app/services/search/query_adapter/abstract.rb +30 -39
  43. data/app/services/search/query_adapter/active_record.rb +33 -21
  44. data/app/services/search/query_adapter/mongoid.rb +38 -20
  45. data/app/services/search/searcher.rb +5 -4
  46. data/app/services/sortable_service.rb +2 -1
  47. data/app/services/video_service.rb +2 -1
  48. data/app/views/rademade_admin/_blocks/_menu.html.erb +7 -1
  49. data/app/views/rademade_admin/_blocks/_sub_menu.html.erb +0 -8
  50. data/app/views/rademade_admin/_layouts/inner/related_index_table.html.erb +1 -2
  51. data/app/views/rademade_admin/abstract/index.html.erb +6 -5
  52. data/app/views/rademade_admin/abstract/related_index.html.erb +11 -4
  53. data/config/initializers/bower_rails.rb +6 -0
  54. data/config/initializers/devise.rb +1 -0
  55. data/config/initializers/formtastic.rb +13 -0
  56. data/config/initializers/routes.rb +2 -1
  57. data/config/routes.rb +2 -1
  58. data/lib/rademade_admin/bower/performer.rb +14 -0
  59. data/lib/rademade_admin/configuration.rb +2 -1
  60. data/lib/rademade_admin/engine.rb +5 -1
  61. data/lib/rademade_admin/file_info_formatter.rb +2 -1
  62. data/lib/rademade_admin/hrml_buffer.rb +2 -1
  63. data/lib/rademade_admin/model/configuration/fields.rb +2 -1
  64. data/lib/rademade_admin/model/configuration.rb +2 -1
  65. data/lib/rademade_admin/model/data_adapter/active_record.rb +10 -4
  66. data/lib/rademade_admin/model/data_adapter/mongoid.rb +6 -1
  67. data/lib/rademade_admin/model/data_adapter.rb +6 -1
  68. data/lib/rademade_admin/model/graph.rb +2 -1
  69. data/lib/rademade_admin/model/info.rb +4 -3
  70. data/lib/rademade_admin/model/reflection/data.rb +2 -1
  71. data/lib/rademade_admin/model/reflection/uploader.rb +2 -2
  72. data/lib/rademade_admin/model/reflection.rb +5 -13
  73. data/lib/rademade_admin/routing/mapper.rb +4 -1
  74. data/lib/rademade_admin/routing/resource.rb +2 -1
  75. data/lib/rademade_admin/routing.rb +2 -1
  76. data/lib/rademade_admin/sortable.rb +1 -0
  77. data/lib/rademade_admin/uploader/photo.rb +2 -1
  78. data/lib/rademade_admin/uploader/video.rb +2 -1
  79. data/lib/rademade_admin/user.rb +1 -0
  80. data/lib/rademade_admin/version.rb +2 -1
  81. data/lib/rademade_admin.rb +8 -6
  82. data/lib/tasks/rademade_bower_install.rake +9 -0
  83. metadata +92 -339
  84. data/MIT-LICENSE +0 -20
  85. data/app/assets/fonts/rademade_admin/glyphicons-halflings-regular.eot +0 -0
  86. data/app/assets/fonts/rademade_admin/glyphicons-halflings-regular.svg +0 -228
  87. data/app/assets/fonts/rademade_admin/glyphicons-halflings-regular.ttf +0 -0
  88. data/app/assets/fonts/rademade_admin/glyphicons-halflings-regular.woff +0 -0
  89. data/app/assets/images/rademade_admin/datatables/back_disabled.png +0 -0
  90. data/app/assets/images/rademade_admin/datatables/back_enabled.png +0 -0
  91. data/app/assets/images/rademade_admin/datatables/back_enabled_hover.png +0 -0
  92. data/app/assets/images/rademade_admin/datatables/forward_disabled.png +0 -0
  93. data/app/assets/images/rademade_admin/datatables/forward_enabled.png +0 -0
  94. data/app/assets/images/rademade_admin/datatables/forward_enabled_hover.png +0 -0
  95. data/app/assets/images/rademade_admin/datatables/sort_asc.png +0 -0
  96. data/app/assets/images/rademade_admin/datatables/sort_asc_disabled.png +0 -0
  97. data/app/assets/images/rademade_admin/datatables/sort_both.png +0 -0
  98. data/app/assets/images/rademade_admin/datatables/sort_desc.png +0 -0
  99. data/app/assets/images/rademade_admin/datatables/sort_desc_disabled.png +0 -0
  100. data/app/assets/images/rademade_admin/jquery-ui/animated-overlay.gif +0 -0
  101. data/app/assets/images/rademade_admin/jquery-ui/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  102. data/app/assets/images/rademade_admin/jquery-ui/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  103. data/app/assets/images/rademade_admin/jquery-ui/ui-bg_flat_10_000000_40x100.png +0 -0
  104. data/app/assets/images/rademade_admin/jquery-ui/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  105. data/app/assets/images/rademade_admin/jquery-ui/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  106. data/app/assets/images/rademade_admin/jquery-ui/ui-bg_glass_65_ffffff_1x400.png +0 -0
  107. data/app/assets/images/rademade_admin/jquery-ui/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  108. data/app/assets/images/rademade_admin/jquery-ui/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  109. data/app/assets/images/rademade_admin/jquery-ui/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  110. data/app/assets/images/rademade_admin/jquery-ui/ui-icons_222222_256x240.png +0 -0
  111. data/app/assets/images/rademade_admin/jquery-ui/ui-icons_228ef1_256x240.png +0 -0
  112. data/app/assets/images/rademade_admin/jquery-ui/ui-icons_ef8c08_256x240.png +0 -0
  113. data/app/assets/images/rademade_admin/jquery-ui/ui-icons_ffd27a_256x240.png +0 -0
  114. data/app/assets/images/rademade_admin/jquery-ui/ui-icons_ffffff_256x240.png +0 -0
  115. data/app/assets/images/rademade_admin/select2/select2.png +0 -0
  116. data/app/assets/images/rademade_admin/select2/select2x2.png +0 -0
  117. data/app/assets/images/rademade_admin/select2/spinner.gif +0 -0
  118. data/app/assets/images/rademade_admin/uniform/bg-input-focus.png +0 -0
  119. data/app/assets/images/rademade_admin/uniform/bg-input.png +0 -0
  120. data/app/assets/images/rademade_admin/uniform/sprite.png +0 -0
  121. data/app/assets/javascripts/rademade_admin/form/library/jquery.form-serialize.js +0 -54
  122. data/app/assets/javascripts/rademade_admin/form/library/jquery.form.js +0 -1121
  123. data/app/assets/javascripts/rademade_admin/form/library/jquery.formrestrict.js +0 -27
  124. data/app/assets/javascripts/rademade_admin/form/library/jquery.validate.js +0 -1231
  125. data/app/assets/javascripts/rademade_admin/form/library/jquery.validate.messages_ru.js +0 -27
  126. data/app/assets/javascripts/rademade_admin/library/backbone.js +0 -1581
  127. data/app/assets/javascripts/rademade_admin/library/bootstrap/bootstrap.datepicker.js +0 -989
  128. data/app/assets/javascripts/rademade_admin/library/bootstrap/bootstrap.js +0 -1992
  129. data/app/assets/javascripts/rademade_admin/library/jquery/jquery-ui-1.10.4.custom.min.js +0 -6
  130. data/app/assets/javascripts/rademade_admin/library/jquery/jquery.dataTables.js +0 -12099
  131. data/app/assets/javascripts/rademade_admin/library/jquery/jquery.flot.js +0 -2960
  132. data/app/assets/javascripts/rademade_admin/library/jquery/jquery.flot.resize.js +0 -60
  133. data/app/assets/javascripts/rademade_admin/library/jquery/jquery.flot.stack.js +0 -188
  134. data/app/assets/javascripts/rademade_admin/library/jquery/jquery.knob.js +0 -661
  135. data/app/assets/javascripts/rademade_admin/library/jquery/jquery.uniform.min.js +0 -1
  136. data/app/assets/javascripts/rademade_admin/library/notifier.custom.js +0 -431
  137. data/app/assets/javascripts/rademade_admin/library/underscore.js +0 -1276
  138. data/app/assets/javascripts/rademade_admin/library/wysihtml5-0.3.0.js +0 -9463
  139. data/app/assets/stylesheets/rademade_admin/bootstrap/bootstrap.css.erb +0 -5911
  140. data/app/assets/stylesheets/rademade_admin/lib/jquery-ui-1.10.2.custom.css.erb +0 -544
  141. data/app/assets/stylesheets/rademade_admin/lib/select2.css.erb +0 -513
  142. data/app/assets/stylesheets/rademade_admin/lib/uniform.default.css.erb +0 -366
  143. data/app/assets/stylesheets/rademade_admin.css +0 -14
  144. data/app/models/rademade_admin/user.rb +0 -6
  145. data/app/serializers/autocomplete_serializer.rb +0 -46
  146. data/app/services/model_controller/linker.rb +0 -49
  147. data/test/dummy/README.rdoc +0 -28
  148. data/test/dummy/Rakefile +0 -6
  149. data/test/dummy/app/assets/javascripts/application.js +0 -13
  150. data/test/dummy/app/assets/stylesheets/application.css +0 -13
  151. data/test/dummy/app/controllers/application_controller.rb +0 -5
  152. data/test/dummy/app/controllers/rademade_admin/posts_controller.rb +0 -9
  153. data/test/dummy/app/controllers/rademade_admin/users_controller.rb +0 -14
  154. data/test/dummy/app/helpers/application_helper.rb +0 -2
  155. data/test/dummy/app/models/post.rb +0 -9
  156. data/test/dummy/app/models/user.rb +0 -7
  157. data/test/dummy/app/views/layouts/application.html.erb +0 -14
  158. data/test/dummy/bin/bundle +0 -3
  159. data/test/dummy/bin/rails +0 -4
  160. data/test/dummy/bin/rake +0 -4
  161. data/test/dummy/config/application.rb +0 -29
  162. data/test/dummy/config/boot.rb +0 -5
  163. data/test/dummy/config/environment.rb +0 -5
  164. data/test/dummy/config/environments/development.rb +0 -29
  165. data/test/dummy/config/environments/production.rb +0 -80
  166. data/test/dummy/config/environments/test.rb +0 -36
  167. data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
  168. data/test/dummy/config/initializers/filter_parameter_logging.rb +0 -4
  169. data/test/dummy/config/initializers/inflections.rb +0 -16
  170. data/test/dummy/config/initializers/mime_types.rb +0 -5
  171. data/test/dummy/config/initializers/rademade_admin.rb +0 -3
  172. data/test/dummy/config/initializers/secret_token.rb +0 -12
  173. data/test/dummy/config/initializers/session_store.rb +0 -3
  174. data/test/dummy/config/initializers/wrap_parameters.rb +0 -14
  175. data/test/dummy/config/locales/en.yml +0 -23
  176. data/test/dummy/config/mongoid.yml +0 -6
  177. data/test/dummy/config/routes.rb +0 -8
  178. data/test/dummy/config.ru +0 -4
  179. data/test/dummy/db/development.sqlite3 +0 -0
  180. data/test/dummy/public/404.html +0 -58
  181. data/test/dummy/public/422.html +0 -58
  182. data/test/dummy/public/500.html +0 -57
  183. data/test/dummy/public/favicon.ico +0 -0
  184. data/test/integration/navigation_test.rb +0 -10
  185. data/test/rademade_admin_test.rb +0 -7
  186. data/test/test_helper.rb +0 -15
@@ -1,27 +0,0 @@
1
- /*
2
- * Every time the form field is changed, sanitize its contents with the given
3
- * function to only allow input of a certain form.
4
- */
5
- (function ($) {
6
- var inputEvents = "input";
7
- if (!("oninput" in document || "oninput" in $("<input>")[0])) {
8
- inputEvents += " keypress keyup";
9
- }
10
-
11
- jQuery.fn.restrict = function(sanitizationFunc) {
12
- $(this).bind(inputEvents, function(e) {
13
- $(this).val(sanitizationFunc($(this).val()));
14
- });
15
- };
16
-
17
- /*
18
- * Every time the form field is changed, modify its contents by eliminating
19
- * matches for the given regular expression within the field.
20
- */
21
- jQuery.fn.regexRestrict = function(regex){
22
- var sanitize = function(text) {
23
- return text.replace(regex, '');
24
- };
25
- $(this).restrict(sanitize);
26
- }
27
- })(jQuery);
@@ -1,1231 +0,0 @@
1
- /*!
2
- * jQuery Validation Plugin 1.11.1
3
- *
4
- * http://bassistance.de/jquery-plugins/jquery-plugin-validation/
5
- * http://docs.jquery.com/Plugins/Validation
6
- *
7
- * Copyright 2013 Jörn Zaefferer
8
- * Released under the MIT license:
9
- * http://www.opensource.org/licenses/mit-license.php
10
- */
11
-
12
- (function($) {
13
-
14
- $.extend($.fn, {
15
- // http://docs.jquery.com/Plugins/Validation/validate
16
- validate: function( options ) {
17
-
18
- // if nothing is selected, return nothing; can't chain anyway
19
- if ( !this.length ) {
20
- if ( options && options.debug && window.console ) {
21
- console.warn( "Nothing selected, can't validate, returning nothing." );
22
- }
23
- return;
24
- }
25
-
26
- // check if a validator for this form was already created
27
- var validator = $.data( this[0], "validator" );
28
- if ( validator ) {
29
- return validator;
30
- }
31
-
32
- // Add novalidate tag if HTML5.
33
- this.attr( "novalidate", "novalidate" );
34
-
35
- validator = new $.validator( options, this[0] );
36
- $.data( this[0], "validator", validator );
37
-
38
- if ( validator.settings.onsubmit ) {
39
-
40
- this.validateDelegate( ":submit", "click", function( event ) {
41
- if ( validator.settings.submitHandler ) {
42
- validator.submitButton = event.target;
43
- }
44
- // allow suppressing validation by adding a cancel class to the submit button
45
- if ( $(event.target).hasClass("cancel") ) {
46
- validator.cancelSubmit = true;
47
- }
48
-
49
- // allow suppressing validation by adding the html5 formnovalidate attribute to the submit button
50
- if ( $(event.target).attr("formnovalidate") !== undefined ) {
51
- validator.cancelSubmit = true;
52
- }
53
- });
54
-
55
- // validate the form on submit
56
- this.submit( function( event ) {
57
- if ( validator.settings.debug ) {
58
- // prevent form submit to be able to see console output
59
- event.preventDefault();
60
- }
61
- function handle() {
62
- var hidden;
63
- if ( validator.settings.submitHandler ) {
64
- if ( validator.submitButton ) {
65
- // insert a hidden input as a replacement for the missing submit button
66
- hidden = $("<input type='hidden'/>").attr("name", validator.submitButton.name).val( $(validator.submitButton).val() ).appendTo(validator.currentForm);
67
- }
68
- validator.settings.submitHandler.call( validator, validator.currentForm, event );
69
- if ( validator.submitButton ) {
70
- // and clean up afterwards; thanks to no-block-scope, hidden can be referenced
71
- hidden.remove();
72
- }
73
- return false;
74
- }
75
- return true;
76
- }
77
-
78
- // prevent submit for invalid forms or custom submit handlers
79
- if ( validator.cancelSubmit ) {
80
- validator.cancelSubmit = false;
81
- return handle();
82
- }
83
- if ( validator.form() ) {
84
- if ( validator.pendingRequest ) {
85
- validator.formSubmitted = true;
86
- return false;
87
- }
88
- return handle();
89
- } else {
90
- validator.focusInvalid();
91
- return false;
92
- }
93
- });
94
- }
95
-
96
- return validator;
97
- },
98
- // http://docs.jquery.com/Plugins/Validation/valid
99
- valid: function() {
100
- if ( $(this[0]).is("form")) {
101
- return this.validate().form();
102
- } else {
103
- var valid = true;
104
- var validator = $(this[0].form).validate();
105
- this.each(function() {
106
- valid = valid && validator.element(this);
107
- });
108
- return valid;
109
- }
110
- },
111
- // attributes: space seperated list of attributes to retrieve and remove
112
- removeAttrs: function( attributes ) {
113
- var result = {},
114
- $element = this;
115
- $.each(attributes.split(/\s/), function( index, value ) {
116
- result[value] = $element.attr(value);
117
- $element.removeAttr(value);
118
- });
119
- return result;
120
- },
121
- // http://docs.jquery.com/Plugins/Validation/rules
122
- rules: function( command, argument ) {
123
- var element = this[0];
124
-
125
- if ( command ) {
126
- var settings = $.data(element.form, "validator").settings;
127
- var staticRules = settings.rules;
128
- var existingRules = $.validator.staticRules(element);
129
- switch(command) {
130
- case "add":
131
- $.extend(existingRules, $.validator.normalizeRule(argument));
132
- // remove messages from rules, but allow them to be set separetely
133
- delete existingRules.messages;
134
- staticRules[element.name] = existingRules;
135
- if ( argument.messages ) {
136
- settings.messages[element.name] = $.extend( settings.messages[element.name], argument.messages );
137
- }
138
- break;
139
- case "remove":
140
- if ( !argument ) {
141
- delete staticRules[element.name];
142
- return existingRules;
143
- }
144
- var filtered = {};
145
- $.each(argument.split(/\s/), function( index, method ) {
146
- filtered[method] = existingRules[method];
147
- delete existingRules[method];
148
- });
149
- return filtered;
150
- }
151
- }
152
-
153
- var data = $.validator.normalizeRules(
154
- $.extend(
155
- {},
156
- $.validator.classRules(element),
157
- $.validator.attributeRules(element),
158
- $.validator.dataRules(element),
159
- $.validator.staticRules(element)
160
- ), element);
161
-
162
- // make sure required is at front
163
- if ( data.required ) {
164
- var param = data.required;
165
- delete data.required;
166
- data = $.extend({required: param}, data);
167
- }
168
-
169
- return data;
170
- }
171
- });
172
-
173
- // Custom selectors
174
- $.extend($.expr[":"], {
175
- // http://docs.jquery.com/Plugins/Validation/blank
176
- blank: function( a ) { return !$.trim("" + $(a).val()); },
177
- // http://docs.jquery.com/Plugins/Validation/filled
178
- filled: function( a ) { return !!$.trim("" + $(a).val()); },
179
- // http://docs.jquery.com/Plugins/Validation/unchecked
180
- unchecked: function( a ) { return !$(a).prop("checked"); }
181
- });
182
-
183
- // constructor for validator
184
- $.validator = function( options, form ) {
185
- this.settings = $.extend( true, {}, $.validator.defaults, options );
186
- this.currentForm = form;
187
- this.init();
188
- };
189
-
190
- $.validator.format = function( source, params ) {
191
- if ( arguments.length === 1 ) {
192
- return function() {
193
- var args = $.makeArray(arguments);
194
- args.unshift(source);
195
- return $.validator.format.apply( this, args );
196
- };
197
- }
198
- if ( arguments.length > 2 && params.constructor !== Array ) {
199
- params = $.makeArray(arguments).slice(1);
200
- }
201
- if ( params.constructor !== Array ) {
202
- params = [ params ];
203
- }
204
- $.each(params, function( i, n ) {
205
- source = source.replace( new RegExp("\\{" + i + "\\}", "g"), function() {
206
- return n;
207
- });
208
- });
209
- return source;
210
- };
211
-
212
- $.extend($.validator, {
213
-
214
- defaults: {
215
- messages: {},
216
- groups: {},
217
- rules: {},
218
- errorClass: "error",
219
- validClass: "valid",
220
- errorElement: "label",
221
- focusInvalid: true,
222
- errorContainer: $([]),
223
- errorLabelContainer: $([]),
224
- onsubmit: true,
225
- ignore: ":hidden",
226
- ignoreTitle: false,
227
- onfocusin: function( element, event ) {
228
- this.lastActive = element;
229
-
230
- // hide error label and remove error class on focus if enabled
231
- if ( this.settings.focusCleanup && !this.blockFocusCleanup ) {
232
- if ( this.settings.unhighlight ) {
233
- this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );
234
- }
235
- this.addWrapper(this.errorsFor(element)).hide();
236
- }
237
- },
238
- onfocusout: function( element, event ) {
239
- if ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) {
240
- this.element(element);
241
- }
242
- },
243
- onkeyup: function( element, event ) {
244
- if ( event.which === 9 && this.elementValue(element) === "" ) {
245
- return;
246
- } else if ( element.name in this.submitted || element === this.lastElement ) {
247
- this.element(element);
248
- }
249
- },
250
- onclick: function( element, event ) {
251
- // click on selects, radiobuttons and checkboxes
252
- if ( element.name in this.submitted ) {
253
- this.element(element);
254
- }
255
- // or option elements, check parent select in that case
256
- else if ( element.parentNode.name in this.submitted ) {
257
- this.element(element.parentNode);
258
- }
259
- },
260
- highlight: function( element, errorClass, validClass ) {
261
- if ( element.type === "radio" ) {
262
- this.findByName(element.name).addClass(errorClass).removeClass(validClass);
263
- } else {
264
- $(element).addClass(errorClass).removeClass(validClass);
265
- }
266
- },
267
- unhighlight: function( element, errorClass, validClass ) {
268
- if ( element.type === "radio" ) {
269
- this.findByName(element.name).removeClass(errorClass).addClass(validClass);
270
- } else {
271
- $(element).removeClass(errorClass).addClass(validClass);
272
- }
273
- }
274
- },
275
-
276
- // http://docs.jquery.com/Plugins/Validation/Validator/setDefaults
277
- setDefaults: function( settings ) {
278
- $.extend( $.validator.defaults, settings );
279
- },
280
-
281
- messages: {
282
- required: "This field is required.",
283
- remote: "Please fix this field.",
284
- email: "Please enter a valid email address.",
285
- url: "Please enter a valid URL.",
286
- date: "Please enter a valid date.",
287
- dateISO: "Please enter a valid date (ISO).",
288
- number: "Please enter a valid number.",
289
- digits: "Please enter only digits.",
290
- creditcard: "Please enter a valid credit card number.",
291
- equalTo: "Please enter the same value again.",
292
- maxlength: $.validator.format("Please enter no more than {0} characters."),
293
- minlength: $.validator.format("Please enter at least {0} characters."),
294
- rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."),
295
- range: $.validator.format("Please enter a value between {0} and {1}."),
296
- max: $.validator.format("Please enter a value less than or equal to {0}."),
297
- min: $.validator.format("Please enter a value greater than or equal to {0}.")
298
- },
299
-
300
- autoCreateRanges: false,
301
-
302
- prototype: {
303
-
304
- init: function() {
305
- this.labelContainer = $(this.settings.errorLabelContainer);
306
- this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm);
307
- this.containers = $(this.settings.errorContainer).add( this.settings.errorLabelContainer );
308
- this.submitted = {};
309
- this.valueCache = {};
310
- this.pendingRequest = 0;
311
- this.pending = {};
312
- this.invalid = {};
313
- this.reset();
314
-
315
- var groups = (this.groups = {});
316
- $.each(this.settings.groups, function( key, value ) {
317
- if ( typeof value === "string" ) {
318
- value = value.split(/\s/);
319
- }
320
- $.each(value, function( index, name ) {
321
- groups[name] = key;
322
- });
323
- });
324
- var rules = this.settings.rules;
325
- $.each(rules, function( key, value ) {
326
- rules[key] = $.validator.normalizeRule(value);
327
- });
328
-
329
- function delegate(event) {
330
- var validator = $.data(this[0].form, "validator"),
331
- eventType = "on" + event.type.replace(/^validate/, "");
332
- if ( validator.settings[eventType] ) {
333
- validator.settings[eventType].call(validator, this[0], event);
334
- }
335
- }
336
- $(this.currentForm)
337
- .validateDelegate(":text, [type='password'], [type='file'], select, textarea, " +
338
- "[type='number'], [type='search'] ,[type='tel'], [type='url'], " +
339
- "[type='email'], [type='datetime'], [type='date'], [type='month'], " +
340
- "[type='week'], [type='time'], [type='datetime-local'], " +
341
- "[type='range'], [type='color'] ",
342
- "focusin focusout keyup", delegate)
343
- .validateDelegate("[type='radio'], [type='checkbox'], select, option", "click", delegate);
344
-
345
- if ( this.settings.invalidHandler ) {
346
- $(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler);
347
- }
348
- },
349
-
350
- // http://docs.jquery.com/Plugins/Validation/Validator/form
351
- form: function() {
352
- this.checkForm();
353
- $.extend(this.submitted, this.errorMap);
354
- this.invalid = $.extend({}, this.errorMap);
355
- if ( !this.valid() ) {
356
- $(this.currentForm).triggerHandler("invalid-form", [this]);
357
- }
358
- this.showErrors();
359
- return this.valid();
360
- },
361
-
362
- checkForm: function() {
363
- this.prepareForm();
364
- for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) {
365
- this.check( elements[i] );
366
- }
367
- return this.valid();
368
- },
369
-
370
- // http://docs.jquery.com/Plugins/Validation/Validator/element
371
- element: function( element ) {
372
- element = this.validationTargetFor( this.clean( element ) );
373
- this.lastElement = element;
374
- this.prepareElement( element );
375
- this.currentElements = $(element);
376
- var result = this.check( element ) !== false;
377
- if ( result ) {
378
- delete this.invalid[element.name];
379
- } else {
380
- this.invalid[element.name] = true;
381
- }
382
- if ( !this.numberOfInvalids() ) {
383
- // Hide error containers on last error
384
- this.toHide = this.toHide.add( this.containers );
385
- }
386
- this.showErrors();
387
- return result;
388
- },
389
-
390
- // http://docs.jquery.com/Plugins/Validation/Validator/showErrors
391
- showErrors: function( errors ) {
392
- if ( errors ) {
393
- // add items to error list and map
394
- $.extend( this.errorMap, errors );
395
- this.errorList = [];
396
- for ( var name in errors ) {
397
- this.errorList.push({
398
- message: errors[name],
399
- element: this.findByName(name)[0]
400
- });
401
- }
402
- // remove items from success list
403
- this.successList = $.grep( this.successList, function( element ) {
404
- return !(element.name in errors);
405
- });
406
- }
407
- if ( this.settings.showErrors ) {
408
- this.settings.showErrors.call( this, this.errorMap, this.errorList );
409
- } else {
410
- this.defaultShowErrors();
411
- }
412
- },
413
-
414
- // http://docs.jquery.com/Plugins/Validation/Validator/resetForm
415
- resetForm: function() {
416
- if ( $.fn.resetForm ) {
417
- $(this.currentForm).resetForm();
418
- }
419
- this.submitted = {};
420
- this.lastElement = null;
421
- this.prepareForm();
422
- this.hideErrors();
423
- this.elements().removeClass( this.settings.errorClass ).removeData( "previousValue" );
424
- },
425
-
426
- numberOfInvalids: function() {
427
- return this.objectLength(this.invalid);
428
- },
429
-
430
- objectLength: function( obj ) {
431
- var count = 0;
432
- for ( var i in obj ) {
433
- count++;
434
- }
435
- return count;
436
- },
437
-
438
- hideErrors: function() {
439
- this.addWrapper( this.toHide ).hide();
440
- },
441
-
442
- valid: function() {
443
- return this.size() === 0;
444
- },
445
-
446
- size: function() {
447
- return this.errorList.length;
448
- },
449
-
450
- focusInvalid: function() {
451
- if ( this.settings.focusInvalid ) {
452
- try {
453
- $(this.findLastActive() || this.errorList.length && this.errorList[0].element || [])
454
- .filter(":visible")
455
- .focus()
456
- // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
457
- .trigger("focusin");
458
- } catch(e) {
459
- // ignore IE throwing errors when focusing hidden elements
460
- }
461
- }
462
- },
463
-
464
- findLastActive: function() {
465
- var lastActive = this.lastActive;
466
- return lastActive && $.grep(this.errorList, function( n ) {
467
- return n.element.name === lastActive.name;
468
- }).length === 1 && lastActive;
469
- },
470
-
471
- elements: function() {
472
- var validator = this,
473
- rulesCache = {};
474
-
475
- // select all valid inputs inside the form (no submit or reset buttons)
476
- return $(this.currentForm)
477
- .find("input, select, textarea")
478
- .not(":submit, :reset, :image, [disabled]")
479
- .not( this.settings.ignore )
480
- .filter(function() {
481
- if ( !this.name && validator.settings.debug && window.console ) {
482
- console.error( "%o has no name assigned", this);
483
- }
484
-
485
- // select only the first element for each name, and only those with rules specified
486
- if ( this.name in rulesCache || !validator.objectLength($(this).rules()) ) {
487
- return false;
488
- }
489
-
490
- rulesCache[this.name] = true;
491
- return true;
492
- });
493
- },
494
-
495
- clean: function( selector ) {
496
- return $(selector)[0];
497
- },
498
-
499
- errors: function() {
500
- var errorClass = this.settings.errorClass.replace(" ", ".");
501
- return $(this.settings.errorElement + "." + errorClass, this.errorContext);
502
- },
503
-
504
- reset: function() {
505
- this.successList = [];
506
- this.errorList = [];
507
- this.errorMap = {};
508
- this.toShow = $([]);
509
- this.toHide = $([]);
510
- this.currentElements = $([]);
511
- },
512
-
513
- prepareForm: function() {
514
- this.reset();
515
- this.toHide = this.errors().add( this.containers );
516
- },
517
-
518
- prepareElement: function( element ) {
519
- this.reset();
520
- this.toHide = this.errorsFor(element);
521
- },
522
-
523
- elementValue: function( element ) {
524
- var type = $(element).attr("type"),
525
- val = $(element).val();
526
-
527
- if ( type === "radio" || type === "checkbox" ) {
528
- return $("input[name='" + $(element).attr("name") + "']:checked").val();
529
- }
530
-
531
- if ( typeof val === "string" ) {
532
- return val.replace(/\r/g, "");
533
- }
534
- return val;
535
- },
536
-
537
- check: function( element ) {
538
- element = this.validationTargetFor( this.clean( element ) );
539
-
540
- var rules = $(element).rules();
541
- var dependencyMismatch = false;
542
- var val = this.elementValue(element);
543
- var result;
544
-
545
- for (var method in rules ) {
546
- var rule = { method: method, parameters: rules[method] };
547
- try {
548
-
549
- result = $.validator.methods[method].call( this, val, element, rule.parameters );
550
-
551
- // if a method indicates that the field is optional and therefore valid,
552
- // don't mark it as valid when there are no other rules
553
- if ( result === "dependency-mismatch" ) {
554
- dependencyMismatch = true;
555
- continue;
556
- }
557
- dependencyMismatch = false;
558
-
559
- if ( result === "pending" ) {
560
- this.toHide = this.toHide.not( this.errorsFor(element) );
561
- return;
562
- }
563
-
564
- if ( !result ) {
565
- this.formatAndAdd( element, rule );
566
- return false;
567
- }
568
- } catch(e) {
569
- if ( this.settings.debug && window.console ) {
570
- console.log( "Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e );
571
- }
572
- throw e;
573
- }
574
- }
575
- if ( dependencyMismatch ) {
576
- return;
577
- }
578
- if ( this.objectLength(rules) ) {
579
- this.successList.push(element);
580
- }
581
- return true;
582
- },
583
-
584
- // return the custom message for the given element and validation method
585
- // specified in the element's HTML5 data attribute
586
- customDataMessage: function( element, method ) {
587
- return $(element).data("msg-" + method.toLowerCase()) || (element.attributes && $(element).attr("data-msg-" + method.toLowerCase()));
588
- },
589
-
590
- // return the custom message for the given element name and validation method
591
- customMessage: function( name, method ) {
592
- var m = this.settings.messages[name];
593
- return m && (m.constructor === String ? m : m[method]);
594
- },
595
-
596
- // return the first defined argument, allowing empty strings
597
- findDefined: function() {
598
- for(var i = 0; i < arguments.length; i++) {
599
- if ( arguments[i] !== undefined ) {
600
- return arguments[i];
601
- }
602
- }
603
- return undefined;
604
- },
605
-
606
- defaultMessage: function( element, method ) {
607
- return this.findDefined(
608
- this.customMessage( element.name, method ),
609
- this.customDataMessage( element, method ),
610
- // title is never undefined, so handle empty string as undefined
611
- !this.settings.ignoreTitle && element.title || undefined,
612
- $.validator.messages[method],
613
- "<strong>Warning: No message defined for " + element.name + "</strong>"
614
- );
615
- },
616
-
617
- formatAndAdd: function( element, rule ) {
618
- var message = this.defaultMessage( element, rule.method ),
619
- theregex = /\$?\{(\d+)\}/g;
620
- if ( typeof message === "function" ) {
621
- message = message.call(this, rule.parameters, element);
622
- } else if (theregex.test(message)) {
623
- message = $.validator.format(message.replace(theregex, "{$1}"), rule.parameters);
624
- }
625
- this.errorList.push({
626
- message: message,
627
- element: element
628
- });
629
-
630
- this.errorMap[element.name] = message;
631
- this.submitted[element.name] = message;
632
- },
633
-
634
- addWrapper: function( toToggle ) {
635
- if ( this.settings.wrapper ) {
636
- toToggle = toToggle.add( toToggle.parent() );
637
- }
638
- return toToggle;
639
- },
640
-
641
- defaultShowErrors: function() {
642
- var i, elements;
643
- for ( i = 0; this.errorList[i]; i++ ) {
644
- var error = this.errorList[i];
645
- if ( this.settings.highlight ) {
646
- this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );
647
- }
648
- this.showLabel( error.element, error.message );
649
- }
650
- if ( this.errorList.length ) {
651
- this.toShow = this.toShow.add( this.containers );
652
- }
653
- if ( this.settings.success ) {
654
- for ( i = 0; this.successList[i]; i++ ) {
655
- this.showLabel( this.successList[i] );
656
- }
657
- }
658
- if ( this.settings.unhighlight ) {
659
- for ( i = 0, elements = this.validElements(); elements[i]; i++ ) {
660
- this.settings.unhighlight.call( this, elements[i], this.settings.errorClass, this.settings.validClass );
661
- }
662
- }
663
- this.toHide = this.toHide.not( this.toShow );
664
- this.hideErrors();
665
- this.addWrapper( this.toShow ).show();
666
- },
667
-
668
- validElements: function() {
669
- return this.currentElements.not(this.invalidElements());
670
- },
671
-
672
- invalidElements: function() {
673
- return $(this.errorList).map(function() {
674
- return this.element;
675
- });
676
- },
677
-
678
- showLabel: function( element, message ) {
679
- var label = this.errorsFor( element );
680
- if ( label.length ) {
681
- // refresh error/success class
682
- label.removeClass( this.settings.validClass ).addClass( this.settings.errorClass );
683
- // replace message on existing label
684
- label.html(message);
685
- } else {
686
- // create label
687
- label = $("<" + this.settings.errorElement + ">")
688
- .attr("for", this.idOrName(element))
689
- .addClass(this.settings.errorClass)
690
- .html(message || "");
691
- if ( this.settings.wrapper ) {
692
- // make sure the element is visible, even in IE
693
- // actually showing the wrapped element is handled elsewhere
694
- label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent();
695
- }
696
- if ( !this.labelContainer.append(label).length ) {
697
- if ( this.settings.errorPlacement ) {
698
- this.settings.errorPlacement(label, $(element) );
699
- } else {
700
- label.insertAfter(element);
701
- }
702
- }
703
- }
704
- if ( !message && this.settings.success ) {
705
- label.text("");
706
- if ( typeof this.settings.success === "string" ) {
707
- label.addClass( this.settings.success );
708
- } else {
709
- this.settings.success( label, element );
710
- }
711
- }
712
- this.toShow = this.toShow.add(label);
713
- },
714
-
715
- errorsFor: function( element ) {
716
- var name = this.idOrName(element);
717
- return this.errors().filter(function() {
718
- return $(this).attr("for") === name;
719
- });
720
- },
721
-
722
- idOrName: function( element ) {
723
- return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name);
724
- },
725
-
726
- validationTargetFor: function( element ) {
727
- // if radio/checkbox, validate first element in group instead
728
- if ( this.checkable(element) ) {
729
- element = this.findByName( element.name ).not(this.settings.ignore)[0];
730
- }
731
- return element;
732
- },
733
-
734
- checkable: function( element ) {
735
- return (/radio|checkbox/i).test(element.type);
736
- },
737
-
738
- findByName: function( name ) {
739
- return $(this.currentForm).find("[name='" + name + "']");
740
- },
741
-
742
- getLength: function( value, element ) {
743
- switch( element.nodeName.toLowerCase() ) {
744
- case "select":
745
- return $("option:selected", element).length;
746
- case "input":
747
- if ( this.checkable( element) ) {
748
- return this.findByName(element.name).filter(":checked").length;
749
- }
750
- }
751
- return value.length;
752
- },
753
-
754
- depend: function( param, element ) {
755
- return this.dependTypes[typeof param] ? this.dependTypes[typeof param](param, element) : true;
756
- },
757
-
758
- dependTypes: {
759
- "boolean": function( param, element ) {
760
- return param;
761
- },
762
- "string": function( param, element ) {
763
- return !!$(param, element.form).length;
764
- },
765
- "function": function( param, element ) {
766
- return param(element);
767
- }
768
- },
769
-
770
- optional: function( element ) {
771
- var val = this.elementValue(element);
772
- return !$.validator.methods.required.call(this, val, element) && "dependency-mismatch";
773
- },
774
-
775
- startRequest: function( element ) {
776
- if ( !this.pending[element.name] ) {
777
- this.pendingRequest++;
778
- this.pending[element.name] = true;
779
- }
780
- },
781
-
782
- stopRequest: function( element, valid ) {
783
- this.pendingRequest--;
784
- // sometimes synchronization fails, make sure pendingRequest is never < 0
785
- if ( this.pendingRequest < 0 ) {
786
- this.pendingRequest = 0;
787
- }
788
- delete this.pending[element.name];
789
- if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) {
790
- $(this.currentForm).submit();
791
- this.formSubmitted = false;
792
- } else if (!valid && this.pendingRequest === 0 && this.formSubmitted) {
793
- $(this.currentForm).triggerHandler("invalid-form", [this]);
794
- this.formSubmitted = false;
795
- }
796
- },
797
-
798
- previousValue: function( element ) {
799
- return $.data(element, "previousValue") || $.data(element, "previousValue", {
800
- old: null,
801
- valid: true,
802
- message: this.defaultMessage( element, "remote" )
803
- });
804
- }
805
-
806
- },
807
-
808
- classRuleSettings: {
809
- required: {required: true},
810
- email: {email: true},
811
- url: {url: true},
812
- date: {date: true},
813
- dateISO: {dateISO: true},
814
- number: {number: true},
815
- digits: {digits: true},
816
- creditcard: {creditcard: true}
817
- },
818
-
819
- addClassRules: function( className, rules ) {
820
- if ( className.constructor === String ) {
821
- this.classRuleSettings[className] = rules;
822
- } else {
823
- $.extend(this.classRuleSettings, className);
824
- }
825
- },
826
-
827
- classRules: function( element ) {
828
- var rules = {};
829
- var classes = $(element).attr("class");
830
- if ( classes ) {
831
- $.each(classes.split(" "), function() {
832
- if ( this in $.validator.classRuleSettings ) {
833
- $.extend(rules, $.validator.classRuleSettings[this]);
834
- }
835
- });
836
- }
837
- return rules;
838
- },
839
-
840
- attributeRules: function( element ) {
841
- var rules = {};
842
- var $element = $(element);
843
- var type = $element[0].getAttribute("type");
844
-
845
- for (var method in $.validator.methods) {
846
- var value;
847
-
848
- // support for <input required> in both html5 and older browsers
849
- if ( method === "required" ) {
850
- value = $element.get(0).getAttribute(method);
851
- // Some browsers return an empty string for the required attribute
852
- // and non-HTML5 browsers might have required="" markup
853
- if ( value === "" ) {
854
- value = true;
855
- }
856
- // force non-HTML5 browsers to return bool
857
- value = !!value;
858
- } else {
859
- value = $element.attr(method);
860
- }
861
-
862
- // convert the value to a number for number inputs, and for text for backwards compability
863
- // allows type="date" and others to be compared as strings
864
- if ( /min|max/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) {
865
- value = Number(value);
866
- }
867
-
868
- if ( value ) {
869
- rules[method] = value;
870
- } else if ( type === method && type !== 'range' ) {
871
- // exception: the jquery validate 'range' method
872
- // does not test for the html5 'range' type
873
- rules[method] = true;
874
- }
875
- }
876
-
877
- // maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs
878
- if ( rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength) ) {
879
- delete rules.maxlength;
880
- }
881
-
882
- return rules;
883
- },
884
-
885
- dataRules: function( element ) {
886
- var method, value,
887
- rules = {}, $element = $(element);
888
- for (method in $.validator.methods) {
889
- value = $element.data("rule-" + method.toLowerCase());
890
- if ( value !== undefined ) {
891
- rules[method] = value;
892
- }
893
- }
894
- return rules;
895
- },
896
-
897
- staticRules: function( element ) {
898
- var rules = {};
899
- var validator = $.data(element.form, "validator");
900
- if ( validator.settings.rules ) {
901
- rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {};
902
- }
903
- return rules;
904
- },
905
-
906
- normalizeRules: function( rules, element ) {
907
- // handle dependency check
908
- $.each(rules, function( prop, val ) {
909
- // ignore rule when param is explicitly false, eg. required:false
910
- if ( val === false ) {
911
- delete rules[prop];
912
- return;
913
- }
914
- if ( val.param || val.depends ) {
915
- var keepRule = true;
916
- switch (typeof val.depends) {
917
- case "string":
918
- keepRule = !!$(val.depends, element.form).length;
919
- break;
920
- case "function":
921
- keepRule = val.depends.call(element, element);
922
- break;
923
- }
924
- if ( keepRule ) {
925
- rules[prop] = val.param !== undefined ? val.param : true;
926
- } else {
927
- delete rules[prop];
928
- }
929
- }
930
- });
931
-
932
- // evaluate parameters
933
- $.each(rules, function( rule, parameter ) {
934
- rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter;
935
- });
936
-
937
- // clean number parameters
938
- $.each(['minlength', 'maxlength'], function() {
939
- if ( rules[this] ) {
940
- rules[this] = Number(rules[this]);
941
- }
942
- });
943
- $.each(['rangelength', 'range'], function() {
944
- var parts;
945
- if ( rules[this] ) {
946
- if ( $.isArray(rules[this]) ) {
947
- rules[this] = [Number(rules[this][0]), Number(rules[this][1])];
948
- } else if ( typeof rules[this] === "string" ) {
949
- parts = rules[this].split(/[\s,]+/);
950
- rules[this] = [Number(parts[0]), Number(parts[1])];
951
- }
952
- }
953
- });
954
-
955
- if ( $.validator.autoCreateRanges ) {
956
- // auto-create ranges
957
- if ( rules.min && rules.max ) {
958
- rules.range = [rules.min, rules.max];
959
- delete rules.min;
960
- delete rules.max;
961
- }
962
- if ( rules.minlength && rules.maxlength ) {
963
- rules.rangelength = [rules.minlength, rules.maxlength];
964
- delete rules.minlength;
965
- delete rules.maxlength;
966
- }
967
- }
968
-
969
- return rules;
970
- },
971
-
972
- // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
973
- normalizeRule: function( data ) {
974
- if ( typeof data === "string" ) {
975
- var transformed = {};
976
- $.each(data.split(/\s/), function() {
977
- transformed[this] = true;
978
- });
979
- data = transformed;
980
- }
981
- return data;
982
- },
983
-
984
- // http://docs.jquery.com/Plugins/Validation/Validator/addMethod
985
- addMethod: function( name, method, message ) {
986
- $.validator.methods[name] = method;
987
- $.validator.messages[name] = message !== undefined ? message : $.validator.messages[name];
988
- if ( method.length < 3 ) {
989
- $.validator.addClassRules(name, $.validator.normalizeRule(name));
990
- }
991
- },
992
-
993
- methods: {
994
-
995
- // http://docs.jquery.com/Plugins/Validation/Methods/required
996
- required: function( value, element, param ) {
997
- // check if dependency is met
998
- if ( !this.depend(param, element) ) {
999
- return "dependency-mismatch";
1000
- }
1001
- if ( element.nodeName.toLowerCase() === "select" ) {
1002
- // could be an array for select-multiple or a string, both are fine this way
1003
- var val = $(element).val();
1004
- return val && val.length > 0;
1005
- }
1006
- if ( this.checkable(element) ) {
1007
- return this.getLength(value, element) > 0;
1008
- }
1009
- return $.trim(value).length > 0;
1010
- },
1011
-
1012
- // http://docs.jquery.com/Plugins/Validation/Methods/email
1013
- email: function( value, element ) {
1014
- // contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/
1015
- return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(value);
1016
- },
1017
-
1018
- // http://docs.jquery.com/Plugins/Validation/Methods/url
1019
- url: function( value, element ) {
1020
- // contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/
1021
- return this.optional(element) || /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);
1022
- },
1023
-
1024
- // http://docs.jquery.com/Plugins/Validation/Methods/date
1025
- date: function( value, element ) {
1026
- return this.optional(element) || !/Invalid|NaN/.test(new Date(value).toString());
1027
- },
1028
-
1029
- // http://docs.jquery.com/Plugins/Validation/Methods/dateISO
1030
- dateISO: function( value, element ) {
1031
- return this.optional(element) || /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/.test(value);
1032
- },
1033
-
1034
- // http://docs.jquery.com/Plugins/Validation/Methods/number
1035
- number: function( value, element ) {
1036
- return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value);
1037
- },
1038
-
1039
- // http://docs.jquery.com/Plugins/Validation/Methods/digits
1040
- digits: function( value, element ) {
1041
- return this.optional(element) || /^\d+$/.test(value);
1042
- },
1043
-
1044
- // http://docs.jquery.com/Plugins/Validation/Methods/creditcard
1045
- // based on http://en.wikipedia.org/wiki/Luhn
1046
- creditcard: function( value, element ) {
1047
- if ( this.optional(element) ) {
1048
- return "dependency-mismatch";
1049
- }
1050
- // accept only spaces, digits and dashes
1051
- if ( /[^0-9 \-]+/.test(value) ) {
1052
- return false;
1053
- }
1054
- var nCheck = 0,
1055
- nDigit = 0,
1056
- bEven = false;
1057
-
1058
- value = value.replace(/\D/g, "");
1059
-
1060
- for (var n = value.length - 1; n >= 0; n--) {
1061
- var cDigit = value.charAt(n);
1062
- nDigit = parseInt(cDigit, 10);
1063
- if ( bEven ) {
1064
- if ( (nDigit *= 2) > 9 ) {
1065
- nDigit -= 9;
1066
- }
1067
- }
1068
- nCheck += nDigit;
1069
- bEven = !bEven;
1070
- }
1071
-
1072
- return (nCheck % 10) === 0;
1073
- },
1074
-
1075
- // http://docs.jquery.com/Plugins/Validation/Methods/minlength
1076
- minlength: function( value, element, param ) {
1077
- var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element);
1078
- return this.optional(element) || length >= param;
1079
- },
1080
-
1081
- // http://docs.jquery.com/Plugins/Validation/Methods/maxlength
1082
- maxlength: function( value, element, param ) {
1083
- var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element);
1084
- return this.optional(element) || length <= param;
1085
- },
1086
-
1087
- // http://docs.jquery.com/Plugins/Validation/Methods/rangelength
1088
- rangelength: function( value, element, param ) {
1089
- var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element);
1090
- return this.optional(element) || ( length >= param[0] && length <= param[1] );
1091
- },
1092
-
1093
- // http://docs.jquery.com/Plugins/Validation/Methods/min
1094
- min: function( value, element, param ) {
1095
- return this.optional(element) || value >= param;
1096
- },
1097
-
1098
- // http://docs.jquery.com/Plugins/Validation/Methods/max
1099
- max: function( value, element, param ) {
1100
- return this.optional(element) || value <= param;
1101
- },
1102
-
1103
- // http://docs.jquery.com/Plugins/Validation/Methods/range
1104
- range: function( value, element, param ) {
1105
- return this.optional(element) || ( value >= param[0] && value <= param[1] );
1106
- },
1107
-
1108
- // http://docs.jquery.com/Plugins/Validation/Methods/equalTo
1109
- equalTo: function( value, element, param ) {
1110
- // bind to the blur event of the target in order to revalidate whenever the target field is updated
1111
- // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead
1112
- var target = $(param);
1113
- if ( this.settings.onfocusout ) {
1114
- target.unbind(".validate-equalTo").bind("blur.validate-equalTo", function() {
1115
- $(element).valid();
1116
- });
1117
- }
1118
- return value === target.val();
1119
- },
1120
-
1121
- // http://docs.jquery.com/Plugins/Validation/Methods/remote
1122
- remote: function( value, element, param ) {
1123
- if ( this.optional(element) ) {
1124
- return "dependency-mismatch";
1125
- }
1126
-
1127
- var previous = this.previousValue(element);
1128
- if (!this.settings.messages[element.name] ) {
1129
- this.settings.messages[element.name] = {};
1130
- }
1131
- previous.originalMessage = this.settings.messages[element.name].remote;
1132
- this.settings.messages[element.name].remote = previous.message;
1133
-
1134
- param = typeof param === "string" && {url:param} || param;
1135
-
1136
- if ( previous.old === value ) {
1137
- return previous.valid;
1138
- }
1139
-
1140
- previous.old = value;
1141
- var validator = this;
1142
- this.startRequest(element);
1143
- var data = {};
1144
- data[element.name] = value;
1145
- $.ajax($.extend(true, {
1146
- url: param,
1147
- mode: "abort",
1148
- port: "validate" + element.name,
1149
- dataType: "json",
1150
- data: data,
1151
- success: function( response ) {
1152
- validator.settings.messages[element.name].remote = previous.originalMessage;
1153
- var valid = response === true || response === "true";
1154
- if ( valid ) {
1155
- var submitted = validator.formSubmitted;
1156
- validator.prepareElement(element);
1157
- validator.formSubmitted = submitted;
1158
- validator.successList.push(element);
1159
- delete validator.invalid[element.name];
1160
- validator.showErrors();
1161
- } else {
1162
- var errors = {};
1163
- var message = response || validator.defaultMessage( element, "remote" );
1164
- errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message;
1165
- validator.invalid[element.name] = true;
1166
- validator.showErrors(errors);
1167
- }
1168
- previous.valid = valid;
1169
- validator.stopRequest(element, valid);
1170
- }
1171
- }, param));
1172
- return "pending";
1173
- }
1174
-
1175
- }
1176
-
1177
- });
1178
-
1179
- // deprecated, use $.validator.format instead
1180
- $.format = $.validator.format;
1181
-
1182
- }(jQuery));
1183
-
1184
- // ajax mode: abort
1185
- // usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
1186
- // if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
1187
- (function($) {
1188
- var pendingRequests = {};
1189
- // Use a prefilter if available (1.5+)
1190
- if ( $.ajaxPrefilter ) {
1191
- $.ajaxPrefilter(function( settings, _, xhr ) {
1192
- var port = settings.port;
1193
- if ( settings.mode === "abort" ) {
1194
- if ( pendingRequests[port] ) {
1195
- pendingRequests[port].abort();
1196
- }
1197
- pendingRequests[port] = xhr;
1198
- }
1199
- });
1200
- } else {
1201
- // Proxy ajax
1202
- var ajax = $.ajax;
1203
- $.ajax = function( settings ) {
1204
- var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
1205
- port = ( "port" in settings ? settings : $.ajaxSettings ).port;
1206
- if ( mode === "abort" ) {
1207
- if ( pendingRequests[port] ) {
1208
- pendingRequests[port].abort();
1209
- }
1210
- pendingRequests[port] = ajax.apply(this, arguments);
1211
- return pendingRequests[port];
1212
- }
1213
- return ajax.apply(this, arguments);
1214
- };
1215
- }
1216
- }(jQuery));
1217
-
1218
- // provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation
1219
- // handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target
1220
- (function($) {
1221
- $.extend($.fn, {
1222
- validateDelegate: function( delegate, type, handler ) {
1223
- return this.bind(type, function( event ) {
1224
- var target = $(event.target);
1225
- if ( target.is(delegate) ) {
1226
- return handler.apply(target, arguments);
1227
- }
1228
- });
1229
- }
1230
- });
1231
- }(jQuery));