surveyor_gui 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (283) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +44 -0
  3. data/.travis.yml +17 -0
  4. data/Gemfile +7 -0
  5. data/LICENSE +21 -0
  6. data/MIT-LICENSE +20 -0
  7. data/README.md +159 -0
  8. data/Rakefile +66 -0
  9. data/app/controllers/answers_controller.rb +3 -0
  10. data/app/controllers/application_controller.rb +3 -0
  11. data/app/controllers/dependencys_controller.rb +286 -0
  12. data/app/controllers/question_groups_controller.rb +84 -0
  13. data/app/controllers/questions_controller.rb +187 -0
  14. data/app/controllers/survey_sections_controller.rb +80 -0
  15. data/app/controllers/surveyforms_controller.rb +4 -0
  16. data/app/controllers/surveyor_controller.rb +89 -0
  17. data/app/controllers/surveyor_gui/reports_controller.rb +339 -0
  18. data/app/controllers/surveyor_gui/responses_controller.rb +39 -0
  19. data/app/controllers/surveyor_gui/survey_controller.rb +16 -0
  20. data/app/facades/report_formatter.rb +44 -0
  21. data/app/facades/report_preview_wrapper.rb +11 -0
  22. data/app/facades/report_response_generator.rb +147 -0
  23. data/app/helpers/application_helper.rb +2 -0
  24. data/app/helpers/dependency_helper.rb +5 -0
  25. data/app/helpers/question_helper.rb +22 -0
  26. data/app/helpers/surveyform_helper.rb +179 -0
  27. data/app/helpers/surveyor_gui/report_helper.rb +19 -0
  28. data/app/helpers/surveyor_helper.rb +4 -0
  29. data/app/inputs/currency_input.rb +5 -0
  30. data/app/inputs/date_picker_input.rb +7 -0
  31. data/app/inputs/datetime_picker_input.rb +5 -0
  32. data/app/inputs/percent_input.rb +5 -0
  33. data/app/inputs/time_picker_input.rb +5 -0
  34. data/app/mailers/.gitkeep +0 -0
  35. data/app/models/.gitkeep +0 -0
  36. data/app/models/answer.rb +4 -0
  37. data/app/models/column.rb +3 -0
  38. data/app/models/dependency.rb +4 -0
  39. data/app/models/dependency_condition.rb +4 -0
  40. data/app/models/permitted_params_decorator.rb +80 -0
  41. data/app/models/question.rb +4 -0
  42. data/app/models/question_group.rb +4 -0
  43. data/app/models/question_type.rb +7 -0
  44. data/app/models/response.rb +4 -0
  45. data/app/models/response_set.rb +4 -0
  46. data/app/models/row.rb +3 -0
  47. data/app/models/survey.rb +4 -0
  48. data/app/models/survey_section.rb +4 -0
  49. data/app/models/surveyform.rb +103 -0
  50. data/app/uploaders/blob_uploader.rb +48 -0
  51. data/app/views/dependencys/_column.html.erb +1 -0
  52. data/app/views/dependencys/_dependency.html.erb +22 -0
  53. data/app/views/dependencys/_dependency_condition_fields.html.erb +48 -0
  54. data/app/views/dependencys/_form.html.erb +20 -0
  55. data/app/views/dependencys/blank.html.erb +0 -0
  56. data/app/views/dependencys/edit.html.erb +1 -0
  57. data/app/views/dependencys/new.html.erb +1 -0
  58. data/app/views/layouts/application.html.erb +14 -0
  59. data/app/views/layouts/surveyor_gui_blank.html.erb +12 -0
  60. data/app/views/layouts/surveyor_gui_default.html.erb +16 -0
  61. data/app/views/layouts/surveyor_modified.html.erb +14 -0
  62. data/app/views/partials/_answer.html.haml +33 -0
  63. data/app/views/partials/_question.html.haml +33 -0
  64. data/app/views/partials/_question_group.html.haml +73 -0
  65. data/app/views/partials/_section.html.haml +13 -0
  66. data/app/views/question_groups/_form.html.erb +56 -0
  67. data/app/views/question_groups/_group_inline_field.html.erb +21 -0
  68. data/app/views/question_groups/_group_inline_fields.html.erb +25 -0
  69. data/app/views/question_groups/blank.html.erb +0 -0
  70. data/app/views/question_groups/edit.html.erb +1 -0
  71. data/app/views/question_groups/new.html.erb +1 -0
  72. data/app/views/questions/_answer_fields.html.erb +23 -0
  73. data/app/views/questions/_answer_options.html.erb +28 -0
  74. data/app/views/questions/_form.html.erb +65 -0
  75. data/app/views/questions/_grid_dropdown_columns.html.erb +10 -0
  76. data/app/views/questions/_grid_dropdown_fields.html.erb +42 -0
  77. data/app/views/questions/_grid_fields.html.erb +9 -0
  78. data/app/views/questions/_no_picks.html.erb +29 -0
  79. data/app/views/questions/_pick.html +21 -0
  80. data/app/views/questions/_picks.html.erb +12 -0
  81. data/app/views/questions/blank.html.erb +0 -0
  82. data/app/views/questions/edit.html.erb +1 -0
  83. data/app/views/questions/new.html.erb +1 -0
  84. data/app/views/survey_sections/_form.html.erb +13 -0
  85. data/app/views/survey_sections/blank.html.erb +0 -0
  86. data/app/views/survey_sections/edit.html.erb +1 -0
  87. data/app/views/survey_sections/new.html.erb +1 -0
  88. data/app/views/surveyforms/_form.html.erb +50 -0
  89. data/app/views/surveyforms/_question_field.html.erb +148 -0
  90. data/app/views/surveyforms/_question_group.html.erb +116 -0
  91. data/app/views/surveyforms/_question_group_fields.html.erb +3 -0
  92. data/app/views/surveyforms/_question_name_and_number.html.erb +6 -0
  93. data/app/views/surveyforms/_question_section.html.erb +15 -0
  94. data/app/views/surveyforms/_question_wrapper.html.erb +109 -0
  95. data/app/views/surveyforms/_survey_section_fields.html.erb +138 -0
  96. data/app/views/surveyforms/clone_survey.html.erb +13 -0
  97. data/app/views/surveyforms/edit.html.erb +5 -0
  98. data/app/views/surveyforms/index.html.erb +40 -0
  99. data/app/views/surveyforms/new.html.erb +1 -0
  100. data/app/views/surveyforms/show.html.erb +5 -0
  101. data/app/views/surveyor_gui/reports/_graphs.html.haml +21 -0
  102. data/app/views/surveyor_gui/reports/_grid.html.haml +42 -0
  103. data/app/views/surveyor_gui/reports/_grid_dropdown.html.haml +56 -0
  104. data/app/views/surveyor_gui/reports/_repeater.html.haml +28 -0
  105. data/app/views/surveyor_gui/reports/_show_report.html.haml +33 -0
  106. data/app/views/surveyor_gui/reports/_single_question.html.haml +70 -0
  107. data/app/views/surveyor_gui/reports/show.html.erb +14 -0
  108. data/app/views/surveyor_gui/responses/_grid.html.haml +20 -0
  109. data/app/views/surveyor_gui/responses/_grid_dropdown.html.haml +20 -0
  110. data/app/views/surveyor_gui/responses/_repeater.html.haml +22 -0
  111. data/app/views/surveyor_gui/responses/_survey_results.html.haml +40 -0
  112. data/app/views/surveyor_gui/responses/index.html.haml +24 -0
  113. data/app/views/surveyor_gui/responses/show.html.haml +42 -0
  114. data/app/views/surveyor_gui/shared/_grid_comments.html.haml +10 -0
  115. data/app/views/surveyor_gui/shared/_new_line.html.haml +2 -0
  116. data/app/views/surveyor_gui/shared/_pick_comments.html.haml +15 -0
  117. data/app/views/surveyor_gui/shared/_question_number.html.haml +9 -0
  118. data/app/views/surveyor_gui/shared/_report_data.html.haml +24 -0
  119. data/app/views/surveyor_gui/shared/_stars_report_data.html.haml +14 -0
  120. data/config.ru +4 -0
  121. data/config/environment.rb +0 -0
  122. data/config/routes.rb +71 -0
  123. data/db/migrate/20140307204049_add_template_to_surveys.rb +5 -0
  124. data/db/migrate/20140307235607_add_test_data_to_response_sets.rb +5 -0
  125. data/db/migrate/20140308171947_add_original_choice_to_answers.rb +5 -0
  126. data/db/migrate/20140308172118_add_blob_to_responses.rb +5 -0
  127. data/db/migrate/20140308172417_add_modifiable_to_survey_section.rb +5 -0
  128. data/db/migrate/20140308174532_add_modifiable_to_question.rb +5 -0
  129. data/db/migrate/20140308175305_add_dynamically_generate_to_questions.rb +5 -0
  130. data/db/migrate/20140311032923_add_dummy_blob_to_questions.rb +5 -0
  131. data/db/migrate/20140311160609_add_dynamic_source_to_questions.rb +5 -0
  132. data/db/migrate/20140311161714_add_report_code_to_questions.rb +5 -0
  133. data/db/migrate/20140530181134_add_is_comment_to_questions.rb +5 -0
  134. data/db/migrate/20140531012006_add_is_comment_to_answers.rb +5 -0
  135. data/db/migrate/20140531225529_create_rows.rb +9 -0
  136. data/db/migrate/20140601011151_create_columns.rb +11 -0
  137. data/db/migrate/20140602030330_add_column_id_to_answers.rb +5 -0
  138. data/db/migrate/20140603155606_add_column_id_to_responses.rb +5 -0
  139. data/db/migrate/20140606023527_add_column_id_to_dependency_conditions.rb +5 -0
  140. data/db/migrate/20140815165307_add_user_id_to_survey.rb +5 -0
  141. data/lib/assets/.gitkeep +0 -0
  142. data/lib/assets/images/addicon.png +0 -0
  143. data/lib/assets/images/datepicker.gif +0 -0
  144. data/lib/assets/images/delete.gif +0 -0
  145. data/lib/assets/images/delete.png +0 -0
  146. data/lib/assets/images/images/border.png +0 -0
  147. data/lib/assets/images/images/controls.png +0 -0
  148. data/lib/assets/images/images/loading.gif +0 -0
  149. data/lib/assets/images/images/loading_background.png +0 -0
  150. data/lib/assets/images/images/overlay.png +0 -0
  151. data/lib/assets/images/rails.png +0 -0
  152. data/lib/assets/images/star.gif +0 -0
  153. data/lib/assets/javascripts/.gitkeep +0 -0
  154. data/lib/assets/javascripts/surveyor_gui/jquery.MetaData.js +121 -0
  155. data/lib/assets/javascripts/surveyor_gui/jquery.blockUI.js +619 -0
  156. data/lib/assets/javascripts/surveyor_gui/jquery.rating.js +377 -0
  157. data/lib/assets/javascripts/surveyor_gui/jquery.validate.js +1188 -0
  158. data/lib/assets/javascripts/surveyor_gui/surveyor_add_ons.js +10 -0
  159. data/lib/assets/javascripts/surveyor_gui/surveyor_gui.js +1417 -0
  160. data/lib/assets/stylesheets/.gitkeep +0 -0
  161. data/lib/assets/stylesheets/surveyor_gui/jquery.rating.css +12 -0
  162. data/lib/assets/stylesheets/surveyor_gui/surveyor_add_ons.css +3 -0
  163. data/lib/assets/stylesheets/surveyor_gui/surveyor_gui.sass +650 -0
  164. data/lib/enumerable_extenders.rb +31 -0
  165. data/lib/generators/surveyor_gui/install_generator.rb +57 -0
  166. data/lib/generators/surveyor_gui/templates/app/assets/javascripts/surveyor_add_ons.js +2 -0
  167. data/lib/generators/surveyor_gui/templates/app/assets/javascripts/surveyor_gui_all.js +24 -0
  168. data/lib/generators/surveyor_gui/templates/app/assets/stylesheets/surveyor_add_ons.css.sass +1 -0
  169. data/lib/generators/surveyor_gui/templates/app/assets/stylesheets/surveyor_gui_all.css.sass +8 -0
  170. data/lib/generators/surveyor_gui/templates/app/helpers/surveyor_helper.rb +4 -0
  171. data/lib/generators/surveyor_gui/templates/app/models/response_set_user.rb +13 -0
  172. data/lib/generators/surveyor_gui/templates/app/views/layouts/surveyor_gui_default.html.erb +16 -0
  173. data/lib/generators/surveyor_gui/templates/config/initializers/simple_form.rb +140 -0
  174. data/lib/generators/surveyor_gui/templates/config/locales/en.yml +5 -0
  175. data/lib/surveyor_gui.rb +17 -0
  176. data/lib/surveyor_gui/engine.rb +30 -0
  177. data/lib/surveyor_gui/helpers/surveyor_helper_methods.rb +19 -0
  178. data/lib/surveyor_gui/models/answer_methods.rb +24 -0
  179. data/lib/surveyor_gui/models/column_methods.rb +43 -0
  180. data/lib/surveyor_gui/models/dependency_condition_methods.rb +53 -0
  181. data/lib/surveyor_gui/models/dependency_methods.rb +83 -0
  182. data/lib/surveyor_gui/models/question_and_group_shared_methods.rb +11 -0
  183. data/lib/surveyor_gui/models/question_group_methods.rb +55 -0
  184. data/lib/surveyor_gui/models/question_methods.rb +435 -0
  185. data/lib/surveyor_gui/models/question_type_methods.rb +493 -0
  186. data/lib/surveyor_gui/models/response_methods.rb +67 -0
  187. data/lib/surveyor_gui/models/response_set_methods.rb +54 -0
  188. data/lib/surveyor_gui/models/row_methods.rb +11 -0
  189. data/lib/surveyor_gui/models/survey_methods.rb +32 -0
  190. data/lib/surveyor_gui/models/survey_section_methods.rb +32 -0
  191. data/lib/surveyor_gui/surveyforms_controller_methods.rb +258 -0
  192. data/lib/surveyor_gui/version.rb +3 -0
  193. data/lib/tasks/.gitkeep +0 -0
  194. data/lib/tasks/surveyor_gui_tasks.rake +4 -0
  195. data/lib/templates/erb/scaffold/_form.html.erb +13 -0
  196. data/spec/controllers/surveyforms_controller_spec.rb +361 -0
  197. data/spec/controllers/surveyor_controller_spec.rb +303 -0
  198. data/spec/factories.rb +181 -0
  199. data/spec/features/create_survey_spec.rb +418 -0
  200. data/spec/features/dependencies_spec.rb +61 -0
  201. data/spec/features/rearrange_survey_spec.rb +118 -0
  202. data/spec/features/ui_spec.rb +469 -0
  203. data/spec/fixtures/REDCapDemoDatabase_DataDictionary.csv +127 -0
  204. data/spec/fixtures/chinese_survey.rb +14 -0
  205. data/spec/fixtures/everything.rb +215 -0
  206. data/spec/fixtures/favorites-ish.rb +22 -0
  207. data/spec/fixtures/favorites.rb +22 -0
  208. data/spec/fixtures/feelings.rb +38 -0
  209. data/spec/fixtures/lifestyle.rb +55 -0
  210. data/spec/fixtures/numbers.rb +21 -0
  211. data/spec/fixtures/redcap_new_headers.csv +1 -0
  212. data/spec/fixtures/redcap_siblings.csv +1 -0
  213. data/spec/fixtures/redcap_whitespace.csv +1 -0
  214. data/spec/helpers/formtastic_custom_input_spec.rb +15 -0
  215. data/spec/helpers/surveyor_helper_spec.rb +116 -0
  216. data/spec/lib/common_spec.rb +37 -0
  217. data/spec/lib/parser_spec.rb +393 -0
  218. data/spec/lib/rake_kitchen_sink.rb +42 -0
  219. data/spec/lib/redcap_parser_spec.rb +129 -0
  220. data/spec/lib/unparser_spec.rb +126 -0
  221. data/spec/models/answer_spec.rb +144 -0
  222. data/spec/models/dependency_condition_spec.rb +428 -0
  223. data/spec/models/dependency_spec.rb +90 -0
  224. data/spec/models/question_group_spec.rb +66 -0
  225. data/spec/models/question_spec.rb +176 -0
  226. data/spec/models/response_set_spec.rb +452 -0
  227. data/spec/models/response_spec.rb +208 -0
  228. data/spec/models/survey_section_spec.rb +58 -0
  229. data/spec/models/survey_spec.rb +155 -0
  230. data/spec/models/surveyor_gui/question_spec.rb +60 -0
  231. data/spec/models/surveyor_gui/question_type_spec.rb +268 -0
  232. data/spec/models/validation_condition_spec.rb +98 -0
  233. data/spec/models/validation_spec.rb +64 -0
  234. data/spec/spec.opts +4 -0
  235. data/spec/spec_helper.rb +119 -0
  236. data/spec/support/scenario_outline_helper.rb +39 -0
  237. data/spec/support/shared.rb +10 -0
  238. data/spec/support/surveyforms_creation_helpers.rb +312 -0
  239. data/spec/support/surveyforms_rearrangement_helpers.rb +170 -0
  240. data/spec/support/surveyor_api_helpers.rb +15 -0
  241. data/spec/support/surveyor_ui_helpers.rb +108 -0
  242. data/spec/support/wait_for_ajax.rb +11 -0
  243. data/spec/views/questions/edit.html.erb_spec.rb +73 -0
  244. data/spec/views/surveyforms/edit.html.erb_spec.rb +126 -0
  245. data/surveyor_gui.gemspec +52 -0
  246. data/test/dummy/README.rdoc +261 -0
  247. data/test/dummy/Rakefile +7 -0
  248. data/test/dummy/app/assets/javascripts/application.js +15 -0
  249. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  250. data/test/dummy/app/controllers/application_controller.rb +3 -0
  251. data/test/dummy/app/helpers/application_helper.rb +2 -0
  252. data/test/dummy/app/mailers/.gitkeep +0 -0
  253. data/test/dummy/app/models/.gitkeep +0 -0
  254. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  255. data/test/dummy/config.ru +4 -0
  256. data/test/dummy/config/application.rb +59 -0
  257. data/test/dummy/config/boot.rb +10 -0
  258. data/test/dummy/config/database.yml +25 -0
  259. data/test/dummy/config/environment.rb +5 -0
  260. data/test/dummy/config/environments/development.rb +37 -0
  261. data/test/dummy/config/environments/production.rb +67 -0
  262. data/test/dummy/config/environments/test.rb +37 -0
  263. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  264. data/test/dummy/config/initializers/inflections.rb +15 -0
  265. data/test/dummy/config/initializers/mime_types.rb +5 -0
  266. data/test/dummy/config/initializers/secret_token.rb +7 -0
  267. data/test/dummy/config/initializers/session_store.rb +8 -0
  268. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  269. data/test/dummy/config/locales/en.yml +5 -0
  270. data/test/dummy/config/routes.rb +58 -0
  271. data/test/dummy/lib/assets/.gitkeep +0 -0
  272. data/test/dummy/log/.gitkeep +0 -0
  273. data/test/dummy/public/404.html +26 -0
  274. data/test/dummy/public/422.html +26 -0
  275. data/test/dummy/public/500.html +25 -0
  276. data/test/dummy/public/favicon.ico +0 -0
  277. data/test/dummy/script/rails +6 -0
  278. data/test/surveyor-gui_test.rb +7 -0
  279. data/test/test_helper.rb +15 -0
  280. data/vendor/assets/stylesheets/.gitkeep +0 -0
  281. data/vendor/assets/stylesheets/custom.sass +5 -0
  282. data/vendor/plugins/.gitkeep +0 -0
  283. metadata +664 -0
