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.
- checksums.yaml +7 -0
- data/.gitignore +44 -0
- data/.travis.yml +17 -0
- data/Gemfile +7 -0
- data/LICENSE +21 -0
- data/MIT-LICENSE +20 -0
- data/README.md +159 -0
- data/Rakefile +66 -0
- data/app/controllers/answers_controller.rb +3 -0
- data/app/controllers/application_controller.rb +3 -0
- data/app/controllers/dependencys_controller.rb +286 -0
- data/app/controllers/question_groups_controller.rb +84 -0
- data/app/controllers/questions_controller.rb +187 -0
- data/app/controllers/survey_sections_controller.rb +80 -0
- data/app/controllers/surveyforms_controller.rb +4 -0
- data/app/controllers/surveyor_controller.rb +89 -0
- data/app/controllers/surveyor_gui/reports_controller.rb +339 -0
- data/app/controllers/surveyor_gui/responses_controller.rb +39 -0
- data/app/controllers/surveyor_gui/survey_controller.rb +16 -0
- data/app/facades/report_formatter.rb +44 -0
- data/app/facades/report_preview_wrapper.rb +11 -0
- data/app/facades/report_response_generator.rb +147 -0
- data/app/helpers/application_helper.rb +2 -0
- data/app/helpers/dependency_helper.rb +5 -0
- data/app/helpers/question_helper.rb +22 -0
- data/app/helpers/surveyform_helper.rb +179 -0
- data/app/helpers/surveyor_gui/report_helper.rb +19 -0
- data/app/helpers/surveyor_helper.rb +4 -0
- data/app/inputs/currency_input.rb +5 -0
- data/app/inputs/date_picker_input.rb +7 -0
- data/app/inputs/datetime_picker_input.rb +5 -0
- data/app/inputs/percent_input.rb +5 -0
- data/app/inputs/time_picker_input.rb +5 -0
- data/app/mailers/.gitkeep +0 -0
- data/app/models/.gitkeep +0 -0
- data/app/models/answer.rb +4 -0
- data/app/models/column.rb +3 -0
- data/app/models/dependency.rb +4 -0
- data/app/models/dependency_condition.rb +4 -0
- data/app/models/permitted_params_decorator.rb +80 -0
- data/app/models/question.rb +4 -0
- data/app/models/question_group.rb +4 -0
- data/app/models/question_type.rb +7 -0
- data/app/models/response.rb +4 -0
- data/app/models/response_set.rb +4 -0
- data/app/models/row.rb +3 -0
- data/app/models/survey.rb +4 -0
- data/app/models/survey_section.rb +4 -0
- data/app/models/surveyform.rb +103 -0
- data/app/uploaders/blob_uploader.rb +48 -0
- data/app/views/dependencys/_column.html.erb +1 -0
- data/app/views/dependencys/_dependency.html.erb +22 -0
- data/app/views/dependencys/_dependency_condition_fields.html.erb +48 -0
- data/app/views/dependencys/_form.html.erb +20 -0
- data/app/views/dependencys/blank.html.erb +0 -0
- data/app/views/dependencys/edit.html.erb +1 -0
- data/app/views/dependencys/new.html.erb +1 -0
- data/app/views/layouts/application.html.erb +14 -0
- data/app/views/layouts/surveyor_gui_blank.html.erb +12 -0
- data/app/views/layouts/surveyor_gui_default.html.erb +16 -0
- data/app/views/layouts/surveyor_modified.html.erb +14 -0
- data/app/views/partials/_answer.html.haml +33 -0
- data/app/views/partials/_question.html.haml +33 -0
- data/app/views/partials/_question_group.html.haml +73 -0
- data/app/views/partials/_section.html.haml +13 -0
- data/app/views/question_groups/_form.html.erb +56 -0
- data/app/views/question_groups/_group_inline_field.html.erb +21 -0
- data/app/views/question_groups/_group_inline_fields.html.erb +25 -0
- data/app/views/question_groups/blank.html.erb +0 -0
- data/app/views/question_groups/edit.html.erb +1 -0
- data/app/views/question_groups/new.html.erb +1 -0
- data/app/views/questions/_answer_fields.html.erb +23 -0
- data/app/views/questions/_answer_options.html.erb +28 -0
- data/app/views/questions/_form.html.erb +65 -0
- data/app/views/questions/_grid_dropdown_columns.html.erb +10 -0
- data/app/views/questions/_grid_dropdown_fields.html.erb +42 -0
- data/app/views/questions/_grid_fields.html.erb +9 -0
- data/app/views/questions/_no_picks.html.erb +29 -0
- data/app/views/questions/_pick.html +21 -0
- data/app/views/questions/_picks.html.erb +12 -0
- data/app/views/questions/blank.html.erb +0 -0
- data/app/views/questions/edit.html.erb +1 -0
- data/app/views/questions/new.html.erb +1 -0
- data/app/views/survey_sections/_form.html.erb +13 -0
- data/app/views/survey_sections/blank.html.erb +0 -0
- data/app/views/survey_sections/edit.html.erb +1 -0
- data/app/views/survey_sections/new.html.erb +1 -0
- data/app/views/surveyforms/_form.html.erb +50 -0
- data/app/views/surveyforms/_question_field.html.erb +148 -0
- data/app/views/surveyforms/_question_group.html.erb +116 -0
- data/app/views/surveyforms/_question_group_fields.html.erb +3 -0
- data/app/views/surveyforms/_question_name_and_number.html.erb +6 -0
- data/app/views/surveyforms/_question_section.html.erb +15 -0
- data/app/views/surveyforms/_question_wrapper.html.erb +109 -0
- data/app/views/surveyforms/_survey_section_fields.html.erb +138 -0
- data/app/views/surveyforms/clone_survey.html.erb +13 -0
- data/app/views/surveyforms/edit.html.erb +5 -0
- data/app/views/surveyforms/index.html.erb +40 -0
- data/app/views/surveyforms/new.html.erb +1 -0
- data/app/views/surveyforms/show.html.erb +5 -0
- data/app/views/surveyor_gui/reports/_graphs.html.haml +21 -0
- data/app/views/surveyor_gui/reports/_grid.html.haml +42 -0
- data/app/views/surveyor_gui/reports/_grid_dropdown.html.haml +56 -0
- data/app/views/surveyor_gui/reports/_repeater.html.haml +28 -0
- data/app/views/surveyor_gui/reports/_show_report.html.haml +33 -0
- data/app/views/surveyor_gui/reports/_single_question.html.haml +70 -0
- data/app/views/surveyor_gui/reports/show.html.erb +14 -0
- data/app/views/surveyor_gui/responses/_grid.html.haml +20 -0
- data/app/views/surveyor_gui/responses/_grid_dropdown.html.haml +20 -0
- data/app/views/surveyor_gui/responses/_repeater.html.haml +22 -0
- data/app/views/surveyor_gui/responses/_survey_results.html.haml +40 -0
- data/app/views/surveyor_gui/responses/index.html.haml +24 -0
- data/app/views/surveyor_gui/responses/show.html.haml +42 -0
- data/app/views/surveyor_gui/shared/_grid_comments.html.haml +10 -0
- data/app/views/surveyor_gui/shared/_new_line.html.haml +2 -0
- data/app/views/surveyor_gui/shared/_pick_comments.html.haml +15 -0
- data/app/views/surveyor_gui/shared/_question_number.html.haml +9 -0
- data/app/views/surveyor_gui/shared/_report_data.html.haml +24 -0
- data/app/views/surveyor_gui/shared/_stars_report_data.html.haml +14 -0
- data/config.ru +4 -0
- data/config/environment.rb +0 -0
- data/config/routes.rb +71 -0
- data/db/migrate/20140307204049_add_template_to_surveys.rb +5 -0
- data/db/migrate/20140307235607_add_test_data_to_response_sets.rb +5 -0
- data/db/migrate/20140308171947_add_original_choice_to_answers.rb +5 -0
- data/db/migrate/20140308172118_add_blob_to_responses.rb +5 -0
- data/db/migrate/20140308172417_add_modifiable_to_survey_section.rb +5 -0
- data/db/migrate/20140308174532_add_modifiable_to_question.rb +5 -0
- data/db/migrate/20140308175305_add_dynamically_generate_to_questions.rb +5 -0
- data/db/migrate/20140311032923_add_dummy_blob_to_questions.rb +5 -0
- data/db/migrate/20140311160609_add_dynamic_source_to_questions.rb +5 -0
- data/db/migrate/20140311161714_add_report_code_to_questions.rb +5 -0
- data/db/migrate/20140530181134_add_is_comment_to_questions.rb +5 -0
- data/db/migrate/20140531012006_add_is_comment_to_answers.rb +5 -0
- data/db/migrate/20140531225529_create_rows.rb +9 -0
- data/db/migrate/20140601011151_create_columns.rb +11 -0
- data/db/migrate/20140602030330_add_column_id_to_answers.rb +5 -0
- data/db/migrate/20140603155606_add_column_id_to_responses.rb +5 -0
- data/db/migrate/20140606023527_add_column_id_to_dependency_conditions.rb +5 -0
- data/db/migrate/20140815165307_add_user_id_to_survey.rb +5 -0
- data/lib/assets/.gitkeep +0 -0
- data/lib/assets/images/addicon.png +0 -0
- data/lib/assets/images/datepicker.gif +0 -0
- data/lib/assets/images/delete.gif +0 -0
- data/lib/assets/images/delete.png +0 -0
- data/lib/assets/images/images/border.png +0 -0
- data/lib/assets/images/images/controls.png +0 -0
- data/lib/assets/images/images/loading.gif +0 -0
- data/lib/assets/images/images/loading_background.png +0 -0
- data/lib/assets/images/images/overlay.png +0 -0
- data/lib/assets/images/rails.png +0 -0
- data/lib/assets/images/star.gif +0 -0
- data/lib/assets/javascripts/.gitkeep +0 -0
- data/lib/assets/javascripts/surveyor_gui/jquery.MetaData.js +121 -0
- data/lib/assets/javascripts/surveyor_gui/jquery.blockUI.js +619 -0
- data/lib/assets/javascripts/surveyor_gui/jquery.rating.js +377 -0
- data/lib/assets/javascripts/surveyor_gui/jquery.validate.js +1188 -0
- data/lib/assets/javascripts/surveyor_gui/surveyor_add_ons.js +10 -0
- data/lib/assets/javascripts/surveyor_gui/surveyor_gui.js +1417 -0
- data/lib/assets/stylesheets/.gitkeep +0 -0
- data/lib/assets/stylesheets/surveyor_gui/jquery.rating.css +12 -0
- data/lib/assets/stylesheets/surveyor_gui/surveyor_add_ons.css +3 -0
- data/lib/assets/stylesheets/surveyor_gui/surveyor_gui.sass +650 -0
- data/lib/enumerable_extenders.rb +31 -0
- data/lib/generators/surveyor_gui/install_generator.rb +57 -0
- data/lib/generators/surveyor_gui/templates/app/assets/javascripts/surveyor_add_ons.js +2 -0
- data/lib/generators/surveyor_gui/templates/app/assets/javascripts/surveyor_gui_all.js +24 -0
- data/lib/generators/surveyor_gui/templates/app/assets/stylesheets/surveyor_add_ons.css.sass +1 -0
- data/lib/generators/surveyor_gui/templates/app/assets/stylesheets/surveyor_gui_all.css.sass +8 -0
- data/lib/generators/surveyor_gui/templates/app/helpers/surveyor_helper.rb +4 -0
- data/lib/generators/surveyor_gui/templates/app/models/response_set_user.rb +13 -0
- data/lib/generators/surveyor_gui/templates/app/views/layouts/surveyor_gui_default.html.erb +16 -0
- data/lib/generators/surveyor_gui/templates/config/initializers/simple_form.rb +140 -0
- data/lib/generators/surveyor_gui/templates/config/locales/en.yml +5 -0
- data/lib/surveyor_gui.rb +17 -0
- data/lib/surveyor_gui/engine.rb +30 -0
- data/lib/surveyor_gui/helpers/surveyor_helper_methods.rb +19 -0
- data/lib/surveyor_gui/models/answer_methods.rb +24 -0
- data/lib/surveyor_gui/models/column_methods.rb +43 -0
- data/lib/surveyor_gui/models/dependency_condition_methods.rb +53 -0
- data/lib/surveyor_gui/models/dependency_methods.rb +83 -0
- data/lib/surveyor_gui/models/question_and_group_shared_methods.rb +11 -0
- data/lib/surveyor_gui/models/question_group_methods.rb +55 -0
- data/lib/surveyor_gui/models/question_methods.rb +435 -0
- data/lib/surveyor_gui/models/question_type_methods.rb +493 -0
- data/lib/surveyor_gui/models/response_methods.rb +67 -0
- data/lib/surveyor_gui/models/response_set_methods.rb +54 -0
- data/lib/surveyor_gui/models/row_methods.rb +11 -0
- data/lib/surveyor_gui/models/survey_methods.rb +32 -0
- data/lib/surveyor_gui/models/survey_section_methods.rb +32 -0
- data/lib/surveyor_gui/surveyforms_controller_methods.rb +258 -0
- data/lib/surveyor_gui/version.rb +3 -0
- data/lib/tasks/.gitkeep +0 -0
- data/lib/tasks/surveyor_gui_tasks.rake +4 -0
- data/lib/templates/erb/scaffold/_form.html.erb +13 -0
- data/spec/controllers/surveyforms_controller_spec.rb +361 -0
- data/spec/controllers/surveyor_controller_spec.rb +303 -0
- data/spec/factories.rb +181 -0
- data/spec/features/create_survey_spec.rb +418 -0
- data/spec/features/dependencies_spec.rb +61 -0
- data/spec/features/rearrange_survey_spec.rb +118 -0
- data/spec/features/ui_spec.rb +469 -0
- data/spec/fixtures/REDCapDemoDatabase_DataDictionary.csv +127 -0
- data/spec/fixtures/chinese_survey.rb +14 -0
- data/spec/fixtures/everything.rb +215 -0
- data/spec/fixtures/favorites-ish.rb +22 -0
- data/spec/fixtures/favorites.rb +22 -0
- data/spec/fixtures/feelings.rb +38 -0
- data/spec/fixtures/lifestyle.rb +55 -0
- data/spec/fixtures/numbers.rb +21 -0
- data/spec/fixtures/redcap_new_headers.csv +1 -0
- data/spec/fixtures/redcap_siblings.csv +1 -0
- data/spec/fixtures/redcap_whitespace.csv +1 -0
- data/spec/helpers/formtastic_custom_input_spec.rb +15 -0
- data/spec/helpers/surveyor_helper_spec.rb +116 -0
- data/spec/lib/common_spec.rb +37 -0
- data/spec/lib/parser_spec.rb +393 -0
- data/spec/lib/rake_kitchen_sink.rb +42 -0
- data/spec/lib/redcap_parser_spec.rb +129 -0
- data/spec/lib/unparser_spec.rb +126 -0
- data/spec/models/answer_spec.rb +144 -0
- data/spec/models/dependency_condition_spec.rb +428 -0
- data/spec/models/dependency_spec.rb +90 -0
- data/spec/models/question_group_spec.rb +66 -0
- data/spec/models/question_spec.rb +176 -0
- data/spec/models/response_set_spec.rb +452 -0
- data/spec/models/response_spec.rb +208 -0
- data/spec/models/survey_section_spec.rb +58 -0
- data/spec/models/survey_spec.rb +155 -0
- data/spec/models/surveyor_gui/question_spec.rb +60 -0
- data/spec/models/surveyor_gui/question_type_spec.rb +268 -0
- data/spec/models/validation_condition_spec.rb +98 -0
- data/spec/models/validation_spec.rb +64 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +119 -0
- data/spec/support/scenario_outline_helper.rb +39 -0
- data/spec/support/shared.rb +10 -0
- data/spec/support/surveyforms_creation_helpers.rb +312 -0
- data/spec/support/surveyforms_rearrangement_helpers.rb +170 -0
- data/spec/support/surveyor_api_helpers.rb +15 -0
- data/spec/support/surveyor_ui_helpers.rb +108 -0
- data/spec/support/wait_for_ajax.rb +11 -0
- data/spec/views/questions/edit.html.erb_spec.rb +73 -0
- data/spec/views/surveyforms/edit.html.erb_spec.rb +126 -0
- data/surveyor_gui.gemspec +52 -0
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/mailers/.gitkeep +0 -0
- data/test/dummy/app/models/.gitkeep +0 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +59 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +58 -0
- data/test/dummy/lib/assets/.gitkeep +0 -0
- data/test/dummy/log/.gitkeep +0 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/surveyor-gui_test.rb +7 -0
- data/test/test_helper.rb +15 -0
- data/vendor/assets/stylesheets/.gitkeep +0 -0
- data/vendor/assets/stylesheets/custom.sass +5 -0
- data/vendor/plugins/.gitkeep +0 -0
- 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);
|