affectiva-surveyor 1.5.0.pre.disco.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +28 -0
- data/.rspec +1 -0
- data/CHANGELOG.md +198 -0
- data/Gemfile +5 -0
- data/Gemfile.rails_version +27 -0
- data/MIT-LICENSE +20 -0
- data/README.md +166 -0
- data/Rakefile +106 -0
- data/app/controllers/surveyor_controller.rb +5 -0
- data/app/helpers/results_helper.rb +20 -0
- data/app/helpers/survey_form_builder.rb +37 -0
- data/app/helpers/surveyor_helper.rb +3 -0
- data/app/inputs/quiet_input.rb +5 -0
- data/app/inputs/surveyor_check_boxes_input.rb +35 -0
- data/app/inputs/surveyor_radio_input.rb +18 -0
- data/app/models/answer.rb +3 -0
- data/app/models/dependency.rb +3 -0
- data/app/models/dependency_condition.rb +3 -0
- data/app/models/question.rb +3 -0
- data/app/models/question_group.rb +4 -0
- data/app/models/response.rb +4 -0
- data/app/models/response_set.rb +3 -0
- data/app/models/survey.rb +3 -0
- data/app/models/survey_section.rb +4 -0
- data/app/models/survey_section_sweeper.rb +15 -0
- data/app/models/survey_translation.rb +4 -0
- data/app/models/validation.rb +3 -0
- data/app/models/validation_condition.rb +3 -0
- data/app/views/layouts/results.html.erb +13 -0
- data/app/views/layouts/surveyor_default.html.erb +12 -0
- data/app/views/partials/_answer.html.haml +25 -0
- data/app/views/partials/_dependents.html.haml +5 -0
- data/app/views/partials/_question.html.haml +28 -0
- data/app/views/partials/_question_group.html.haml +44 -0
- data/app/views/partials/_section.html.haml +12 -0
- data/app/views/partials/_section_menu.html.haml +12 -0
- data/app/views/surveyor/edit.html.haml +24 -0
- data/app/views/surveyor/export.json.rabl +85 -0
- data/app/views/surveyor/new.html.haml +24 -0
- data/app/views/surveyor/show.html.haml +74 -0
- data/app/views/surveyor/show.json.rabl +15 -0
- data/ci-exec.sh +56 -0
- data/config/routes.rb +8 -0
- data/cucumber.yml +10 -0
- data/doc/REPRESENTATIONS.md +34 -0
- data/doc/api_id_schema.json +7 -0
- data/doc/question types.png +0 -0
- data/doc/response_set_schema.json +54 -0
- data/doc/surveyor question combinations.png +0 -0
- data/doc/surveyor reject or delete decision matrix.png +0 -0
- data/doc/surveyor_models.png +0 -0
- data/doc/surveyor_models2.png +0 -0
- data/doc/surveyor_timestamp_schema.json +9 -0
- data/features/ajax_submissions.feature +140 -0
- data/features/export_to_json.feature +344 -0
- data/features/internationalization.feature +121 -0
- data/features/no_duplicates.feature +110 -0
- data/features/show_survey.feature +71 -0
- data/features/step_definitions/parser_steps.rb +145 -0
- data/features/step_definitions/surveyor_steps.rb +325 -0
- data/features/step_definitions/ui_steps.rb +25 -0
- data/features/step_definitions/web_steps.rb +225 -0
- data/features/support/REDCapDemoDatabase_DataDictionary.csv +127 -0
- data/features/support/database_cleaner.rb +16 -0
- data/features/support/env.rb +56 -0
- data/features/support/hooks.rb +4 -0
- data/features/support/paths.rb +39 -0
- data/features/support/redcap_new_headers.csv +1 -0
- data/features/support/redcap_siblings.csv +1 -0
- data/features/support/redcap_whitespace.csv +1 -0
- data/features/support/selectors.rb +39 -0
- data/features/support/simultaneous_ajax.rb +101 -0
- data/features/support/single_quit_selenium_driver.rb +23 -0
- data/features/support/slow_updates.rb +18 -0
- data/features/surveyor.feature +895 -0
- data/features/surveyor_dependencies.feature +476 -0
- data/features/surveyor_parser.feature +504 -0
- data/features/z_redcap_parser.feature +62 -0
- data/lib/assets/images/surveyor/next.gif +0 -0
- data/lib/assets/images/surveyor/prev.gif +0 -0
- data/lib/assets/images/surveyor/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/lib/assets/images/surveyor/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/lib/assets/images/surveyor/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/lib/assets/images/surveyor/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/lib/assets/images/surveyor/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/lib/assets/images/surveyor/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/lib/assets/images/surveyor/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/lib/assets/images/surveyor/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/lib/assets/images/surveyor/ui-icons_222222_256x240.png +0 -0
- data/lib/assets/images/surveyor/ui-icons_2e83ff_256x240.png +0 -0
- data/lib/assets/images/surveyor/ui-icons_454545_256x240.png +0 -0
- data/lib/assets/images/surveyor/ui-icons_888888_256x240.png +0 -0
- data/lib/assets/images/surveyor/ui-icons_cd0a0a_256x240.png +0 -0
- data/lib/assets/javascripts/surveyor/jquery-1.9.0.js +9555 -0
- data/lib/assets/javascripts/surveyor/jquery-ui-1.10.0.custom.js +14850 -0
- data/lib/assets/javascripts/surveyor/jquery-ui-timepicker-addon.js +1919 -0
- data/lib/assets/javascripts/surveyor/jquery.maskedinput.js +338 -0
- data/lib/assets/javascripts/surveyor/jquery.selectToUISlider.js +240 -0
- data/lib/assets/javascripts/surveyor/jquery.surveyor.js +154 -0
- data/lib/assets/stylesheets/surveyor.sass +132 -0
- data/lib/assets/stylesheets/surveyor/jquery-ui-1.10.0.custom.css +1174 -0
- data/lib/assets/stylesheets/surveyor/jquery-ui-timepicker-addon.css +11 -0
- data/lib/assets/stylesheets/surveyor/reset.css +48 -0
- data/lib/assets/stylesheets/surveyor/results.css +125 -0
- data/lib/assets/stylesheets/surveyor/ui.slider.extras.css +110 -0
- data/lib/generators/surveyor/custom_generator.rb +18 -0
- data/lib/generators/surveyor/install_generator.rb +101 -0
- data/lib/generators/surveyor/templates/app/assets/javascripts/surveyor_all.js +6 -0
- data/lib/generators/surveyor/templates/app/assets/stylesheets/surveyor_all.css +9 -0
- data/lib/generators/surveyor/templates/app/controllers/surveyor_controller.rb +40 -0
- data/lib/generators/surveyor/templates/app/views/layouts/surveyor_custom.html.erb +13 -0
- data/lib/generators/surveyor/templates/config/locales/surveyor_en.yml +19 -0
- data/lib/generators/surveyor/templates/config/locales/surveyor_es.yml +19 -0
- data/lib/generators/surveyor/templates/config/locales/surveyor_he.yml +19 -0
- data/lib/generators/surveyor/templates/config/locales/surveyor_ko.yml +19 -0
- data/lib/generators/surveyor/templates/db/migrate/add_api_id_to_question_groups.rb +10 -0
- data/lib/generators/surveyor/templates/db/migrate/add_api_ids.rb +14 -0
- data/lib/generators/surveyor/templates/db/migrate/add_api_ids_to_response_sets_and_responses.rb +12 -0
- data/lib/generators/surveyor/templates/db/migrate/add_correct_answer_id_to_questions.rb +10 -0
- data/lib/generators/surveyor/templates/db/migrate/add_default_value_to_answers.rb +10 -0
- data/lib/generators/surveyor/templates/db/migrate/add_display_order_to_surveys.rb +10 -0
- data/lib/generators/surveyor/templates/db/migrate/add_display_type_to_answers.rb +14 -0
- data/lib/generators/surveyor/templates/db/migrate/add_index_to_response_sets.rb +10 -0
- data/lib/generators/surveyor/templates/db/migrate/add_index_to_surveys.rb +10 -0
- data/lib/generators/surveyor/templates/db/migrate/add_input_mask_attributes_to_answer.rb +12 -0
- data/lib/generators/surveyor/templates/db/migrate/add_section_id_to_responses.rb +12 -0
- data/lib/generators/surveyor/templates/db/migrate/add_unique_index_on_access_code_and_version_in_surveys.rb +10 -0
- data/lib/generators/surveyor/templates/db/migrate/add_unique_indicies.rb +18 -0
- data/lib/generators/surveyor/templates/db/migrate/add_version_to_surveys.rb +10 -0
- data/lib/generators/surveyor/templates/db/migrate/api_ids_must_be_unique.rb +23 -0
- data/lib/generators/surveyor/templates/db/migrate/create_answers.rb +38 -0
- data/lib/generators/surveyor/templates/db/migrate/create_dependencies.rb +23 -0
- data/lib/generators/surveyor/templates/db/migrate/create_dependency_conditions.rb +30 -0
- data/lib/generators/surveyor/templates/db/migrate/create_question_groups.rb +28 -0
- data/lib/generators/surveyor/templates/db/migrate/create_questions.rb +37 -0
- data/lib/generators/surveyor/templates/db/migrate/create_response_sets.rb +23 -0
- data/lib/generators/surveyor/templates/db/migrate/create_responses.rb +34 -0
- data/lib/generators/surveyor/templates/db/migrate/create_survey_sections.rb +30 -0
- data/lib/generators/surveyor/templates/db/migrate/create_survey_translations.rb +19 -0
- data/lib/generators/surveyor/templates/db/migrate/create_surveys.rb +32 -0
- data/lib/generators/surveyor/templates/db/migrate/create_validation_conditions.rb +33 -0
- data/lib/generators/surveyor/templates/db/migrate/create_validations.rb +21 -0
- data/lib/generators/surveyor/templates/db/migrate/drop_unique_index_on_access_code_in_surveys.rb +10 -0
- data/lib/generators/surveyor/templates/db/migrate/update_blank_api_ids_on_question_group.rb +22 -0
- data/lib/generators/surveyor/templates/db/migrate/update_blank_versions_on_surveys.rb +13 -0
- data/lib/generators/surveyor/templates/surveys/EXTENDING_SURVEYOR.md +52 -0
- data/lib/generators/surveyor/templates/surveys/MODIFYING_SURVEYOR.md +91 -0
- data/lib/generators/surveyor/templates/surveys/date_survey.rb +16 -0
- data/lib/generators/surveyor/templates/surveys/kitchen_sink_survey.rb +280 -0
- data/lib/generators/surveyor/templates/surveys/languages.rb +14 -0
- data/lib/generators/surveyor/templates/surveys/quiz.rb +11 -0
- data/lib/generators/surveyor/templates/surveys/translations/languages.es.yml +18 -0
- data/lib/generators/surveyor/templates/surveys/translations/languages.he.yml +18 -0
- data/lib/generators/surveyor/templates/surveys/translations/languages.ko.yml +18 -0
- data/lib/generators/surveyor/templates/vendor/assets/stylesheets/custom.sass +5 -0
- data/lib/surveyor.rb +13 -0
- data/lib/surveyor/acts_as_response.rb +17 -0
- data/lib/surveyor/common.rb +59 -0
- data/lib/surveyor/engine.rb +10 -0
- data/lib/surveyor/helpers/asset_pipeline.rb +18 -0
- data/lib/surveyor/helpers/formtastic_custom_input.rb +13 -0
- data/lib/surveyor/helpers/surveyor_helper_methods.rb +103 -0
- data/lib/surveyor/models/answer_methods.rb +83 -0
- data/lib/surveyor/models/dependency_condition_methods.rb +69 -0
- data/lib/surveyor/models/dependency_methods.rb +57 -0
- data/lib/surveyor/models/question_group_methods.rb +58 -0
- data/lib/surveyor/models/question_methods.rb +112 -0
- data/lib/surveyor/models/response_methods.rb +126 -0
- data/lib/surveyor/models/response_set_methods.rb +188 -0
- data/lib/surveyor/models/survey_methods.rb +100 -0
- data/lib/surveyor/models/survey_section_methods.rb +53 -0
- data/lib/surveyor/models/survey_translation_methods.rb +30 -0
- data/lib/surveyor/models/validation_condition_methods.rb +54 -0
- data/lib/surveyor/models/validation_methods.rb +45 -0
- data/lib/surveyor/mustache_context.rb +11 -0
- data/lib/surveyor/parser.rb +427 -0
- data/lib/surveyor/redcap_parser.rb +288 -0
- data/lib/surveyor/surveyor_controller_methods.rb +236 -0
- data/lib/surveyor/unparser.rb +147 -0
- data/lib/surveyor/version.rb +3 -0
- data/lib/tasks/surveyor_tasks.rake +88 -0
- data/rails/init.rb +1 -0
- data/spec/controllers/surveyor_controller_spec.rb +311 -0
- data/spec/factories.rb +166 -0
- data/spec/helpers/formtastic_custom_input_spec.rb +15 -0
- data/spec/helpers/surveyor_helper_spec.rb +117 -0
- data/spec/lib/benchmark_spec.rb +22 -0
- data/spec/lib/chinese_survey.rb +14 -0
- data/spec/lib/common_spec.rb +34 -0
- data/spec/lib/parser_spec.rb +204 -0
- data/spec/lib/rake_kitchen_sink.rb +40 -0
- data/spec/lib/redcap_parser_spec.rb +75 -0
- data/spec/lib/tasks_spec.rake +26 -0
- data/spec/lib/unparser_spec.rb +126 -0
- data/spec/models/answer_spec.rb +174 -0
- data/spec/models/dependency_condition_spec.rb +439 -0
- data/spec/models/dependency_spec.rb +101 -0
- data/spec/models/question_group_spec.rb +93 -0
- data/spec/models/question_spec.rb +206 -0
- data/spec/models/response_set_spec.rb +477 -0
- data/spec/models/response_spec.rb +218 -0
- data/spec/models/survey_section_spec.rb +85 -0
- data/spec/models/survey_spec.rb +191 -0
- data/spec/models/validation_condition_spec.rb +113 -0
- data/spec/models/validation_spec.rb +74 -0
- data/spec/rcov.opts +2 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +56 -0
- data/stacktests.sh +65 -0
- data/surveyor.gemspec +53 -0
- metadata +601 -0
@@ -0,0 +1,338 @@
|
|
1
|
+
/*
|
2
|
+
Masked Input plugin for jQuery
|
3
|
+
Copyright (c) 2007-2013 Josh Bush (digitalbush.com)
|
4
|
+
Licensed under the MIT license (http://digitalbush.com/projects/masked-input-plugin/#license)
|
5
|
+
Version: 1.3.1
|
6
|
+
*/
|
7
|
+
(function($) {
|
8
|
+
function getPasteEvent() {
|
9
|
+
var el = document.createElement('input'),
|
10
|
+
name = 'onpaste';
|
11
|
+
el.setAttribute(name, '');
|
12
|
+
return (typeof el[name] === 'function')?'paste':'input';
|
13
|
+
}
|
14
|
+
|
15
|
+
var pasteEventName = getPasteEvent() + ".mask",
|
16
|
+
ua = navigator.userAgent,
|
17
|
+
iPhone = /iphone/i.test(ua),
|
18
|
+
android=/android/i.test(ua),
|
19
|
+
caretTimeoutId;
|
20
|
+
|
21
|
+
$.mask = {
|
22
|
+
//Predefined character definitions
|
23
|
+
definitions: {
|
24
|
+
'9': "[0-9]",
|
25
|
+
'a': "[A-Za-z]",
|
26
|
+
'*': "[A-Za-z0-9]"
|
27
|
+
},
|
28
|
+
dataName: "rawMaskFn",
|
29
|
+
placeholder: '_',
|
30
|
+
};
|
31
|
+
|
32
|
+
$.fn.extend({
|
33
|
+
//Helper Function for Caret positioning
|
34
|
+
caret: function(begin, end) {
|
35
|
+
var range;
|
36
|
+
|
37
|
+
if (this.length === 0 || this.is(":hidden")) {
|
38
|
+
return;
|
39
|
+
}
|
40
|
+
|
41
|
+
if (typeof begin == 'number') {
|
42
|
+
end = (typeof end === 'number') ? end : begin;
|
43
|
+
return this.each(function() {
|
44
|
+
if (this.setSelectionRange) {
|
45
|
+
this.setSelectionRange(begin, end);
|
46
|
+
} else if (this.createTextRange) {
|
47
|
+
range = this.createTextRange();
|
48
|
+
range.collapse(true);
|
49
|
+
range.moveEnd('character', end);
|
50
|
+
range.moveStart('character', begin);
|
51
|
+
range.select();
|
52
|
+
}
|
53
|
+
});
|
54
|
+
} else {
|
55
|
+
if (this[0].setSelectionRange) {
|
56
|
+
begin = this[0].selectionStart;
|
57
|
+
end = this[0].selectionEnd;
|
58
|
+
} else if (document.selection && document.selection.createRange) {
|
59
|
+
range = document.selection.createRange();
|
60
|
+
begin = 0 - range.duplicate().moveStart('character', -100000);
|
61
|
+
end = begin + range.text.length;
|
62
|
+
}
|
63
|
+
return { begin: begin, end: end };
|
64
|
+
}
|
65
|
+
},
|
66
|
+
unmask: function() {
|
67
|
+
return this.trigger("unmask");
|
68
|
+
},
|
69
|
+
mask: function(mask, settings) {
|
70
|
+
var input,
|
71
|
+
defs,
|
72
|
+
tests,
|
73
|
+
partialPosition,
|
74
|
+
firstNonMaskPos,
|
75
|
+
len;
|
76
|
+
|
77
|
+
if (!mask && this.length > 0) {
|
78
|
+
input = $(this[0]);
|
79
|
+
return input.data($.mask.dataName)();
|
80
|
+
}
|
81
|
+
settings = $.extend({
|
82
|
+
placeholder: $.mask.placeholder, // Load default placeholder
|
83
|
+
completed: null
|
84
|
+
}, settings);
|
85
|
+
|
86
|
+
|
87
|
+
defs = $.mask.definitions;
|
88
|
+
tests = [];
|
89
|
+
partialPosition = len = mask.length;
|
90
|
+
firstNonMaskPos = null;
|
91
|
+
|
92
|
+
$.each(mask.split(""), function(i, c) {
|
93
|
+
if (c == '?') {
|
94
|
+
len--;
|
95
|
+
partialPosition = i;
|
96
|
+
} else if (defs[c]) {
|
97
|
+
tests.push(new RegExp(defs[c]));
|
98
|
+
if (firstNonMaskPos === null) {
|
99
|
+
firstNonMaskPos = tests.length - 1;
|
100
|
+
}
|
101
|
+
} else {
|
102
|
+
tests.push(null);
|
103
|
+
}
|
104
|
+
});
|
105
|
+
|
106
|
+
return this.trigger("unmask").each(function() {
|
107
|
+
var input = $(this),
|
108
|
+
buffer = $.map(
|
109
|
+
mask.split(""),
|
110
|
+
function(c, i) {
|
111
|
+
if (c != '?') {
|
112
|
+
return defs[c] ? settings.placeholder : c;
|
113
|
+
}
|
114
|
+
}),
|
115
|
+
focusText = input.val();
|
116
|
+
|
117
|
+
function seekNext(pos) {
|
118
|
+
while (++pos < len && !tests[pos]);
|
119
|
+
return pos;
|
120
|
+
}
|
121
|
+
|
122
|
+
function seekPrev(pos) {
|
123
|
+
while (--pos >= 0 && !tests[pos]);
|
124
|
+
return pos;
|
125
|
+
}
|
126
|
+
|
127
|
+
function shiftL(begin,end) {
|
128
|
+
var i,
|
129
|
+
j;
|
130
|
+
|
131
|
+
if (begin<0) {
|
132
|
+
return;
|
133
|
+
}
|
134
|
+
|
135
|
+
for (i = begin, j = seekNext(end); i < len; i++) {
|
136
|
+
if (tests[i]) {
|
137
|
+
if (j < len && tests[i].test(buffer[j])) {
|
138
|
+
buffer[i] = buffer[j];
|
139
|
+
buffer[j] = settings.placeholder;
|
140
|
+
} else {
|
141
|
+
break;
|
142
|
+
}
|
143
|
+
|
144
|
+
j = seekNext(j);
|
145
|
+
}
|
146
|
+
}
|
147
|
+
writeBuffer();
|
148
|
+
input.caret(Math.max(firstNonMaskPos, begin));
|
149
|
+
}
|
150
|
+
|
151
|
+
function shiftR(pos) {
|
152
|
+
var i,
|
153
|
+
c,
|
154
|
+
j,
|
155
|
+
t;
|
156
|
+
|
157
|
+
for (i = pos, c = settings.placeholder; i < len; i++) {
|
158
|
+
if (tests[i]) {
|
159
|
+
j = seekNext(i);
|
160
|
+
t = buffer[i];
|
161
|
+
buffer[i] = c;
|
162
|
+
if (j < len && tests[j].test(t)) {
|
163
|
+
c = t;
|
164
|
+
} else {
|
165
|
+
break;
|
166
|
+
}
|
167
|
+
}
|
168
|
+
}
|
169
|
+
}
|
170
|
+
|
171
|
+
function keydownEvent(e) {
|
172
|
+
var k = e.which,
|
173
|
+
pos,
|
174
|
+
begin,
|
175
|
+
end;
|
176
|
+
|
177
|
+
//backspace, delete, and escape get special treatment
|
178
|
+
if (k === 8 || k === 46 || (iPhone && k === 127)) {
|
179
|
+
pos = input.caret();
|
180
|
+
begin = pos.begin;
|
181
|
+
end = pos.end;
|
182
|
+
|
183
|
+
if (end - begin === 0) {
|
184
|
+
begin=k!==46?seekPrev(begin):(end=seekNext(begin-1));
|
185
|
+
end=k===46?seekNext(end):end;
|
186
|
+
}
|
187
|
+
clearBuffer(begin, end);
|
188
|
+
shiftL(begin, end - 1);
|
189
|
+
|
190
|
+
e.preventDefault();
|
191
|
+
} else if (k == 27) {//escape
|
192
|
+
input.val(focusText);
|
193
|
+
input.caret(0, checkVal());
|
194
|
+
e.preventDefault();
|
195
|
+
}
|
196
|
+
}
|
197
|
+
|
198
|
+
function keypressEvent(e) {
|
199
|
+
var k = e.which,
|
200
|
+
pos = input.caret(),
|
201
|
+
p,
|
202
|
+
c,
|
203
|
+
next;
|
204
|
+
|
205
|
+
if (e.ctrlKey || e.altKey || e.metaKey || k < 32) {//Ignore
|
206
|
+
return;
|
207
|
+
} else if (k) {
|
208
|
+
if (pos.end - pos.begin !== 0){
|
209
|
+
clearBuffer(pos.begin, pos.end);
|
210
|
+
shiftL(pos.begin, pos.end-1);
|
211
|
+
}
|
212
|
+
|
213
|
+
p = seekNext(pos.begin - 1);
|
214
|
+
if (p < len) {
|
215
|
+
c = String.fromCharCode(k);
|
216
|
+
if (tests[p].test(c)) {
|
217
|
+
shiftR(p);
|
218
|
+
|
219
|
+
buffer[p] = c;
|
220
|
+
writeBuffer();
|
221
|
+
next = seekNext(p);
|
222
|
+
|
223
|
+
if(android){
|
224
|
+
setTimeout($.proxy($.fn.caret,input,next),0);
|
225
|
+
}else{
|
226
|
+
input.caret(next);
|
227
|
+
}
|
228
|
+
|
229
|
+
if (settings.completed && next >= len) {
|
230
|
+
settings.completed.call(input);
|
231
|
+
}
|
232
|
+
}
|
233
|
+
}
|
234
|
+
e.preventDefault();
|
235
|
+
}
|
236
|
+
}
|
237
|
+
|
238
|
+
function clearBuffer(start, end) {
|
239
|
+
var i;
|
240
|
+
for (i = start; i < end && i < len; i++) {
|
241
|
+
if (tests[i]) {
|
242
|
+
buffer[i] = settings.placeholder;
|
243
|
+
}
|
244
|
+
}
|
245
|
+
}
|
246
|
+
|
247
|
+
function writeBuffer() { input.val(buffer.join('')); }
|
248
|
+
|
249
|
+
function checkVal(allow) {
|
250
|
+
//try to place characters where they belong
|
251
|
+
var test = input.val(),
|
252
|
+
lastMatch = -1,
|
253
|
+
i,
|
254
|
+
c;
|
255
|
+
|
256
|
+
for (i = 0, pos = 0; i < len; i++) {
|
257
|
+
if (tests[i]) {
|
258
|
+
buffer[i] = settings.placeholder;
|
259
|
+
while (pos++ < test.length) {
|
260
|
+
c = test.charAt(pos - 1);
|
261
|
+
if (tests[i].test(c)) {
|
262
|
+
buffer[i] = c;
|
263
|
+
lastMatch = i;
|
264
|
+
break;
|
265
|
+
}
|
266
|
+
}
|
267
|
+
if (pos > test.length) {
|
268
|
+
break;
|
269
|
+
}
|
270
|
+
} else if (buffer[i] === test.charAt(pos) && i !== partialPosition) {
|
271
|
+
pos++;
|
272
|
+
lastMatch = i;
|
273
|
+
}
|
274
|
+
}
|
275
|
+
if (allow) {
|
276
|
+
writeBuffer();
|
277
|
+
} else if (lastMatch + 1 < partialPosition) {
|
278
|
+
input.val("");
|
279
|
+
clearBuffer(0, len);
|
280
|
+
} else {
|
281
|
+
writeBuffer();
|
282
|
+
input.val(input.val().substring(0, lastMatch + 1));
|
283
|
+
}
|
284
|
+
return (partialPosition ? i : firstNonMaskPos);
|
285
|
+
}
|
286
|
+
|
287
|
+
input.data($.mask.dataName,function(){
|
288
|
+
return $.map(buffer, function(c, i) {
|
289
|
+
return tests[i]&&c!=settings.placeholder ? c : null;
|
290
|
+
}).join('');
|
291
|
+
});
|
292
|
+
|
293
|
+
if (!input.attr("readonly"))
|
294
|
+
input
|
295
|
+
.one("unmask", function() {
|
296
|
+
input
|
297
|
+
.unbind(".mask")
|
298
|
+
.removeData($.mask.dataName);
|
299
|
+
})
|
300
|
+
.bind("focus.mask", function() {
|
301
|
+
clearTimeout(caretTimeoutId);
|
302
|
+
var pos,
|
303
|
+
moveCaret;
|
304
|
+
|
305
|
+
focusText = input.val();
|
306
|
+
pos = checkVal();
|
307
|
+
|
308
|
+
caretTimeoutId = setTimeout(function(){
|
309
|
+
writeBuffer();
|
310
|
+
if (pos == mask.length) {
|
311
|
+
input.caret(0, pos);
|
312
|
+
} else {
|
313
|
+
input.caret(pos);
|
314
|
+
}
|
315
|
+
}, 10);
|
316
|
+
})
|
317
|
+
.bind("blur.mask", function() {
|
318
|
+
checkVal();
|
319
|
+
if (input.val() != focusText)
|
320
|
+
input.change();
|
321
|
+
})
|
322
|
+
.bind("keydown.mask", keydownEvent)
|
323
|
+
.bind("keypress.mask", keypressEvent)
|
324
|
+
.bind(pasteEventName, function() {
|
325
|
+
setTimeout(function() {
|
326
|
+
var pos=checkVal(true);
|
327
|
+
input.caret(pos);
|
328
|
+
if (settings.completed && pos == input.val().length)
|
329
|
+
settings.completed.call(input);
|
330
|
+
}, 0);
|
331
|
+
});
|
332
|
+
checkVal(); //Perform initial check for existing values
|
333
|
+
});
|
334
|
+
}
|
335
|
+
});
|
336
|
+
|
337
|
+
|
338
|
+
})(jQuery);
|
@@ -0,0 +1,240 @@
|
|
1
|
+
/*
|
2
|
+
* --------------------------------------------------------------------
|
3
|
+
* jQuery-Plugin - selectToUISlider - creates a UI slider component from a select element(s)
|
4
|
+
* by Scott Jehl, scott@filamentgroup.com
|
5
|
+
* http://www.filamentgroup.com
|
6
|
+
* reference article: http://www.filamentgroup.com/lab/update_jquery_ui_16_slider_from_a_select_element/
|
7
|
+
* demo page: http://www.filamentgroup.com/examples/slider_v2/index.html
|
8
|
+
*
|
9
|
+
* Copyright (c) 2008 Filament Group, Inc
|
10
|
+
* Dual licensed under the MIT (filamentgroup.com/examples/mit-license.txt) and GPL (filamentgroup.com/examples/gpl-license.txt) licenses.
|
11
|
+
*
|
12
|
+
* Usage Notes: please refer to our article above for documentation
|
13
|
+
*
|
14
|
+
* --------------------------------------------------------------------
|
15
|
+
*/
|
16
|
+
|
17
|
+
|
18
|
+
jQuery.fn.selectToUISlider = function(settings){
|
19
|
+
var selects = jQuery(this);
|
20
|
+
|
21
|
+
//accessible slider options
|
22
|
+
var options = jQuery.extend({
|
23
|
+
labels: 3, //number of visible labels
|
24
|
+
tooltip: true, //show tooltips, boolean
|
25
|
+
tooltipSrc: 'text',//accepts 'value' as well
|
26
|
+
labelSrc: 'value',//accepts 'value' as well ,
|
27
|
+
sliderOptions: null
|
28
|
+
}, settings);
|
29
|
+
|
30
|
+
|
31
|
+
//handle ID attrs - selects each need IDs for handles to find them
|
32
|
+
var handleIds = (function(){
|
33
|
+
var tempArr = [];
|
34
|
+
selects.each(function(){
|
35
|
+
tempArr.push('handle_'+jQuery(this).attr('id'));
|
36
|
+
});
|
37
|
+
return tempArr;
|
38
|
+
})();
|
39
|
+
|
40
|
+
//array of all option elements in select element (ignores optgroups)
|
41
|
+
var selectOptions = (function(){
|
42
|
+
var opts = [];
|
43
|
+
selects.eq(0).find('option').each(function(){
|
44
|
+
opts.push({
|
45
|
+
value: jQuery(this).attr('value'),
|
46
|
+
text: jQuery(this).text()
|
47
|
+
});
|
48
|
+
});
|
49
|
+
return opts;
|
50
|
+
})();
|
51
|
+
|
52
|
+
//array of opt groups if present
|
53
|
+
var groups = (function(){
|
54
|
+
if(selects.eq(0).find('optgroup').size()>0){
|
55
|
+
var groupedData = [];
|
56
|
+
selects.eq(0).find('optgroup').each(function(i){
|
57
|
+
groupedData[i] = {};
|
58
|
+
groupedData[i].label = jQuery(this).attr('label');
|
59
|
+
groupedData[i].options = [];
|
60
|
+
jQuery(this).find('option').each(function(){
|
61
|
+
groupedData[i].options.push({text: jQuery(this).text(), value: jQuery(this).attr('value')});
|
62
|
+
});
|
63
|
+
});
|
64
|
+
return groupedData;
|
65
|
+
}
|
66
|
+
else return null;
|
67
|
+
})();
|
68
|
+
|
69
|
+
//check if obj is array
|
70
|
+
function isArray(obj) {
|
71
|
+
return obj.constructor == Array;
|
72
|
+
}
|
73
|
+
//return tooltip text from option index
|
74
|
+
function ttText(optIndex){
|
75
|
+
return (options.tooltipSrc == 'text') ? selectOptions[optIndex].text : selectOptions[optIndex].value;
|
76
|
+
}
|
77
|
+
|
78
|
+
//plugin-generated slider options (can be overridden)
|
79
|
+
var sliderOptions = {
|
80
|
+
step: 1,
|
81
|
+
min: 0,
|
82
|
+
orientation: 'horizontal',
|
83
|
+
max: selectOptions.length-1,
|
84
|
+
range: selects.length > 1,//multiple select elements = true
|
85
|
+
slide: function(e, ui) {//slide function
|
86
|
+
var thisHandle = jQuery(ui.handle);
|
87
|
+
//handle feedback
|
88
|
+
var textval = ttText(ui.value);
|
89
|
+
thisHandle
|
90
|
+
.attr('aria-valuetext', textval)
|
91
|
+
.attr('aria-valuenow', ui.value)
|
92
|
+
.find('.ui-slider-tooltip .ttContent')
|
93
|
+
.text( textval );
|
94
|
+
|
95
|
+
//control original select menu
|
96
|
+
var currSelect = jQuery('#' + thisHandle.attr('id').split('handle_')[1]);
|
97
|
+
currSelect.find('option').eq(ui.value).attr('selected', 'selected');
|
98
|
+
},
|
99
|
+
values: (function(){
|
100
|
+
var values = [];
|
101
|
+
selects.each(function(){
|
102
|
+
values.push( jQuery(this).get(0).selectedIndex );
|
103
|
+
});
|
104
|
+
return values;
|
105
|
+
})()
|
106
|
+
};
|
107
|
+
|
108
|
+
//slider options from settings
|
109
|
+
options.sliderOptions = (settings) ? jQuery.extend(sliderOptions, settings.sliderOptions) : sliderOptions;
|
110
|
+
|
111
|
+
//select element change event
|
112
|
+
selects.bind('change keyup click', function(){
|
113
|
+
var thisIndex = jQuery(this).get(0).selectedIndex;
|
114
|
+
var thisHandle = jQuery('#handle_'+ jQuery(this).attr('id'));
|
115
|
+
var handleIndex = thisHandle.data('handleNum');
|
116
|
+
thisHandle.parents('.ui-slider:eq(0)').slider("values", handleIndex, thisIndex);
|
117
|
+
});
|
118
|
+
|
119
|
+
|
120
|
+
//create slider component div
|
121
|
+
var sliderComponent = jQuery('<div></div>');
|
122
|
+
|
123
|
+
//CREATE HANDLES
|
124
|
+
selects.each(function(i){
|
125
|
+
var hidett = '';
|
126
|
+
|
127
|
+
//associate label for ARIA
|
128
|
+
var thisLabel = jQuery('label[for=' + jQuery(this).attr('id') +']');
|
129
|
+
//labelled by aria doesn't seem to work on slider handle. Using title attr as backup
|
130
|
+
var labelText = (thisLabel.size()>0) ? 'Slider control for '+ thisLabel.text()+'' : '';
|
131
|
+
var thisLabelId = thisLabel.attr('id') || thisLabel.attr('id', 'label_'+handleIds[i]).attr('id');
|
132
|
+
|
133
|
+
|
134
|
+
if( options.tooltip == false ){hidett = ' style="display: none;"';}
|
135
|
+
jQuery('<a '+
|
136
|
+
'href="#" tabindex="0" '+
|
137
|
+
'id="'+handleIds[i]+'" '+
|
138
|
+
'class="ui-slider-handle" '+
|
139
|
+
'role="slider" '+
|
140
|
+
'aria-labelledby="'+thisLabelId+'" '+
|
141
|
+
'aria-valuemin="'+options.sliderOptions.min+'" '+
|
142
|
+
'aria-valuemax="'+options.sliderOptions.max+'" '+
|
143
|
+
'aria-valuenow="'+options.sliderOptions.values[i]+'" '+
|
144
|
+
'aria-valuetext="'+ttText(options.sliderOptions.values[i])+'" '+
|
145
|
+
'><span class="screenReaderContext">'+labelText+'</span>'+
|
146
|
+
'<span class="ui-slider-tooltip ui-widget-content ui-corner-all"'+ hidett +'><span class="ttContent"></span>'+
|
147
|
+
'<span class="ui-tooltip-pointer-down ui-widget-content"><span class="ui-tooltip-pointer-down-inner"></span></span>'+
|
148
|
+
'</span></a>')
|
149
|
+
.data('handleNum',i)
|
150
|
+
.appendTo(sliderComponent);
|
151
|
+
});
|
152
|
+
|
153
|
+
//CREATE SCALE AND TICS
|
154
|
+
|
155
|
+
//write dl if there are optgroups
|
156
|
+
if(groups) {
|
157
|
+
var inc = 0;
|
158
|
+
var scale = sliderComponent.append('<dl class="ui-slider-scale ui-helper-reset" role="presentation"></dl>').find('.ui-slider-scale:eq(0)');
|
159
|
+
jQuery(groups).each(function(h){
|
160
|
+
scale.append('<dt style="width: '+ (100/groups.length).toFixed(2) +'%' +'; left:'+ (h/(groups.length-1) * 100).toFixed(2) +'%' +'"><span>'+this.label+'</span></dt>');//class name becomes camelCased label
|
161
|
+
var groupOpts = this.options;
|
162
|
+
jQuery(this.options).each(function(i){
|
163
|
+
var style = (inc == selectOptions.length-1 || inc == 0) ? 'style="display: none;"' : '' ;
|
164
|
+
var labelText = (options.labelSrc == 'text') ? groupOpts[i].text : groupOpts[i].value;
|
165
|
+
scale.append('<dd style="left:'+ leftVal(inc) +'"><span class="ui-slider-label">'+ labelText +'</span><span class="ui-slider-tic ui-widget-content"'+ style +'></span></dd>');
|
166
|
+
inc++;
|
167
|
+
});
|
168
|
+
});
|
169
|
+
}
|
170
|
+
//write ol
|
171
|
+
else {
|
172
|
+
var scale = sliderComponent.append('<ol class="ui-slider-scale ui-helper-reset" role="presentation"></ol>').find('.ui-slider-scale:eq(0)');
|
173
|
+
jQuery(selectOptions).each(function(i){
|
174
|
+
var style = (i == selectOptions.length-1 || i == 0) ? 'style="display: none;"' : '' ;
|
175
|
+
var labelText = (options.labelSrc == 'text') ? this.text : this.value;
|
176
|
+
scale.append('<li style="left:'+ leftVal(i) +'"><span class="ui-slider-label">'+ labelText +'</span><span class="ui-slider-tic ui-widget-content"'+ style +'></span></li>');
|
177
|
+
});
|
178
|
+
}
|
179
|
+
|
180
|
+
function leftVal(i){
|
181
|
+
return (i/(selectOptions.length-1) * 100).toFixed(2) +'%';
|
182
|
+
|
183
|
+
}
|
184
|
+
|
185
|
+
|
186
|
+
|
187
|
+
|
188
|
+
//show and hide labels depending on labels pref
|
189
|
+
//show the last one if there are more than 1 specified
|
190
|
+
if(options.labels > 1) sliderComponent.find('.ui-slider-scale li:last span.ui-slider-label, .ui-slider-scale dd:last span.ui-slider-label').addClass('ui-slider-label-show');
|
191
|
+
|
192
|
+
//set increment
|
193
|
+
var increm = Math.max(1, Math.round(selectOptions.length / options.labels));
|
194
|
+
//show em based on inc
|
195
|
+
for(var j=0; j<selectOptions.length; j+=increm){
|
196
|
+
if((selectOptions.length - j) > increm){//don't show if it's too close to the end label
|
197
|
+
sliderComponent.find('.ui-slider-scale li:eq('+ j +') span.ui-slider-label, .ui-slider-scale dd:eq('+ j +') span.ui-slider-label').addClass('ui-slider-label-show');
|
198
|
+
}
|
199
|
+
}
|
200
|
+
|
201
|
+
//style the dt's
|
202
|
+
sliderComponent.find('.ui-slider-scale dt').each(function(i){
|
203
|
+
jQuery(this).css({
|
204
|
+
'left': ((100 /( groups.length))*i).toFixed(2) + '%'
|
205
|
+
});
|
206
|
+
});
|
207
|
+
|
208
|
+
|
209
|
+
//inject and return
|
210
|
+
sliderComponent
|
211
|
+
.insertAfter(jQuery(this).eq(this.length-1))
|
212
|
+
.slider(options.sliderOptions)
|
213
|
+
.attr('role','application')
|
214
|
+
.find('.ui-slider-label')
|
215
|
+
.each(function(){
|
216
|
+
jQuery(this).css('marginLeft', -jQuery(this).width()/2);
|
217
|
+
});
|
218
|
+
|
219
|
+
//update tooltip arrow inner color
|
220
|
+
sliderComponent.find('.ui-tooltip-pointer-down-inner').each(function(){
|
221
|
+
var bWidth = jQuery('.ui-tooltip-pointer-down-inner').css('borderTopWidth');
|
222
|
+
var bColor = jQuery(this).parents('.ui-slider-tooltip').css('backgroundColor')
|
223
|
+
jQuery(this).css('border-top', bWidth+' solid '+bColor);
|
224
|
+
});
|
225
|
+
|
226
|
+
var values = sliderComponent.slider('values');
|
227
|
+
|
228
|
+
if(isArray(values)){
|
229
|
+
jQuery(values).each(function(i){
|
230
|
+
sliderComponent.find('.ui-slider-tooltip .ttContent').eq(i).text( ttText(this) );
|
231
|
+
});
|
232
|
+
}
|
233
|
+
else {
|
234
|
+
sliderComponent.find('.ui-slider-tooltip .ttContent').eq(0).text( ttText(values) );
|
235
|
+
}
|
236
|
+
|
237
|
+
return this;
|
238
|
+
}
|
239
|
+
|
240
|
+
|