@@ -0,0 +1,377 @@
1
+ /*
2
+
3
+ ### jQuery Star Rating Plugin v4.11 - 2013-03-14 ###
4
+ * Home: http://www.fyneworks.com/jquery/star-rating/
5
+ * Code: http://code.google.com/p/jquery-star-rating-plugin/
6
+ *
7
+ * Licensed under http://en.wikipedia.org/wiki/MIT_License
8
+ ###
9
+ */
10
+
11
+ /*# AVOID COLLISIONS #*/
12
+ ;if(window.jQuery) (function($){
13
+ /*# AVOID COLLISIONS #*/
14
+
15
+ // IE6 Background Image Fix
16
+ if ((!$.support.opacity && !$.support.style)) try { document.execCommand("BackgroundImageCache", false, true)} catch(e) { };
17
+ // Thanks to http://www.visualjquery.com/rating/rating_redux.html
18
+
19
+ // plugin initialization
20
+ $.fn.rating = function(options){
21
+ if(this.length==0) return this; // quick fail
22
+
23
+ // Handle API methods
24
+ if(typeof arguments[0]=='string'){
25
+ // Perform API methods on individual elements
26
+ if(this.length>1){
27
+ var args = arguments;
28
+ return this.each(function(){
29
+ $.fn.rating.apply($(this), args);
30
+ });
31
+ };
32
+ // Invoke API method handler
33
+ $.fn.rating[arguments[0]].apply(this, $.makeArray(arguments).slice(1) || []);
34
+ // Quick exit...
35
+ return this;
36
+ };
37
+
38
+ // Initialize options for this call
39
+ var options = $.extend(
40
+ {}/* new object */,
41
+ $.fn.rating.options/* default options */,
42
+ options || {} /* just-in-time options */
43
+ );
44
+
45
+ // Allow multiple controls with the same name by making each call unique
46
+ $.fn.rating.calls++;
47
+
48
+ // loop through each matched element
49
+ this
50
+ .not('.star-rating-applied')
51
+ .addClass('star-rating-applied')
52
+ .each(function(){
53
+
54
+ // Load control parameters / find context / etc
55
+ var control, input = $(this);
56
+ var eid = (this.name || 'unnamed-rating').replace(/\[|\]/g, '_').replace(/^\_+|\_+$/g,'');
57
+ var context = $(this.form || document.body);
58
+
59
+ // FIX: http://code.google.com/p/jquery-star-rating-plugin/issues/detail?id=23
60
+ var raters = context.data('rating');
61
+ if(!raters || raters.call!=$.fn.rating.calls) raters = { count:0, call:$.fn.rating.calls };
62
+ var rater = raters[eid] || context.data('rating'+eid);
63
+
64
+ // if rater is available, verify that the control still exists
65
+ if(rater) control = rater.data('rating');
66
+
67
+ if(rater && control)//{// save a byte!
68
+ // add star to control if rater is available and the same control still exists
69
+ control.count++;
70
+
71
+ //}// save a byte!
72
+ else{
73
+ // create new control if first star or control element was removed/replaced
74
+
75
+ // Initialize options for this rater
76
+ control = $.extend(
77
+ {}/* new object */,
78
+ options || {} /* current call options */,
79
+ ($.metadata? input.metadata(): ($.meta?input.data():null)) || {}, /* metadata options */
80
+ { count:0, stars: [], inputs: [] }
81
+ );
82
+
83
+ // increment number of rating controls
84
+ control.serial = raters.count++;
85
+
86
+ // create rating element
87
+ rater = $('<span class="star-rating-control"/>');
88
+ input.before(rater);
89
+
90
+ // Mark element for initialization (once all stars are ready)
91
+ rater.addClass('rating-to-be-drawn');
92
+
93
+ // Accept readOnly setting from 'disabled' property
94
+ if(input.attr('disabled') || input.hasClass('disabled')) control.readOnly = true;
95
+
96
+ // Accept required setting from class property (class='required')
97
+ if(input.hasClass('required')) control.required = true;
98
+
99
+ // Create 'cancel' button
100
+ rater.append(
101
+ control.cancel = $('<div class="rating-cancel"><a title="' + control.cancel + '">' + control.cancelValue + '</a></div>')
102
+ .on('mouseover',function(){
103
+ $(this).rating('drain');
104
+ $(this).addClass('star-rating-hover');
105
+ //$(this).rating('focus');
106
+ })
107
+ .on('mouseout',function(){
108
+ $(this).rating('draw');
109
+ $(this).removeClass('star-rating-hover');
110
+ //$(this).rating('blur');
111
+ })
112
+ .on('click',function(){
113
+ $(this).rating('select');
114
+ })
115
+ .data('rating', control)
116
+ );
117
+
118
+ }; // first element of group
119
+
120
+ // insert rating star (thanks Jan Fanslau rev125 for blind support https://code.google.com/p/jquery-star-rating-plugin/issues/detail?id=125)
121
+ var star = $('<div role="text" aria-label="'+ this.title +'" class="star-rating rater-'+ control.serial +'"><a title="' + (this.title || this.value) + '">' + this.value + '</a></div>');
122
+ rater.append(star);
123
+
124
+ // inherit attributes from input element
125
+ if(this.id) star.attr('id', this.id);
126
+ if(this.className) star.addClass(this.className);
127
+
128
+ // Half-stars?
129
+ if(control.half) control.split = 2;
130
+
131
+ // Prepare division control
132
+ if(typeof control.split=='number' && control.split>0){
133
+ var stw = ($.fn.width ? star.width() : 0) || control.starWidth;
134
+ var spi = (control.count % control.split), spw = Math.floor(stw/control.split);
135
+ star
136
+ // restrict star's width and hide overflow (already in CSS)
137
+ .width(spw)
138
+ // move the star left by using a negative margin
139
+ // this is work-around to IE's stupid box model (position:relative doesn't work)
140
+ .find('a').css({ 'margin-left':'-'+ (spi*spw) +'px' })
141
+ };
142
+
143
+ // readOnly?
144
+ if(control.readOnly)//{ //save a byte!
145
+ // Mark star as readOnly so user can customize display
146
+ star.addClass('star-rating-readonly');
147
+ //} //save a byte!
148
+ else//{ //save a byte!
149
+ // Enable hover css effects
150
+ star.addClass('star-rating-live')
151
+ // Attach mouse events
152
+ .on('mouseover',function(){
153
+ $(this).rating('fill');
154
+ $(this).rating('focus');
155
+ })
156
+ .on('mouseout',function(){
157
+ $(this).rating('draw');
158
+ $(this).rating('blur');
159
+ })
160
+ .on('click',function(){
161
+ $(this).rating('select');
162
+ })
163
+ ;
164
+ //}; //save a byte!
165
+
166
+ // set current selection
167
+ if(this.checked) control.current = star;
168
+
169
+ // set current select for links
170
+ if(this.nodeName=="A"){
171
+ if($(this).hasClass('selected'))
172
+ control.current = star;
173
+ };
174
+
175
+ // hide input element
176
+ input.hide();
177
+
178
+ // backward compatibility, form element to plugin
179
+ input.on('change.rating',function(event){
180
+ if(event.selfTriggered) return false;
181
+ $(this).rating('select');
182
+ });
183
+
184
+ // attach reference to star to input element and vice-versa
185
+ star.data('rating.input', input.data('rating.star', star));
186
+
187
+ // store control information in form (or body when form not available)
188
+ control.stars[control.stars.length] = star[0];
189
+ control.inputs[control.inputs.length] = input[0];
190
+ control.rater = raters[eid] = rater;
191
+ control.context = context;
192
+
193
+ input.data('rating', control);
194
+ rater.data('rating', control);
195
+ star.data('rating', control);
196
+ context.data('rating', raters);
197
+ context.data('rating'+eid, rater); // required for ajax forms
198
+ }); // each element
199
+
200
+ // Initialize ratings (first draw)
201
+ $('.rating-to-be-drawn').rating('draw').removeClass('rating-to-be-drawn');
202
+
203
+ return this; // don't break the chain...
204
+ };
205
+
206
+ /*--------------------------------------------------------*/
207
+
208
+ /*
209
+ ### Core functionality and API ###
210
+ */
211
+ $.extend($.fn.rating, {
212
+ // Used to append a unique serial number to internal control ID
213
+ // each time the plugin is invoked so same name controls can co-exist
214
+ calls: 0,
215
+
216
+ focus: function(){
217
+ var control = this.data('rating'); if(!control) return this;
218
+ if(!control.focus) return this; // quick fail if not required
219
+ // find data for event
220
+ var input = $(this).data('rating.input') || $( this.tagName=='INPUT' ? this : null );
221
+ // focus handler, as requested by focusdigital.co.uk
222
+ if(control.focus) control.focus.apply(input[0], [input.val(), $('a', input.data('rating.star'))[0]]);
223
+ }, // $.fn.rating.focus
224
+
225
+ blur: function(){
226
+ var control = this.data('rating'); if(!control) return this;
227
+ if(!control.blur) return this; // quick fail if not required
228
+ // find data for event
229
+ var input = $(this).data('rating.input') || $( this.tagName=='INPUT' ? this : null );
230
+ // blur handler, as requested by focusdigital.co.uk
231
+ if(control.blur) control.blur.apply(input[0], [input.val(), $('a', input.data('rating.star'))[0]]);
232
+ }, // $.fn.rating.blur
233
+
234
+ fill: function(){ // fill to the current mouse position.
235
+ var control = this.data('rating'); if(!control) return this;
236
+ // do not execute when control is in read-only mode
237
+ if(control.readOnly) return;
238
+ // Reset all stars and highlight them up to this element
239
+ this.rating('drain');
240
+ this.prevAll().addBack().filter('.rater-'+ control.serial).addClass('star-rating-hover');
241
+ },// $.fn.rating.fill
242
+
243
+ drain: function() { // drain all the stars.
244
+ var control = this.data('rating'); if(!control) return this;
245
+ // do not execute when control is in read-only mode
246
+ if(control.readOnly) return;
247
+ // Reset all stars
248
+ control.rater.children().filter('.rater-'+ control.serial).removeClass('star-rating-on').removeClass('star-rating-hover');
249
+ },// $.fn.rating.drain
250
+
251
+ draw: function(){ // set value and stars to reflect current selection
252
+ var control = this.data('rating'); if(!control) return this;
253
+ // Clear all stars
254
+ this.rating('drain');
255
+ // Set control value
256
+ var current = $( control.current );//? control.current.data('rating.input') : null );
257
+ var starson = current.length ? current.prevAll().addBack().filter('.rater-'+ control.serial) : null;
258
+ if(starson) starson.addClass('star-rating-on');
259
+ // Show/hide 'cancel' button
260
+ control.cancel[control.readOnly || control.required?'hide':'show']();
261
+ // Add/remove read-only classes to remove hand pointer
262
+ this.siblings()[control.readOnly?'addClass':'removeClass']('star-rating-readonly');
263
+ },// $.fn.rating.draw
264
+
265
+
266
+
267
+
268
+
269
+ select: function(value,wantCallBack){ // select a value
270
+ var control = this.data('rating'); if(!control) return this;
271
+ // do not execute when control is in read-only mode
272
+ if(control.readOnly) return;
273
+ // clear selection
274
+ control.current = null;
275
+ // programmatically (based on user input)
276
+ if(typeof value!='undefined' || this.length>1){
277
+ // select by index (0 based)
278
+ if(typeof value=='number')
279
+ return $(control.stars[value]).rating('select',undefined,wantCallBack);
280
+ // select by literal value (must be passed as a string
281
+ if(typeof value=='string'){
282
+ //return
283
+ $.each(control.stars, function(){
284
+ //console.log($(this).data('rating.input'), $(this).data('rating.input').val(), value, $(this).data('rating.input').val()==value?'BINGO!':'');
285
+ if($(this).data('rating.input').val()==value) $(this).rating('select',undefined,wantCallBack);
286
+ });
287
+ // don't break the chain
288
+ return this;
289
+ };
290
+ }
291
+ else{
292
+ control.current = this[0].tagName=='INPUT' ?
293
+ this.data('rating.star') :
294
+ (this.is('.rater-'+ control.serial) ? this : null);
295
+ };
296
+ // Update rating control state
297
+ this.data('rating', control);
298
+ // Update display
299
+ this.rating('draw');
300
+ // find current input and its sibblings
301
+ var current = $( control.current ? control.current.data('rating.input') : null );
302
+ var lastipt = $( control.inputs ).filter(':checked');
303
+ var deadipt = $( control.inputs ).not(current);
304
+ // check and uncheck elements as required
305
+ deadipt.prop('checked',false);//.removeAttr('checked');
306
+ current.prop('checked',true);//.attr('checked','checked');
307
+ // trigger change on current or last selected input
308
+ $(current.length? current : lastipt ).trigger({ type:'change', selfTriggered:true });
309
+ // click callback, as requested here: http://plugins.jquery.com/node/1655
310
+ if((wantCallBack || wantCallBack == undefined) && control.callback) control.callback.apply(current[0], [current.val(), $('a', control.current)[0]]);// callback event
311
+ // don't break the chain
312
+ return this;
313
+ },// $.fn.rating.select
314
+
315
+
316
+
317
+
318
+
319
+ readOnly: function(toggle, disable){ // make the control read-only (still submits value)
320
+ var control = this.data('rating'); if(!control) return this;
321
+ // setread-only status
322
+ control.readOnly = toggle || toggle==undefined ? true : false;
323
+ // enable/disable control value submission
324
+ if(disable) $(control.inputs).attr("disabled", "disabled");
325
+ else $(control.inputs).removeAttr("disabled");
326
+ // Update rating control state
327
+ this.data('rating', control);
328
+ // Update display
329
+ this.rating('draw');
330
+ },// $.fn.rating.readOnly
331
+
332
+ disable: function(){ // make read-only and never submit value
333
+ this.rating('readOnly', true, true);
334
+ },// $.fn.rating.disable
335
+
336
+ enable: function(){ // make read/write and submit value
337
+ this.rating('readOnly', false, false);
338
+ }// $.fn.rating.select
339
+
340
+ });
341
+
342
+ /*--------------------------------------------------------*/
343
+
344
+ /*
345
+ ### Default Settings ###
346
+ eg.: You can override default control like this:
347
+ $.fn.rating.options.cancel = 'Clear';
348
+ */
349
+ $.fn.rating.options = { //$.extend($.fn.rating, { options: {
350
+ cancel: 'Cancel Rating', // advisory title for the 'cancel' link
351
+ cancelValue: '', // value to submit when user click the 'cancel' link
352
+ split: 0, // split the star into how many parts?
353
+
354
+ // Width of star image in case the plugin can't work it out. This can happen if
355
+ // the jQuery.dimensions plugin is not available OR the image is hidden at installation
356
+ starWidth: 16//,
357
+
358
+ //NB.: These don't need to be pre-defined (can be undefined/null) so let's save some code!
359
+ //half: false, // just a shortcut to control.split = 2
360
+ //required: false, // disables the 'cancel' button so user can only select one of the specified values
361
+ //readOnly: false, // disable rating plugin interaction/ values cannot be.one('change', //focus: function(){}, // executed when stars are focused
362
+ //blur: function(){}, // executed when stars are focused
363
+ //callback: function(){}, // executed when a star is clicked
364
+ }; //} });
365
+
366
+ /*--------------------------------------------------------*/
367
+
368
+
369
+ // auto-initialize plugin
370
+ $(function(){
371
+ $('input[type=radio].star').rating();
372
+ });
373
+
374
+
375
+ /*# AVOID COLLISIONS #*/
376
+ })(jQuery);
377
+ /*# AVOID COLLISIONS #*/
@@ -0,0 +1,1188 @@
1
+ /**
2
+ * jQuery Validation Plugin 1.9.0
3
+ *
4
+ * http://bassistance.de/jquery-plugins/jquery-plugin-validation/
5
+ * http://docs.jquery.com/Plugins/Validation
6
+ *
7
+ * Copyright (c) 2006 - 2011 Jörn Zaefferer
8
+ *
9
+ * Dual licensed under the MIT and GPL licenses:
10
+ * http://www.opensource.org/licenses/mit-license.php
11
+ * http://www.gnu.org/licenses/gpl.html
12
+ */
13
+
14
+ (function($) {
15
+
16
+ $.extend($.fn, {
17
+ // http://docs.jquery.com/Plugins/Validation/validate
18
+ validate: function( options ) {
19
+
20
+ // if nothing is selected, return nothing; can't chain anyway
21
+ if (!this.length) {
22
+ options && options.debug && window.console && console.warn( "nothing selected, can't validate, returning nothing" );
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
+ var inputsAndButtons = this.find("input, button");
41
+
42
+ // allow suppresing validation by adding a cancel class to the submit button
43
+ inputsAndButtons.filter(".cancel").click(function () {
44
+ validator.cancelSubmit = true;
45
+ });
46
+
47
+ // when a submitHandler is used, capture the submitting button
48
+ if (validator.settings.submitHandler) {
49
+ inputsAndButtons.filter(":submit").click(function () {
50
+ validator.submitButton = this;
51
+ });
52
+ }
53
+
54
+ // validate the form on submit
55
+ this.submit( function( event ) {
56
+ if ( validator.settings.debug )
57
+ // prevent form submit to be able to see console output
58
+ event.preventDefault();
59
+
60
+ function handle() {
61
+ if ( validator.settings.submitHandler ) {
62
+ if (validator.submitButton) {
63
+ // insert a hidden input as a replacement for the missing submit button
64
+ var hidden = $("<input type='hidden'/>").attr("name", validator.submitButton.name).val(validator.submitButton.value).appendTo(validator.currentForm);
65
+ }
66
+ validator.settings.submitHandler.call( validator, validator.currentForm );
67
+ if (validator.submitButton) {
68
+ // and clean up afterwards; thanks to no-block-scope, hidden can be referenced
69
+ hidden.remove();
70
+ }
71
+ return false;
72
+ }
73
+ return true;
74
+ }
75
+
76
+ // prevent submit for invalid forms or custom submit handlers
77
+ if ( validator.cancelSubmit ) {
78
+ validator.cancelSubmit = false;
79
+ return handle();
80
+ }
81
+ if ( validator.form() ) {
82
+ if ( validator.pendingRequest ) {
83
+ validator.formSubmitted = true;
84
+ return false;
85
+ }
86
+ return handle();
87
+ } else {
88
+ validator.focusInvalid();
89
+ return false;
90
+ }
91
+ });
92
+ }
93
+
94
+ return validator;
95
+ },
96
+ // http://docs.jquery.com/Plugins/Validation/valid
97
+ valid: function() {
98
+ if ( $(this[0]).is('form')) {
99
+ return this.validate().form();
100
+ } else {
101
+ var valid = true;
102
+ var validator = $(this[0].form).validate();
103
+ this.each(function() {
104
+ valid &= validator.element(this);
105
+ });
106
+ return valid;
107
+ }
108
+ },
109
+ // attributes: space seperated list of attributes to retrieve and remove
110
+ removeAttrs: function(attributes) {
111
+ var result = {},
112
+ $element = this;
113
+ $.each(attributes.split(/\s/), function(index, value) {
114
+ result[value] = $element.attr(value);
115
+ $element.removeAttr(value);
116
+ });
117
+ return result;
118
+ },
119
+ // http://docs.jquery.com/Plugins/Validation/rules
120
+ rules: function(command, argument) {
121
+ var element = this[0];
122
+
123
+ if (command) {
124
+ var settings = $.data(element.form, 'validator').settings;
125
+ var staticRules = settings.rules;
126
+ var existingRules = $.validator.staticRules(element);
127
+ switch(command) {
128
+ case "add":
129
+ $.extend(existingRules, $.validator.normalizeRule(argument));
130
+ staticRules[element.name] = existingRules;
131
+ if (argument.messages)
132
+ settings.messages[element.name] = $.extend( settings.messages[element.name], argument.messages );
133
+ break;
134
+ case "remove":
135
+ if (!argument) {
136
+ delete staticRules[element.name];
137
+ return existingRules;
138
+ }
139
+ var filtered = {};
140
+ $.each(argument.split(/\s/), function(index, method) {
141
+ filtered[method] = existingRules[method];
142
+ delete existingRules[method];
143
+ });
144
+ return filtered;
145
+ }
146
+ }
147
+
148
+ var data = $.validator.normalizeRules(
149
+ $.extend(
150
+ {},
151
+ $.validator.metadataRules(element),
152
+ $.validator.classRules(element),
153
+ $.validator.attributeRules(element),
154
+ $.validator.staticRules(element)
155
+ ), element);
156
+
157
+ // make sure required is at front
158
+ if (data.required) {
159
+ var param = data.required;
160
+ delete data.required;
161
+ data = $.extend({required: param}, data);
162
+ }
163
+
164
+ return data;
165
+ }
166
+ });
167
+
168
+ // Custom selectors
169
+ $.extend($.expr[":"], {
170
+ // http://docs.jquery.com/Plugins/Validation/blank
171
+ blank: function(a) {return !$.trim("" + a.value);},
172
+ // http://docs.jquery.com/Plugins/Validation/filled
173
+ filled: function(a) {return !!$.trim("" + a.value);},
174
+ // http://docs.jquery.com/Plugins/Validation/unchecked
175
+ unchecked: function(a) {return !a.checked;}
176
+ });
177
+
178
+ // constructor for validator
179
+ $.validator = function( options, form ) {
180
+ this.settings = $.extend( true, {}, $.validator.defaults, options );
181
+ this.currentForm = form;
182
+ this.init();
183
+ };
184
+
185
+ $.validator.format = function(source, params) {
186
+ if ( arguments.length == 1 )
187
+ return function() {
188
+ var args = $.makeArray(arguments);
189
+ args.unshift(source);
190
+ return $.validator.format.apply( this, args );
191
+ };
192
+ if ( arguments.length > 2 && params.constructor != Array ) {
193
+ params = $.makeArray(arguments).slice(1);
194
+ }
195
+ if ( params.constructor != Array ) {
196
+ params = [ params ];
197
+ }
198
+ $.each(params, function(i, n) {
199
+ source = source.replace(new RegExp("\\{" + i + "\\}", "g"), n);
200
+ });
201
+ return source;
202
+ };
203
+
204
+ $.extend($.validator, {
205
+
206
+ defaults: {
207
+ messages: {},
208
+ groups: {},
209
+ rules: {},
210
+ errorClass: "error",
211
+ validClass: "valid",
212
+ errorElement: "label",
213
+ focusInvalid: true,
214
+ errorContainer: $( [] ),
215
+ errorLabelContainer: $( [] ),
216
+ onsubmit: true,
217
+ ignore: ":hidden",
218
+ ignoreTitle: false,
219
+ onfocusin: function(element, event) {
220
+ this.lastActive = element;
221
+
222
+ // hide error label and remove error class on focus if enabled
223
+ if ( this.settings.focusCleanup && !this.blockFocusCleanup ) {
224
+ this.settings.unhighlight && this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );
225
+ this.addWrapper(this.errorsFor(element)).hide();
226
+ }
227
+ },
228
+ onfocusout: function(element, event) {
229
+ if ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) {
230
+ this.element(element);
231
+ }
232
+ },
233
+ onkeyup: function(element, event) {
234
+ if ( element.name in this.submitted || element == this.lastElement ) {
235
+ this.element(element);
236
+ }
237
+ },
238
+ onclick: function(element, event) {
239
+ // click on selects, radiobuttons and checkboxes
240
+ if ( element.name in this.submitted )
241
+ this.element(element);
242
+ // or option elements, check parent select in that case
243
+ else if (element.parentNode.name in this.submitted)
244
+ this.element(element.parentNode);
245
+ },
246
+ highlight: function(element, errorClass, validClass) {
247
+ if (element.type === 'radio') {
248
+ this.findByName(element.name).addClass(errorClass).removeClass(validClass);
249
+ } else {
250
+ $(element).addClass(errorClass).removeClass(validClass);
251
+ }
252
+ },
253
+ unhighlight: function(element, errorClass, validClass) {
254
+ if (element.type === 'radio') {
255
+ this.findByName(element.name).removeClass(errorClass).addClass(validClass);
256
+ } else {
257
+ $(element).removeClass(errorClass).addClass(validClass);
258
+ }
259
+ }
260
+ },
261
+
262
+ // http://docs.jquery.com/Plugins/Validation/Validator/setDefaults
263
+ setDefaults: function(settings) {
264
+ $.extend( $.validator.defaults, settings );
265
+ },
266
+
267
+ messages: {
268
+ required: "This field is required.",
269
+ remote: "Please fix this field.",
270
+ email: "Please enter a valid email address.",
271
+ url: "Please enter a valid URL.",
272
+ date: "Please enter a valid date.",
273
+ dateISO: "Please enter a valid date (ISO).",
274
+ number: "Please enter a valid number.",
275
+ digits: "Please enter only digits.",
276
+ creditcard: "Please enter a valid credit card number.",
277
+ equalTo: "Please enter the same value again.",
278
+ accept: "Please enter a value with a valid extension.",
279
+ maxlength: $.validator.format("Please enter no more than {0} characters."),
280
+ minlength: $.validator.format("Please enter at least {0} characters."),
281
+ rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."),
282
+ range: $.validator.format("Please enter a value between {0} and {1}."),
283
+ max: $.validator.format("Please enter a value less than or equal to {0}."),
284
+ min: $.validator.format("Please enter a value greater than or equal to {0}.")
285
+ },
286
+
287
+ autoCreateRanges: false,
288
+
289
+ prototype: {
290
+
291
+ init: function() {
292
+ this.labelContainer = $(this.settings.errorLabelContainer);
293
+ this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm);
294
+ this.containers = $(this.settings.errorContainer).add( this.settings.errorLabelContainer );
295
+ this.submitted = {};
296
+ this.valueCache = {};
297
+ this.pendingRequest = 0;
298
+ this.pending = {};
299
+ this.invalid = {};
300
+ this.reset();
301
+
302
+ var groups = (this.groups = {});
303
+ $.each(this.settings.groups, function(key, value) {
304
+ $.each(value.split(/\s/), function(index, name) {
305
+ groups[name] = key;
306
+ });
307
+ });
308
+ var rules = this.settings.rules;
309
+ $.each(rules, function(key, value) {
310
+ rules[key] = $.validator.normalizeRule(value);
311
+ });
312
+
313
+ function delegate(event) {
314
+ var validator = $.data(this[0].form, "validator"),
315
+ eventType = "on" + event.type.replace(/^validate/, "");
316
+ validator.settings[eventType] && validator.settings[eventType].call(validator, this[0], event);
317
+ }
318
+ $(this.currentForm)
319
+ .validateDelegate("[type='text'], [type='password'], [type='file'], select, textarea, " +
320
+ "[type='number'], [type='search'] ,[type='tel'], [type='url'], " +
321
+ "[type='email'], [type='datetime'], [type='date'], [type='month'], " +
322
+ "[type='week'], [type='time'], [type='datetime-local'], " +
323
+ "[type='range'], [type='color'] ",
324
+ "focusin focusout keyup", delegate)
325
+ .validateDelegate("[type='radio'], [type='checkbox'], select, option", "click", delegate);
326
+
327
+ if (this.settings.invalidHandler)
328
+ $(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler);
329
+ },
330
+
331
+ // http://docs.jquery.com/Plugins/Validation/Validator/form
332
+ form: function() {
333
+ this.checkForm();
334
+ $.extend(this.submitted, this.errorMap);
335
+ this.invalid = $.extend({}, this.errorMap);
336
+ if (!this.valid())
337
+ $(this.currentForm).triggerHandler("invalid-form", [this]);
338
+ this.showErrors();
339
+ return this.valid();
340
+ },
341
+
342
+ checkForm: function() {
343
+ this.prepareForm();
344
+ for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) {
345
+ this.check( elements[i] );
346
+ }
347
+ return this.valid();
348
+ },
349
+
350
+ // http://docs.jquery.com/Plugins/Validation/Validator/element
351
+ element: function( element ) {
352
+ element = this.validationTargetFor( this.clean( element ) );
353
+ this.lastElement = element;
354
+ this.prepareElement( element );
355
+ this.currentElements = $(element);
356
+ var result = this.check( element );
357
+ if ( result ) {
358
+ delete this.invalid[element.name];
359
+ } else {
360
+ this.invalid[element.name] = true;
361
+ }
362
+ if ( !this.numberOfInvalids() ) {
363
+ // Hide error containers on last error
364
+ this.toHide = this.toHide.add( this.containers );
365
+ }
366
+ this.showErrors();
367
+ return result;
368
+ },
369
+
370
+ // http://docs.jquery.com/Plugins/Validation/Validator/showErrors
371
+ showErrors: function(errors) {
372
+ if(errors) {
373
+ // add items to error list and map
374
+ $.extend( this.errorMap, errors );
375
+ this.errorList = [];
376
+ for ( var name in errors ) {
377
+ this.errorList.push({
378
+ message: errors[name],
379
+ element: this.findByName(name)[0]
380
+ });
381
+ }
382
+ // remove items from success list
383
+ this.successList = $.grep( this.successList, function(element) {
384
+ return !(element.name in errors);
385
+ });
386
+ }
387
+ this.settings.showErrors
388
+ ? this.settings.showErrors.call( this, this.errorMap, this.errorList )
389
+ : this.defaultShowErrors();
390
+ },
391
+
392
+ // http://docs.jquery.com/Plugins/Validation/Validator/resetForm
393
+ resetForm: function() {
394
+ if ( $.fn.resetForm )
395
+ $( this.currentForm ).resetForm();
396
+ this.submitted = {};
397
+ this.lastElement = null;
398
+ this.prepareForm();
399
+ this.hideErrors();
400
+ this.elements().removeClass( this.settings.errorClass );
401
+ },
402
+
403
+ numberOfInvalids: function() {
404
+ return this.objectLength(this.invalid);
405
+ },
406
+
407
+ objectLength: function( obj ) {
408
+ var count = 0;
409
+ for ( var i in obj )
410
+ count++;
411
+ return count;
412
+ },
413
+
414
+ hideErrors: function() {
415
+ this.addWrapper( this.toHide ).hide();
416
+ },
417
+
418
+ valid: function() {
419
+ return this.size() == 0;
420
+ },
421
+
422
+ size: function() {
423
+ return this.errorList.length;
424
+ },
425
+
426
+ focusInvalid: function() {
427
+ if( this.settings.focusInvalid ) {
428
+ try {
429
+ $(this.findLastActive() || this.errorList.length && this.errorList[0].element || [])
430
+ .filter(":visible")
431
+ .focus()
432
+ // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
433
+ .trigger("focusin");
434
+ } catch(e) {
435
+ // ignore IE throwing errors when focusing hidden elements
436
+ }
437
+ }
438
+ },
439
+
440
+ findLastActive: function() {
441
+ var lastActive = this.lastActive;
442
+ return lastActive && $.grep(this.errorList, function(n) {
443
+ return n.element.name == lastActive.name;
444
+ }).length == 1 && lastActive;
445
+ },
446
+
447
+ elements: function() {
448
+ var validator = this,
449
+ rulesCache = {};
450
+
451
+ // select all valid inputs inside the form (no submit or reset buttons)
452
+ return $(this.currentForm)
453
+ .find("input, select, textarea")
454
+ .not(":submit, :reset, :image, [disabled]")
455
+ .not( this.settings.ignore )
456
+ .filter(function() {
457
+ !this.name && validator.settings.debug && window.console && console.error( "%o has no name assigned", this);
458
+
459
+ // select only the first element for each name, and only those with rules specified
460
+ if ( this.name in rulesCache || !validator.objectLength($(this).rules()) )
461
+ return false;
462
+
463
+ rulesCache[this.name] = true;
464
+ return true;
465
+ });
466
+ },
467
+
468
+ clean: function( selector ) {
469
+ return $( selector )[0];
470
+ },
471
+
472
+ errors: function() {
473
+ return $( this.settings.errorElement + "." + this.settings.errorClass, this.errorContext );
474
+ },
475
+
476
+ reset: function() {
477
+ this.successList = [];
478
+ this.errorList = [];
479
+ this.errorMap = {};
480
+ this.toShow = $([]);
481
+ this.toHide = $([]);
482
+ this.currentElements = $([]);
483
+ },
484
+
485
+ prepareForm: function() {
486
+ this.reset();
487
+ this.toHide = this.errors().add( this.containers );
488
+ },
489
+
490
+ prepareElement: function( element ) {
491
+ this.reset();
492
+ this.toHide = this.errorsFor(element);
493
+ },
494
+
495
+ check: function( element ) {
496
+ element = this.validationTargetFor( this.clean( element ) );
497
+
498
+ var rules = $(element).rules();
499
+ var dependencyMismatch = false;
500
+ for (var method in rules ) {
501
+ var rule = { method: method, parameters: rules[method] };
502
+ try {
503
+ var result = $.validator.methods[method].call( this, element.value.replace(/\r/g, ""), element, rule.parameters );
504
+
505
+ // if a method indicates that the field is optional and therefore valid,
506
+ // don't mark it as valid when there are no other rules
507
+ if ( result == "dependency-mismatch" ) {
508
+ dependencyMismatch = true;
509
+ continue;
510
+ }
511
+ dependencyMismatch = false;
512
+
513
+ if ( result == "pending" ) {
514
+ this.toHide = this.toHide.not( this.errorsFor(element) );
515
+ return;
516
+ }
517
+
518
+ if( !result ) {
519
+ this.formatAndAdd( element, rule );
520
+ return false;
521
+ }
522
+ } catch(e) {
523
+ this.settings.debug && window.console && console.log("exception occured when checking element " + element.id
524
+ + ", check the '" + rule.method + "' method", e);
525
+ throw e;
526
+ }
527
+ }
528
+ if (dependencyMismatch)
529
+ return;
530
+ if ( this.objectLength(rules) )
531
+ this.successList.push(element);
532
+ return true;
533
+ },
534
+
535
+ // return the custom message for the given element and validation method
536
+ // specified in the element's "messages" metadata
537
+ customMetaMessage: function(element, method) {
538
+ if (!$.metadata)
539
+ return;
540
+
541
+ var meta = this.settings.meta
542
+ ? $(element).metadata()[this.settings.meta]
543
+ : $(element).metadata();
544
+
545
+ return meta && meta.messages && meta.messages[method];
546
+ },
547
+
548
+ // return the custom message for the given element name and validation method
549
+ customMessage: function( name, method ) {
550
+ var m = this.settings.messages[name];
551
+ return m && (m.constructor == String
552
+ ? m
553
+ : m[method]);
554
+ },
555
+
556
+ // return the first defined argument, allowing empty strings
557
+ findDefined: function() {
558
+ for(var i = 0; i < arguments.length; i++) {
559
+ if (arguments[i] !== undefined)
560
+ return arguments[i];
561
+ }
562
+ return undefined;
563
+ },
564
+
565
+ defaultMessage: function( element, method) {
566
+ return this.findDefined(
567
+ this.customMessage( element.name, method ),
568
+ this.customMetaMessage( element, method ),
569
+ // title is never undefined, so handle empty string as undefined
570
+ !this.settings.ignoreTitle && element.title || undefined,
571
+ $.validator.messages[method],
572
+ "<strong>Warning: No message defined for " + element.name + "</strong>"
573
+ );
574
+ },
575
+
576
+ formatAndAdd: function( element, rule ) {
577
+ var message = this.defaultMessage( element, rule.method ),
578
+ theregex = /\$?\{(\d+)\}/g;
579
+ if ( typeof message == "function" ) {
580
+ message = message.call(this, rule.parameters, element);
581
+ } else if (theregex.test(message)) {
582
+ message = jQuery.format(message.replace(theregex, '{$1}'), rule.parameters);
583
+ }
584
+ this.errorList.push({
585
+ message: message,
586
+ element: element
587
+ });
588
+
589
+ this.errorMap[element.name] = message;
590
+ this.submitted[element.name] = message;
591
+ },
592
+
593
+ addWrapper: function(toToggle) {
594
+ if ( this.settings.wrapper )
595
+ toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );
596
+ return toToggle;
597
+ },
598
+
599
+ defaultShowErrors: function() {
600
+ for ( var i = 0; this.errorList[i]; i++ ) {
601
+ var error = this.errorList[i];
602
+ this.settings.highlight && this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );
603
+ this.showLabel( error.element, error.message );
604
+ }
605
+ if( this.errorList.length ) {
606
+ this.toShow = this.toShow.add( this.containers );
607
+ }
608
+ if (this.settings.success) {
609
+ for ( var i = 0; this.successList[i]; i++ ) {
610
+ this.showLabel( this.successList[i] );
611
+ }
612
+ }
613
+ if (this.settings.unhighlight) {
614
+ for ( var i = 0, elements = this.validElements(); elements[i]; i++ ) {
615
+ this.settings.unhighlight.call( this, elements[i], this.settings.errorClass, this.settings.validClass );
616
+ }
617
+ }
618
+ this.toHide = this.toHide.not( this.toShow );
619
+ this.hideErrors();
620
+ this.addWrapper( this.toShow ).show();
621
+ },
622
+
623
+ validElements: function() {
624
+ return this.currentElements.not(this.invalidElements());
625
+ },
626
+
627
+ invalidElements: function() {
628
+ return $(this.errorList).map(function() {
629
+ return this.element;
630
+ });
631
+ },
632
+
633
+ showLabel: function(element, message) {
634
+ var label = this.errorsFor( element );
635
+ if ( label.length ) {
636
+ // refresh error/success class
637
+ label.removeClass( this.settings.validClass ).addClass( this.settings.errorClass );
638
+
639
+ // check if we have a generated label, replace the message then
640
+ label.attr("generated") && label.html(message);
641
+ } else {
642
+ // create label
643
+ label = $("<" + this.settings.errorElement + "/>")
644
+ .attr({"for": this.idOrName(element), generated: true})
645
+ .addClass(this.settings.errorClass)
646
+ .html(message || "");
647
+ if ( this.settings.wrapper ) {
648
+ // make sure the element is visible, even in IE
649
+ // actually showing the wrapped element is handled elsewhere
650
+ label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent();
651
+ }
652
+ if ( !this.labelContainer.append(label).length )
653
+ this.settings.errorPlacement
654
+ ? this.settings.errorPlacement(label, $(element) )
655
+ : label.insertAfter(element);
656
+ }
657
+ if ( !message && this.settings.success ) {
658
+ label.text("");
659
+ typeof this.settings.success == "string"
660
+ ? label.addClass( this.settings.success )
661
+ : this.settings.success( label );
662
+ }
663
+ this.toShow = this.toShow.add(label);
664
+ },
665
+
666
+ errorsFor: function(element) {
667
+ var name = this.idOrName(element);
668
+ return this.errors().filter(function() {
669
+ return $(this).attr('for') == name;
670
+ });
671
+ },
672
+
673
+ idOrName: function(element) {
674
+ return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name);
675
+ },
676
+
677
+ validationTargetFor: function(element) {
678
+ // if radio/checkbox, validate first element in group instead
679
+ if (this.checkable(element)) {
680
+ element = this.findByName( element.name ).not(this.settings.ignore)[0];
681
+ }
682
+ return element;
683
+ },
684
+
685
+ checkable: function( element ) {
686
+ return /radio|checkbox/i.test(element.type);
687
+ },
688
+
689
+ findByName: function( name ) {
690
+ // select by name and filter by form for performance over form.find("[name=...]")
691
+ var form = this.currentForm;
692
+ return $(document.getElementsByName(name)).map(function(index, element) {
693
+ return element.form == form && element.name == name && element || null;
694
+ });
695
+ },
696
+
697
+ getLength: function(value, element) {
698
+ switch( element.nodeName.toLowerCase() ) {
699
+ case 'select':
700
+ return $("option:selected", element).length;
701
+ case 'input':
702
+ if( this.checkable( element) )
703
+ return this.findByName(element.name).filter(':checked').length;
704
+ }
705
+ return value.length;
706
+ },
707
+
708
+ depend: function(param, element) {
709
+ return this.dependTypes[typeof param]
710
+ ? this.dependTypes[typeof param](param, element)
711
+ : true;
712
+ },
713
+
714
+ dependTypes: {
715
+ "boolean": function(param, element) {
716
+ return param;
717
+ },
718
+ "string": function(param, element) {
719
+ return !!$(param, element.form).length;
720
+ },
721
+ "function": function(param, element) {
722
+ return param(element);
723
+ }
724
+ },
725
+
726
+ optional: function(element) {
727
+ return !$.validator.methods.required.call(this, $.trim(element.value), element) && "dependency-mismatch";
728
+ },
729
+
730
+ startRequest: function(element) {
731
+ if (!this.pending[element.name]) {
732
+ this.pendingRequest++;
733
+ this.pending[element.name] = true;
734
+ }
735
+ },
736
+
737
+ stopRequest: function(element, valid) {
738
+ this.pendingRequest--;
739
+ // sometimes synchronization fails, make sure pendingRequest is never < 0
740
+ if (this.pendingRequest < 0)
741
+ this.pendingRequest = 0;
742
+ delete this.pending[element.name];
743
+ if ( valid && this.pendingRequest == 0 && this.formSubmitted && this.form() ) {
744
+ $(this.currentForm).submit();
745
+ this.formSubmitted = false;
746
+ } else if (!valid && this.pendingRequest == 0 && this.formSubmitted) {
747
+ $(this.currentForm).triggerHandler("invalid-form", [this]);
748
+ this.formSubmitted = false;
749
+ }
750
+ },
751
+
752
+ previousValue: function(element) {
753
+ return $.data(element, "previousValue") || $.data(element, "previousValue", {
754
+ old: null,
755
+ valid: true,
756
+ message: this.defaultMessage( element, "remote" )
757
+ });
758
+ }
759
+
760
+ },
761
+
762
+ classRuleSettings: {
763
+ required: {required: true},
764
+ email: {email: true},
765
+ url: {url: true},
766
+ date: {date: true},
767
+ dateISO: {dateISO: true},
768
+ dateDE: {dateDE: true},
769
+ number: {number: true},
770
+ numberDE: {numberDE: true},
771
+ digits: {digits: true},
772
+ creditcard: {creditcard: true}
773
+ },
774
+
775
+ addClassRules: function(className, rules) {
776
+ className.constructor == String ?
777
+ this.classRuleSettings[className] = rules :
778
+ $.extend(this.classRuleSettings, className);
779
+ },
780
+
781
+ classRules: function(element) {
782
+ var rules = {};
783
+ var classes = $(element).attr('class');
784
+ classes && $.each(classes.split(' '), function() {
785
+ if (this in $.validator.classRuleSettings) {
786
+ $.extend(rules, $.validator.classRuleSettings[this]);
787
+ }
788
+ });
789
+ return rules;
790
+ },
791
+
792
+ attributeRules: function(element) {
793
+ var rules = {};
794
+ var $element = $(element);
795
+
796
+ for (var method in $.validator.methods) {
797
+ var value;
798
+ // If .prop exists (jQuery >= 1.6), use it to get true/false for required
799
+ if (method === 'required' && typeof $.fn.prop === 'function') {
800
+ value = $element.prop(method);
801
+ } else {
802
+ value = $element.attr(method);
803
+ }
804
+ if (value) {
805
+ rules[method] = value;
806
+ } else if ($element[0].getAttribute("type") === method) {
807
+ rules[method] = true;
808
+ }
809
+ }
810
+
811
+ // maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs
812
+ if (rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength)) {
813
+ delete rules.maxlength;
814
+ }
815
+
816
+ return rules;
817
+ },
818
+
819
+ metadataRules: function(element) {
820
+ if (!$.metadata) return {};
821
+
822
+ var meta = $.data(element.form, 'validator').settings.meta;
823
+ return meta ?
824
+ $(element).metadata()[meta] :
825
+ $(element).metadata();
826
+ },
827
+
828
+ staticRules: function(element) {
829
+ var rules = {};
830
+ var validator = $.data(element.form, 'validator');
831
+ if (validator.settings.rules) {
832
+ rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {};
833
+ }
834
+ return rules;
835
+ },
836
+
837
+ normalizeRules: function(rules, element) {
838
+ // handle dependency check
839
+ $.each(rules, function(prop, val) {
840
+ // ignore rule when param is explicitly false, eg. required:false
841
+ if (val === false) {
842
+ delete rules[prop];
843
+ return;
844
+ }
845
+ if (val.param || val.depends) {
846
+ var keepRule = true;
847
+ switch (typeof val.depends) {
848
+ case "string":
849
+ keepRule = !!$(val.depends, element.form).length;
850
+ break;
851
+ case "function":
852
+ keepRule = val.depends.call(element, element);
853
+ break;
854
+ }
855
+ if (keepRule) {
856
+ rules[prop] = val.param !== undefined ? val.param : true;
857
+ } else {
858
+ delete rules[prop];
859
+ }
860
+ }
861
+ });
862
+
863
+ // evaluate parameters
864
+ $.each(rules, function(rule, parameter) {
865
+ rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter;
866
+ });
867
+
868
+ // clean number parameters
869
+ $.each(['minlength', 'maxlength', 'min', 'max'], function() {
870
+ if (rules[this]) {
871
+ rules[this] = Number(rules[this]);
872
+ }
873
+ });
874
+ $.each(['rangelength', 'range'], function() {
875
+ if (rules[this]) {
876
+ rules[this] = [Number(rules[this][0]), Number(rules[this][1])];
877
+ }
878
+ });
879
+
880
+ if ($.validator.autoCreateRanges) {
881
+ // auto-create ranges
882
+ if (rules.min && rules.max) {
883
+ rules.range = [rules.min, rules.max];
884
+ delete rules.min;
885
+ delete rules.max;
886
+ }
887
+ if (rules.minlength && rules.maxlength) {
888
+ rules.rangelength = [rules.minlength, rules.maxlength];
889
+ delete rules.minlength;
890
+ delete rules.maxlength;
891
+ }
892
+ }
893
+
894
+ // To support custom messages in metadata ignore rule methods titled "messages"
895
+ if (rules.messages) {
896
+ delete rules.messages;
897
+ }
898
+
899
+ return rules;
900
+ },
901
+
902
+ // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
903
+ normalizeRule: function(data) {
904
+ if( typeof data == "string" ) {
905
+ var transformed = {};
906
+ $.each(data.split(/\s/), function() {
907
+ transformed[this] = true;
908
+ });
909
+ data = transformed;
910
+ }
911
+ return data;
912
+ },
913
+
914
+ // http://docs.jquery.com/Plugins/Validation/Validator/addMethod
915
+ addMethod: function(name, method, message) {
916
+ $.validator.methods[name] = method;
917
+ $.validator.messages[name] = message != undefined ? message : $.validator.messages[name];
918
+ if (method.length < 3) {
919
+ $.validator.addClassRules(name, $.validator.normalizeRule(name));
920
+ }
921
+ },
922
+
923
+ methods: {
924
+
925
+ // http://docs.jquery.com/Plugins/Validation/Methods/required
926
+ required: function(value, element, param) {
927
+ // check if dependency is met
928
+ if ( !this.depend(param, element) )
929
+ return "dependency-mismatch";
930
+ switch( element.nodeName.toLowerCase() ) {
931
+ case 'select':
932
+ // could be an array for select-multiple or a string, both are fine this way
933
+ var val = $(element).val();
934
+ return val && val.length > 0;
935
+ case 'input':
936
+ if ( this.checkable(element) )
937
+ return this.getLength(value, element) > 0;
938
+ default:
939
+ return $.trim(value).length > 0;
940
+ }
941
+ },
942
+
943
+ // http://docs.jquery.com/Plugins/Validation/Methods/remote
944
+ remote: function(value, element, param) {
945
+ if ( this.optional(element) )
946
+ return "dependency-mismatch";
947
+
948
+ var previous = this.previousValue(element);
949
+ if (!this.settings.messages[element.name] )
950
+ this.settings.messages[element.name] = {};
951
+ previous.originalMessage = this.settings.messages[element.name].remote;
952
+ this.settings.messages[element.name].remote = previous.message;
953
+
954
+ param = typeof param == "string" && {url:param} || param;
955
+
956
+ if ( this.pending[element.name] ) {
957
+ return "pending";
958
+ }
959
+ if ( previous.old === value ) {
960
+ return previous.valid;
961
+ }
962
+
963
+ previous.old = value;
964
+ var validator = this;
965
+ this.startRequest(element);
966
+ var data = {};
967
+ data[element.name] = value;
968
+ $.ajax($.extend(true, {
969
+ url: param,
970
+ mode: "abort",
971
+ port: "validate" + element.name,
972
+ dataType: "json",
973
+ data: data,
974
+ success: function(response) {
975
+ validator.settings.messages[element.name].remote = previous.originalMessage;
976
+ var valid = response === true;
977
+ if ( valid ) {
978
+ var submitted = validator.formSubmitted;
979
+ validator.prepareElement(element);
980
+ validator.formSubmitted = submitted;
981
+ validator.successList.push(element);
982
+ validator.showErrors();
983
+ } else {
984
+ var errors = {};
985
+ var message = response || validator.defaultMessage( element, "remote" );
986
+ errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message;
987
+ validator.showErrors(errors);
988
+ }
989
+ previous.valid = valid;
990
+ validator.stopRequest(element, valid);
991
+ }
992
+ }, param));
993
+ return "pending";
994
+ },
995
+
996
+ // http://docs.jquery.com/Plugins/Validation/Methods/minlength
997
+ minlength: function(value, element, param) {
998
+ return this.optional(element) || this.getLength($.trim(value), element) >= param;
999
+ },
1000
+
1001
+ // http://docs.jquery.com/Plugins/Validation/Methods/maxlength
1002
+ maxlength: function(value, element, param) {
1003
+ return this.optional(element) || this.getLength($.trim(value), element) <= param;
1004
+ },
1005
+
1006
+ // http://docs.jquery.com/Plugins/Validation/Methods/rangelength
1007
+ rangelength: function(value, element, param) {
1008
+ var length = this.getLength($.trim(value), element);
1009
+ return this.optional(element) || ( length >= param[0] && length <= param[1] );
1010
+ },
1011
+
1012
+ // http://docs.jquery.com/Plugins/Validation/Methods/min
1013
+ min: function( value, element, param ) {
1014
+ return this.optional(element) || value >= param;
1015
+ },
1016
+
1017
+ // http://docs.jquery.com/Plugins/Validation/Methods/max
1018
+ max: function( value, element, param ) {
1019
+ return this.optional(element) || value <= param;
1020
+ },
1021
+
1022
+ // http://docs.jquery.com/Plugins/Validation/Methods/range
1023
+ range: function( value, element, param ) {
1024
+ return this.optional(element) || ( value >= param[0] && value <= param[1] );
1025
+ },
1026
+
1027
+ // http://docs.jquery.com/Plugins/Validation/Methods/email
1028
+ email: function(value, element) {
1029
+ // contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/
1030
+ 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);
1031
+ },
1032
+
1033
+ // http://docs.jquery.com/Plugins/Validation/Methods/url
1034
+ url: function(value, element) {
1035
+ // contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/
1036
+ return this.optional(element) || /^(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(value);
1037
+ },
1038
+
1039
+ // http://docs.jquery.com/Plugins/Validation/Methods/date
1040
+ date: function(value, element) {
1041
+ return this.optional(element) || !/Invalid|NaN/.test(new Date(value));
1042
+ },
1043
+
1044
+ // http://docs.jquery.com/Plugins/Validation/Methods/dateISO
1045
+ dateISO: function(value, element) {
1046
+ return this.optional(element) || /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(value);
1047
+ },
1048
+
1049
+ // http://docs.jquery.com/Plugins/Validation/Methods/number
1050
+ number: function(value, element) {
1051
+ return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(value);
1052
+ },
1053
+
1054
+ // http://docs.jquery.com/Plugins/Validation/Methods/digits
1055
+ digits: function(value, element) {
1056
+ return this.optional(element) || /^\d+$/.test(value);
1057
+ },
1058
+
1059
+ // http://docs.jquery.com/Plugins/Validation/Methods/creditcard
1060
+ // based on http://en.wikipedia.org/wiki/Luhn
1061
+ creditcard: function(value, element) {
1062
+ if ( this.optional(element) )
1063
+ return "dependency-mismatch";
1064
+ // accept only spaces, digits and dashes
1065
+ if (/[^0-9 -]+/.test(value))
1066
+ return false;
1067
+ var nCheck = 0,
1068
+ nDigit = 0,
1069
+ bEven = false;
1070
+
1071
+ value = value.replace(/\D/g, "");
1072
+
1073
+ for (var n = value.length - 1; n >= 0; n--) {
1074
+ var cDigit = value.charAt(n);
1075
+ var nDigit = parseInt(cDigit, 10);
1076
+ if (bEven) {
1077
+ if ((nDigit *= 2) > 9)
1078
+ nDigit -= 9;
1079
+ }
1080
+ nCheck += nDigit;
1081
+ bEven = !bEven;
1082
+ }
1083
+
1084
+ return (nCheck % 10) == 0;
1085
+ },
1086
+
1087
+ // http://docs.jquery.com/Plugins/Validation/Methods/accept
1088
+ accept: function(value, element, param) {
1089
+ param = typeof param == "string" ? param.replace(/,/g, '|') : "png|jpe?g|gif";
1090
+ return this.optional(element) || value.match(new RegExp(".(" + param + ")$", "i"));
1091
+ },
1092
+
1093
+ // http://docs.jquery.com/Plugins/Validation/Methods/equalTo
1094
+ equalTo: function(value, element, param) {
1095
+ // bind to the blur event of the target in order to revalidate whenever the target field is updated
1096
+ // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead
1097
+ var target = $(param).unbind(".validate-equalTo").bind("blur.validate-equalTo", function() {
1098
+ $(element).valid();
1099
+ });
1100
+ return value == target.val();
1101
+ }
1102
+
1103
+ }
1104
+
1105
+ });
1106
+
1107
+ // deprecated, use $.validator.format instead
1108
+ $.format = $.validator.format;
1109
+
1110
+ })(jQuery);
1111
+
1112
+ // ajax mode: abort
1113
+ // usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
1114
+ // if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
1115
+ ;(function($) {
1116
+ var pendingRequests = {};
1117
+ // Use a prefilter if available (1.5+)
1118
+ if ( $.ajaxPrefilter ) {
1119
+ $.ajaxPrefilter(function(settings, _, xhr) {
1120
+ var port = settings.port;
1121
+ if (settings.mode == "abort") {
1122
+ if ( pendingRequests[port] ) {
1123
+ pendingRequests[port].abort();
1124
+ }
1125
+ pendingRequests[port] = xhr;
1126
+ }
1127
+ });
1128
+ } else {
1129
+ // Proxy ajax
1130
+ var ajax = $.ajax;
1131
+ $.ajax = function(settings) {
1132
+ var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
1133
+ port = ( "port" in settings ? settings : $.ajaxSettings ).port;
1134
+ if (mode == "abort") {
1135
+ if ( pendingRequests[port] ) {
1136
+ pendingRequests[port].abort();
1137
+ }
1138
+ return (pendingRequests[port] = ajax.apply(this, arguments));
1139
+ }
1140
+ return ajax.apply(this, arguments);
1141
+ };
1142
+ }
1143
+ })(jQuery);
1144
+
1145
+ // provides cross-browser focusin and focusout events
1146
+ // IE has native support, in other browsers, use event caputuring (neither bubbles)
1147
+
1148
+ // provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation
1149
+ // handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target
1150
+ ;(function($) {
1151
+ // only implement if not provided by jQuery core (since 1.4)
1152
+ // TODO verify if jQuery 1.4's implementation is compatible with older jQuery special-event APIs
1153
+ if (!jQuery.event.special.focusin && !jQuery.event.special.focusout && document.addEventListener) {
1154
+ $.each({
1155
+ focus: 'focusin',
1156
+ blur: 'focusout'
1157
+ }, function( original, fix ){
1158
+ $.event.special[fix] = {
1159
+ setup:function() {
1160
+ this.addEventListener( original, handler, true );
1161
+ },
1162
+ teardown:function() {
1163
+ this.removeEventListener( original, handler, true );
1164
+ },
1165
+ handler: function(e) {
1166
+ arguments[0] = $.event.fix(e);
1167
+ arguments[0].type = fix;
1168
+ return $.event.handle.apply(this, arguments);
1169
+ }
1170
+ };
1171
+ function handler(e) {
1172
+ e = $.event.fix(e);
1173
+ e.type = fix;
1174
+ return $.event.handle.call(this, e);
1175
+ }
1176
+ });
1177
+ };
1178
+ $.extend($.fn, {
1179
+ validateDelegate: function(delegate, type, handler) {
1180
+ return this.bind(type, function(event) {
1181
+ var target = $(event.target);
1182
+ if (target.is(delegate)) {
1183
+ return handler.apply(target, arguments);
1184
+ }
1185
+ });
1186
+ }
1187
+ });
1188
+ })(jQuery);