hssc_surveyor 1.4.1.pre

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. data/.gitignore +28 -0
  2. data/.rspec +1 -0
  3. data/CHANGELOG.md +198 -0
  4. data/Gemfile +5 -0
  5. data/Gemfile.rails_version +19 -0
  6. data/MIT-LICENSE +20 -0
  7. data/README.md +186 -0
  8. data/Rakefile +105 -0
  9. data/app/controllers/surveyor_controller.rb +6 -0
  10. data/app/helpers/results_helper.rb +20 -0
  11. data/app/helpers/survey_form_builder.rb +37 -0
  12. data/app/helpers/surveyor_helper.rb +3 -0
  13. data/app/inputs/quiet_input.rb +5 -0
  14. data/app/inputs/surveyor_check_boxes_input.rb +35 -0
  15. data/app/inputs/surveyor_radio_input.rb +18 -0
  16. data/app/models/answer.rb +4 -0
  17. data/app/models/dependency.rb +4 -0
  18. data/app/models/dependency_condition.rb +4 -0
  19. data/app/models/question.rb +4 -0
  20. data/app/models/question_group.rb +5 -0
  21. data/app/models/response.rb +5 -0
  22. data/app/models/response_set.rb +4 -0
  23. data/app/models/survey.rb +4 -0
  24. data/app/models/survey_section.rb +5 -0
  25. data/app/models/survey_section_sweeper.rb +15 -0
  26. data/app/models/survey_translation.rb +5 -0
  27. data/app/models/validation.rb +4 -0
  28. data/app/models/validation_condition.rb +4 -0
  29. data/app/views/layouts/results.html.erb +13 -0
  30. data/app/views/layouts/surveyor_default.html.erb +12 -0
  31. data/app/views/partials/_answer.html.haml +25 -0
  32. data/app/views/partials/_dependents.html.haml +5 -0
  33. data/app/views/partials/_question.html.haml +41 -0
  34. data/app/views/partials/_question_group.html.haml +44 -0
  35. data/app/views/partials/_section.html.haml +12 -0
  36. data/app/views/partials/_section_menu.html.haml +12 -0
  37. data/app/views/surveyor/edit.html.haml +24 -0
  38. data/app/views/surveyor/export.json.rabl +85 -0
  39. data/app/views/surveyor/new.html.haml +24 -0
  40. data/app/views/surveyor/show.html.haml +74 -0
  41. data/app/views/surveyor/show.json.rabl +15 -0
  42. data/ci-exec.sh +56 -0
  43. data/config/routes.rb +8 -0
  44. data/cucumber.yml +10 -0
  45. data/doc/REPRESENTATIONS.md +34 -0
  46. data/doc/api_id_schema.json +7 -0
  47. data/doc/question types.png +0 -0
  48. data/doc/response_set_schema.json +54 -0
  49. data/doc/surveyor question combinations.png +0 -0
  50. data/doc/surveyor reject or delete decision matrix.png +0 -0
  51. data/doc/surveyor_models.png +0 -0
  52. data/doc/surveyor_models2.png +0 -0
  53. data/doc/surveyor_timestamp_schema.json +9 -0
  54. data/features/ajax_submissions.feature +140 -0
  55. data/features/export_to_json.feature +344 -0
  56. data/features/internationalization.feature +121 -0
  57. data/features/no_duplicates.feature +110 -0
  58. data/features/show_survey.feature +71 -0
  59. data/features/step_definitions/parser_steps.rb +145 -0
  60. data/features/step_definitions/surveyor_steps.rb +325 -0
  61. data/features/step_definitions/ui_steps.rb +25 -0
  62. data/features/step_definitions/web_steps.rb +225 -0
  63. data/features/support/REDCapDemoDatabase_DataDictionary.csv +127 -0
  64. data/features/support/database_cleaner.rb +16 -0
  65. data/features/support/env.rb +56 -0
  66. data/features/support/hooks.rb +4 -0
  67. data/features/support/paths.rb +39 -0
  68. data/features/support/redcap_new_headers.csv +1 -0
  69. data/features/support/redcap_siblings.csv +1 -0
  70. data/features/support/redcap_whitespace.csv +1 -0
  71. data/features/support/selectors.rb +39 -0
  72. data/features/support/simultaneous_ajax.rb +101 -0
  73. data/features/support/single_quit_selenium_driver.rb +23 -0
  74. data/features/support/slow_updates.rb +18 -0
  75. data/features/surveyor.feature +895 -0
  76. data/features/surveyor_dependencies.feature +476 -0
  77. data/features/surveyor_parser.feature +504 -0
  78. data/features/z_redcap_parser.feature +62 -0
  79. data/lib/assets/images/surveyor/next.gif +0 -0
  80. data/lib/assets/images/surveyor/prev.gif +0 -0
  81. data/lib/assets/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  82. data/lib/assets/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  83. data/lib/assets/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  84. data/lib/assets/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  85. data/lib/assets/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  86. data/lib/assets/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  87. data/lib/assets/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  88. data/lib/assets/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  89. data/lib/assets/images/ui-icons_222222_256x240.png +0 -0
  90. data/lib/assets/images/ui-icons_2e83ff_256x240.png +0 -0
  91. data/lib/assets/images/ui-icons_454545_256x240.png +0 -0
  92. data/lib/assets/images/ui-icons_888888_256x240.png +0 -0
  93. data/lib/assets/images/ui-icons_cd0a0a_256x240.png +0 -0
  94. data/lib/assets/javascripts/surveyor/jquery-1.9.0.js +9555 -0
  95. data/lib/assets/javascripts/surveyor/jquery-ui-1.10.0.custom.js +14850 -0
  96. data/lib/assets/javascripts/surveyor/jquery-ui-timepicker-addon.js +1919 -0
  97. data/lib/assets/javascripts/surveyor/jquery.maskedinput.js +338 -0
  98. data/lib/assets/javascripts/surveyor/jquery.selectToUISlider.js +240 -0
  99. data/lib/assets/javascripts/surveyor/jquery.surveyor.js +156 -0
  100. data/lib/assets/stylesheets/surveyor/jquery-ui-1.10.0.custom.css +1174 -0
  101. data/lib/assets/stylesheets/surveyor/jquery-ui-timepicker-addon.css +11 -0
  102. data/lib/assets/stylesheets/surveyor/reset.css +48 -0
  103. data/lib/assets/stylesheets/surveyor/results.css +125 -0
  104. data/lib/assets/stylesheets/surveyor/ui.slider.extras.css +110 -0
  105. data/lib/assets/stylesheets/surveyor.sass +132 -0
  106. data/lib/generators/surveyor/custom_generator.rb +18 -0
  107. data/lib/generators/surveyor/install_generator.rb +102 -0
  108. data/lib/generators/surveyor/templates/app/assets/javascripts/surveyor_all.js +6 -0
  109. data/lib/generators/surveyor/templates/app/assets/stylesheets/surveyor_all.css +9 -0
  110. data/lib/generators/surveyor/templates/app/controllers/surveyor_controller.rb +40 -0
  111. data/lib/generators/surveyor/templates/app/views/layouts/surveyor_custom.html.erb +13 -0
  112. data/lib/generators/surveyor/templates/config/locales/surveyor_en.yml +19 -0
  113. data/lib/generators/surveyor/templates/config/locales/surveyor_es.yml +19 -0
  114. data/lib/generators/surveyor/templates/config/locales/surveyor_he.yml +19 -0
  115. data/lib/generators/surveyor/templates/config/locales/surveyor_ko.yml +19 -0
  116. data/lib/generators/surveyor/templates/db/migrate/add_api_id_to_question_groups.rb +10 -0
  117. data/lib/generators/surveyor/templates/db/migrate/add_api_ids.rb +14 -0
  118. data/lib/generators/surveyor/templates/db/migrate/add_api_ids_to_response_sets_and_responses.rb +12 -0
  119. data/lib/generators/surveyor/templates/db/migrate/add_attachment_to_response.rb +5 -0
  120. data/lib/generators/surveyor/templates/db/migrate/add_correct_answer_id_to_questions.rb +10 -0
  121. data/lib/generators/surveyor/templates/db/migrate/add_default_value_to_answers.rb +10 -0
  122. data/lib/generators/surveyor/templates/db/migrate/add_display_order_to_surveys.rb +10 -0
  123. data/lib/generators/surveyor/templates/db/migrate/add_display_type_to_answers.rb +14 -0
  124. data/lib/generators/surveyor/templates/db/migrate/add_index_to_response_sets.rb +10 -0
  125. data/lib/generators/surveyor/templates/db/migrate/add_index_to_surveys.rb +10 -0
  126. data/lib/generators/surveyor/templates/db/migrate/add_input_mask_attributes_to_answer.rb +12 -0
  127. data/lib/generators/surveyor/templates/db/migrate/add_section_id_to_responses.rb +12 -0
  128. data/lib/generators/surveyor/templates/db/migrate/add_unique_index_on_access_code_and_version_in_surveys.rb +10 -0
  129. data/lib/generators/surveyor/templates/db/migrate/add_unique_indicies.rb +18 -0
  130. data/lib/generators/surveyor/templates/db/migrate/add_version_to_surveys.rb +10 -0
  131. data/lib/generators/surveyor/templates/db/migrate/api_ids_must_be_unique.rb +23 -0
  132. data/lib/generators/surveyor/templates/db/migrate/create_answers.rb +38 -0
  133. data/lib/generators/surveyor/templates/db/migrate/create_dependencies.rb +23 -0
  134. data/lib/generators/surveyor/templates/db/migrate/create_dependency_conditions.rb +30 -0
  135. data/lib/generators/surveyor/templates/db/migrate/create_question_groups.rb +28 -0
  136. data/lib/generators/surveyor/templates/db/migrate/create_questions.rb +37 -0
  137. data/lib/generators/surveyor/templates/db/migrate/create_response_sets.rb +23 -0
  138. data/lib/generators/surveyor/templates/db/migrate/create_responses.rb +34 -0
  139. data/lib/generators/surveyor/templates/db/migrate/create_survey_sections.rb +30 -0
  140. data/lib/generators/surveyor/templates/db/migrate/create_survey_translations.rb +19 -0
  141. data/lib/generators/surveyor/templates/db/migrate/create_surveys.rb +32 -0
  142. data/lib/generators/surveyor/templates/db/migrate/create_validation_conditions.rb +33 -0
  143. data/lib/generators/surveyor/templates/db/migrate/create_validations.rb +21 -0
  144. data/lib/generators/surveyor/templates/db/migrate/drop_unique_index_on_access_code_in_surveys.rb +10 -0
  145. data/lib/generators/surveyor/templates/db/migrate/update_blank_api_ids_on_question_group.rb +22 -0
  146. data/lib/generators/surveyor/templates/db/migrate/update_blank_versions_on_surveys.rb +13 -0
  147. data/lib/generators/surveyor/templates/surveys/EXTENDING_SURVEYOR.md +52 -0
  148. data/lib/generators/surveyor/templates/surveys/MODIFYING_SURVEYOR.md +91 -0
  149. data/lib/generators/surveyor/templates/surveys/date_survey.rb +16 -0
  150. data/lib/generators/surveyor/templates/surveys/kitchen_sink_survey.rb +284 -0
  151. data/lib/generators/surveyor/templates/surveys/languages.rb +14 -0
  152. data/lib/generators/surveyor/templates/surveys/quiz.rb +11 -0
  153. data/lib/generators/surveyor/templates/surveys/translations/languages.es.yml +18 -0
  154. data/lib/generators/surveyor/templates/surveys/translations/languages.he.yml +18 -0
  155. data/lib/generators/surveyor/templates/surveys/translations/languages.ko.yml +18 -0
  156. data/lib/generators/surveyor/templates/vendor/assets/stylesheets/custom.sass +5 -0
  157. data/lib/surveyor/acts_as_response.rb +17 -0
  158. data/lib/surveyor/common.rb +59 -0
  159. data/lib/surveyor/engine.rb +10 -0
  160. data/lib/surveyor/helpers/asset_pipeline.rb +13 -0
  161. data/lib/surveyor/helpers/formtastic_custom_input.rb +13 -0
  162. data/lib/surveyor/helpers/surveyor_helper_methods.rb +103 -0
  163. data/lib/surveyor/models/answer_methods.rb +86 -0
  164. data/lib/surveyor/models/dependency_condition_methods.rb +72 -0
  165. data/lib/surveyor/models/dependency_methods.rb +60 -0
  166. data/lib/surveyor/models/question_group_methods.rb +61 -0
  167. data/lib/surveyor/models/question_methods.rb +115 -0
  168. data/lib/surveyor/models/response_methods.rb +132 -0
  169. data/lib/surveyor/models/response_set_methods.rb +196 -0
  170. data/lib/surveyor/models/survey_methods.rb +103 -0
  171. data/lib/surveyor/models/survey_section_methods.rb +56 -0
  172. data/lib/surveyor/models/survey_translation_methods.rb +33 -0
  173. data/lib/surveyor/models/validation_condition_methods.rb +56 -0
  174. data/lib/surveyor/models/validation_methods.rb +48 -0
  175. data/lib/surveyor/mustache_context.rb +11 -0
  176. data/lib/surveyor/parser.rb +428 -0
  177. data/lib/surveyor/redcap_parser.rb +289 -0
  178. data/lib/surveyor/surveyor_controller_methods.rb +237 -0
  179. data/lib/surveyor/unparser.rb +147 -0
  180. data/lib/surveyor/version.rb +3 -0
  181. data/lib/surveyor.rb +13 -0
  182. data/lib/tasks/surveyor_tasks.rake +88 -0
  183. data/rails/init.rb +1 -0
  184. data/spec/controllers/surveyor_controller_spec.rb +307 -0
  185. data/spec/factories.rb +161 -0
  186. data/spec/helpers/formtastic_custom_input_spec.rb +15 -0
  187. data/spec/helpers/surveyor_helper_spec.rb +118 -0
  188. data/spec/lib/benchmark_spec.rb +22 -0
  189. data/spec/lib/chinese_survey.rb +14 -0
  190. data/spec/lib/common_spec.rb +34 -0
  191. data/spec/lib/parser_spec.rb +204 -0
  192. data/spec/lib/rake_kitchen_sink.rb +40 -0
  193. data/spec/lib/redcap_parser_spec.rb +75 -0
  194. data/spec/lib/tasks_spec.rake +26 -0
  195. data/spec/lib/unparser_spec.rb +126 -0
  196. data/spec/models/answer_spec.rb +175 -0
  197. data/spec/models/dependency_condition_spec.rb +439 -0
  198. data/spec/models/dependency_spec.rb +101 -0
  199. data/spec/models/question_group_spec.rb +93 -0
  200. data/spec/models/question_spec.rb +207 -0
  201. data/spec/models/response_set_spec.rb +477 -0
  202. data/spec/models/response_spec.rb +218 -0
  203. data/spec/models/survey_section_spec.rb +85 -0
  204. data/spec/models/survey_spec.rb +191 -0
  205. data/spec/models/validation_condition_spec.rb +113 -0
  206. data/spec/models/validation_spec.rb +74 -0
  207. data/spec/rcov.opts +2 -0
  208. data/spec/spec.opts +4 -0
  209. data/spec/spec_helper.rb +56 -0
  210. data/stacktests.sh +65 -0
  211. data/surveyor.gemspec +45 -0
  212. metadata +657 -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
+