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.
Files changed (212) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +28 -0
  3. data/.rspec +1 -0
  4. data/CHANGELOG.md +198 -0
  5. data/Gemfile +5 -0
  6. data/Gemfile.rails_version +27 -0
  7. data/MIT-LICENSE +20 -0
  8. data/README.md +166 -0
  9. data/Rakefile +106 -0
  10. data/app/controllers/surveyor_controller.rb +5 -0
  11. data/app/helpers/results_helper.rb +20 -0
  12. data/app/helpers/survey_form_builder.rb +37 -0
  13. data/app/helpers/surveyor_helper.rb +3 -0
  14. data/app/inputs/quiet_input.rb +5 -0
  15. data/app/inputs/surveyor_check_boxes_input.rb +35 -0
  16. data/app/inputs/surveyor_radio_input.rb +18 -0
  17. data/app/models/answer.rb +3 -0
  18. data/app/models/dependency.rb +3 -0
  19. data/app/models/dependency_condition.rb +3 -0
  20. data/app/models/question.rb +3 -0
  21. data/app/models/question_group.rb +4 -0
  22. data/app/models/response.rb +4 -0
  23. data/app/models/response_set.rb +3 -0
  24. data/app/models/survey.rb +3 -0
  25. data/app/models/survey_section.rb +4 -0
  26. data/app/models/survey_section_sweeper.rb +15 -0
  27. data/app/models/survey_translation.rb +4 -0
  28. data/app/models/validation.rb +3 -0
  29. data/app/models/validation_condition.rb +3 -0
  30. data/app/views/layouts/results.html.erb +13 -0
  31. data/app/views/layouts/surveyor_default.html.erb +12 -0
  32. data/app/views/partials/_answer.html.haml +25 -0
  33. data/app/views/partials/_dependents.html.haml +5 -0
  34. data/app/views/partials/_question.html.haml +28 -0
  35. data/app/views/partials/_question_group.html.haml +44 -0
  36. data/app/views/partials/_section.html.haml +12 -0
  37. data/app/views/partials/_section_menu.html.haml +12 -0
  38. data/app/views/surveyor/edit.html.haml +24 -0
  39. data/app/views/surveyor/export.json.rabl +85 -0
  40. data/app/views/surveyor/new.html.haml +24 -0
  41. data/app/views/surveyor/show.html.haml +74 -0
  42. data/app/views/surveyor/show.json.rabl +15 -0
  43. data/ci-exec.sh +56 -0
  44. data/config/routes.rb +8 -0
  45. data/cucumber.yml +10 -0
  46. data/doc/REPRESENTATIONS.md +34 -0
  47. data/doc/api_id_schema.json +7 -0
  48. data/doc/question types.png +0 -0
  49. data/doc/response_set_schema.json +54 -0
  50. data/doc/surveyor question combinations.png +0 -0
  51. data/doc/surveyor reject or delete decision matrix.png +0 -0
  52. data/doc/surveyor_models.png +0 -0
  53. data/doc/surveyor_models2.png +0 -0
  54. data/doc/surveyor_timestamp_schema.json +9 -0
  55. data/features/ajax_submissions.feature +140 -0
  56. data/features/export_to_json.feature +344 -0
  57. data/features/internationalization.feature +121 -0
  58. data/features/no_duplicates.feature +110 -0
  59. data/features/show_survey.feature +71 -0
  60. data/features/step_definitions/parser_steps.rb +145 -0
  61. data/features/step_definitions/surveyor_steps.rb +325 -0
  62. data/features/step_definitions/ui_steps.rb +25 -0
  63. data/features/step_definitions/web_steps.rb +225 -0
  64. data/features/support/REDCapDemoDatabase_DataDictionary.csv +127 -0
  65. data/features/support/database_cleaner.rb +16 -0
  66. data/features/support/env.rb +56 -0
  67. data/features/support/hooks.rb +4 -0
  68. data/features/support/paths.rb +39 -0
  69. data/features/support/redcap_new_headers.csv +1 -0
  70. data/features/support/redcap_siblings.csv +1 -0
  71. data/features/support/redcap_whitespace.csv +1 -0
  72. data/features/support/selectors.rb +39 -0
  73. data/features/support/simultaneous_ajax.rb +101 -0
  74. data/features/support/single_quit_selenium_driver.rb +23 -0
  75. data/features/support/slow_updates.rb +18 -0
  76. data/features/surveyor.feature +895 -0
  77. data/features/surveyor_dependencies.feature +476 -0
  78. data/features/surveyor_parser.feature +504 -0
  79. data/features/z_redcap_parser.feature +62 -0
  80. data/lib/assets/images/surveyor/next.gif +0 -0
  81. data/lib/assets/images/surveyor/prev.gif +0 -0
  82. data/lib/assets/images/surveyor/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  83. data/lib/assets/images/surveyor/ui-bg_flat_75_ffffff_40x100.png +0 -0
  84. data/lib/assets/images/surveyor/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  85. data/lib/assets/images/surveyor/ui-bg_glass_65_ffffff_1x400.png +0 -0
  86. data/lib/assets/images/surveyor/ui-bg_glass_75_dadada_1x400.png +0 -0
  87. data/lib/assets/images/surveyor/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  88. data/lib/assets/images/surveyor/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  89. data/lib/assets/images/surveyor/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  90. data/lib/assets/images/surveyor/ui-icons_222222_256x240.png +0 -0
  91. data/lib/assets/images/surveyor/ui-icons_2e83ff_256x240.png +0 -0
  92. data/lib/assets/images/surveyor/ui-icons_454545_256x240.png +0 -0
  93. data/lib/assets/images/surveyor/ui-icons_888888_256x240.png +0 -0
  94. data/lib/assets/images/surveyor/ui-icons_cd0a0a_256x240.png +0 -0
  95. data/lib/assets/javascripts/surveyor/jquery-1.9.0.js +9555 -0
  96. data/lib/assets/javascripts/surveyor/jquery-ui-1.10.0.custom.js +14850 -0
  97. data/lib/assets/javascripts/surveyor/jquery-ui-timepicker-addon.js +1919 -0
  98. data/lib/assets/javascripts/surveyor/jquery.maskedinput.js +338 -0
  99. data/lib/assets/javascripts/surveyor/jquery.selectToUISlider.js +240 -0
  100. data/lib/assets/javascripts/surveyor/jquery.surveyor.js +154 -0
  101. data/lib/assets/stylesheets/surveyor.sass +132 -0
  102. data/lib/assets/stylesheets/surveyor/jquery-ui-1.10.0.custom.css +1174 -0
  103. data/lib/assets/stylesheets/surveyor/jquery-ui-timepicker-addon.css +11 -0
  104. data/lib/assets/stylesheets/surveyor/reset.css +48 -0
  105. data/lib/assets/stylesheets/surveyor/results.css +125 -0
  106. data/lib/assets/stylesheets/surveyor/ui.slider.extras.css +110 -0
  107. data/lib/generators/surveyor/custom_generator.rb +18 -0
  108. data/lib/generators/surveyor/install_generator.rb +101 -0
  109. data/lib/generators/surveyor/templates/app/assets/javascripts/surveyor_all.js +6 -0
  110. data/lib/generators/surveyor/templates/app/assets/stylesheets/surveyor_all.css +9 -0
  111. data/lib/generators/surveyor/templates/app/controllers/surveyor_controller.rb +40 -0
  112. data/lib/generators/surveyor/templates/app/views/layouts/surveyor_custom.html.erb +13 -0
  113. data/lib/generators/surveyor/templates/config/locales/surveyor_en.yml +19 -0
  114. data/lib/generators/surveyor/templates/config/locales/surveyor_es.yml +19 -0
  115. data/lib/generators/surveyor/templates/config/locales/surveyor_he.yml +19 -0
  116. data/lib/generators/surveyor/templates/config/locales/surveyor_ko.yml +19 -0
  117. data/lib/generators/surveyor/templates/db/migrate/add_api_id_to_question_groups.rb +10 -0
  118. data/lib/generators/surveyor/templates/db/migrate/add_api_ids.rb +14 -0
  119. data/lib/generators/surveyor/templates/db/migrate/add_api_ids_to_response_sets_and_responses.rb +12 -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 +280 -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.rb +13 -0
  158. data/lib/surveyor/acts_as_response.rb +17 -0
  159. data/lib/surveyor/common.rb +59 -0
  160. data/lib/surveyor/engine.rb +10 -0
  161. data/lib/surveyor/helpers/asset_pipeline.rb +18 -0
  162. data/lib/surveyor/helpers/formtastic_custom_input.rb +13 -0
  163. data/lib/surveyor/helpers/surveyor_helper_methods.rb +103 -0
  164. data/lib/surveyor/models/answer_methods.rb +83 -0
  165. data/lib/surveyor/models/dependency_condition_methods.rb +69 -0
  166. data/lib/surveyor/models/dependency_methods.rb +57 -0
  167. data/lib/surveyor/models/question_group_methods.rb +58 -0
  168. data/lib/surveyor/models/question_methods.rb +112 -0
  169. data/lib/surveyor/models/response_methods.rb +126 -0
  170. data/lib/surveyor/models/response_set_methods.rb +188 -0
  171. data/lib/surveyor/models/survey_methods.rb +100 -0
  172. data/lib/surveyor/models/survey_section_methods.rb +53 -0
  173. data/lib/surveyor/models/survey_translation_methods.rb +30 -0
  174. data/lib/surveyor/models/validation_condition_methods.rb +54 -0
  175. data/lib/surveyor/models/validation_methods.rb +45 -0
  176. data/lib/surveyor/mustache_context.rb +11 -0
  177. data/lib/surveyor/parser.rb +427 -0
  178. data/lib/surveyor/redcap_parser.rb +288 -0
  179. data/lib/surveyor/surveyor_controller_methods.rb +236 -0
  180. data/lib/surveyor/unparser.rb +147 -0
  181. data/lib/surveyor/version.rb +3 -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 +311 -0
  185. data/spec/factories.rb +166 -0
  186. data/spec/helpers/formtastic_custom_input_spec.rb +15 -0
  187. data/spec/helpers/surveyor_helper_spec.rb +117 -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 +174 -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 +206 -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 +53 -0
  212. metadata +601 -0
@@ -0,0 +1,23 @@
1
+ # encoding: UTF-8
2
+ class CreateResponseSets < ActiveRecord::Migration
3
+ def self.up
4
+ create_table :response_sets do |t|
5
+ # Context
6
+ t.integer :user_id
7
+ t.integer :survey_id
8
+
9
+ # Content
10
+ t.string :access_code #unique id for the object used in urls
11
+
12
+ # Expiry
13
+ t.datetime :started_at
14
+ t.datetime :completed_at
15
+
16
+ t.timestamps
17
+ end
18
+ end
19
+
20
+ def self.down
21
+ drop_table :response_sets
22
+ end
23
+ end
@@ -0,0 +1,34 @@
1
+ # encoding: UTF-8
2
+ class CreateResponses < ActiveRecord::Migration
3
+ def self.up
4
+ create_table :responses do |t|
5
+ # Context
6
+ t.integer :response_set_id
7
+ t.integer :question_id
8
+
9
+ # Content
10
+ t.integer :answer_id
11
+ t.datetime :datetime_value # handles date, time, and datetime (segregate by answer.response_class)
12
+
13
+ #t.datetime :time_value
14
+ t.integer :integer_value
15
+ t.float :float_value
16
+ t.string :unit
17
+ t.text :text_value
18
+ t.string :string_value
19
+ t.string :response_other #used to hold the string entered with "Other" type answers in multiple choice questions
20
+
21
+ # arbitrary identifier used to group responses
22
+ # the pertinent example here is Q: What's your car's make/model/year
23
+ # group 1: Ford/Focus/2007
24
+ # group 2: Toyota/Prius/2006
25
+ t.string :response_group
26
+
27
+ t.timestamps
28
+ end
29
+ end
30
+
31
+ def self.down
32
+ drop_table :responses
33
+ end
34
+ end
@@ -0,0 +1,30 @@
1
+ # encoding: UTF-8
2
+ class CreateSurveySections < ActiveRecord::Migration
3
+ def self.up
4
+ create_table :survey_sections do |t|
5
+ # Context
6
+ t.integer :survey_id
7
+
8
+ # Content
9
+ t.string :title
10
+ t.text :description
11
+
12
+ # Reference
13
+ t.string :reference_identifier # from paper
14
+ t.string :data_export_identifier # data export
15
+ t.string :common_namespace # maping to a common vocab
16
+ t.string :common_identifier # maping to a common vocab
17
+
18
+ # Display
19
+ t.integer :display_order
20
+
21
+ t.string :custom_class
22
+
23
+ t.timestamps
24
+ end
25
+ end
26
+
27
+ def self.down
28
+ drop_table :survey_sections
29
+ end
30
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: UTF-8
2
+ class CreateSurveyTranslations < ActiveRecord::Migration
3
+ def self.up
4
+ create_table :survey_translations do |t|
5
+ # Content
6
+ t.integer :survey_id
7
+
8
+ # Reference
9
+ t.string :locale
10
+ t.text :translation
11
+
12
+ t.timestamps
13
+ end
14
+ end
15
+
16
+ def self.down
17
+ drop_table :survey_translations
18
+ end
19
+ end
@@ -0,0 +1,32 @@
1
+ # encoding: UTF-8
2
+ class CreateSurveys < ActiveRecord::Migration
3
+ def self.up
4
+ create_table :surveys do |t|
5
+ # Content
6
+ t.string :title
7
+ t.text :description
8
+
9
+ # Reference
10
+ t.string :access_code
11
+ t.string :reference_identifier # from paper
12
+ t.string :data_export_identifier # data export
13
+ t.string :common_namespace # maping to a common vocab
14
+ t.string :common_identifier # maping to a common vocab
15
+
16
+ # Expiry
17
+ t.datetime :active_at
18
+ t.datetime :inactive_at
19
+
20
+ # Display
21
+ t.string :css_url
22
+
23
+ t.string :custom_class
24
+
25
+ t.timestamps
26
+ end
27
+ end
28
+
29
+ def self.down
30
+ drop_table :surveys
31
+ end
32
+ end
@@ -0,0 +1,33 @@
1
+ # encoding: UTF-8
2
+ class CreateValidationConditions < ActiveRecord::Migration
3
+ def self.up
4
+ create_table :validation_conditions do |t|
5
+ # Context
6
+ t.integer :validation_id
7
+ t.string :rule_key
8
+
9
+ # Conditional
10
+ t.string :operator
11
+
12
+ # Optional external reference
13
+ t.integer :question_id
14
+ t.integer :answer_id
15
+
16
+ # Value
17
+ t.datetime :datetime_value
18
+ t.integer :integer_value
19
+ t.float :float_value
20
+ t.string :unit
21
+ t.text :text_value
22
+ t.string :string_value
23
+ t.string :response_other
24
+ t.string :regexp
25
+
26
+ t.timestamps
27
+ end
28
+ end
29
+
30
+ def self.down
31
+ drop_table :validation_conditions
32
+ end
33
+ end
@@ -0,0 +1,21 @@
1
+ # encoding: UTF-8
2
+ class CreateValidations < ActiveRecord::Migration
3
+ def self.up
4
+ create_table :validations do |t|
5
+ # Context
6
+ t.integer :answer_id # the answer to validate
7
+
8
+ # Conditional
9
+ t.string :rule
10
+
11
+ # Message
12
+ t.string :message
13
+
14
+ t.timestamps
15
+ end
16
+ end
17
+
18
+ def self.down
19
+ drop_table :validations
20
+ end
21
+ end
@@ -0,0 +1,10 @@
1
+ # encoding: UTF-8
2
+ class DropUniqueIndexOnAccessCodeInSurveys < ActiveRecord::Migration
3
+ def self.up
4
+ remove_index( :surveys, :name => 'surveys_ac_idx' )
5
+ end
6
+
7
+ def self.down
8
+ add_index(:surveys, :access_code, :name => 'surveys_ac_idx')
9
+ end
10
+ end
@@ -0,0 +1,22 @@
1
+ # encoding: UTF-8
2
+ class Survey < ActiveRecord::Base; end
3
+ class Question < ActiveRecord::Base; end
4
+ class QuestionGroup < ActiveRecord::Base; end
5
+ class Answer < ActiveRecord::Base; end
6
+ class Response < ActiveRecord::Base; end
7
+ class ResponseSet < ActiveRecord::Base; end
8
+
9
+ class UpdateBlankApiIdsOnQuestionGroup < ActiveRecord::Migration
10
+ def self.up
11
+ check = [Survey, Question, QuestionGroup, Answer, Response, ResponseSet]
12
+ check.each do |clazz|
13
+ clazz.where('api_id IS ?', nil).each do |c|
14
+ c.api_id = Surveyor::Common.generate_api_id
15
+ c.save!
16
+ end
17
+ end
18
+ end
19
+
20
+ def self.down
21
+ end
22
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: UTF-8
2
+ class Survey < ActiveRecord::Base; end
3
+ class UpdateBlankVersionsOnSurveys < ActiveRecord::Migration
4
+ def self.up
5
+ Survey.where('survey_version IS ?', nil).each do |s|
6
+ s.survey_version = 0
7
+ s.save!
8
+ end
9
+ end
10
+
11
+ def self.down
12
+ end
13
+ end
@@ -0,0 +1,52 @@
1
+ == SurveyorController
2
+
3
+ The SurveyorController class just includes actions from Surveyor::SurveyorControllerMethods module. You may include your own module, and overwrite the methods or add to them using "super". A template for this customization is in your app/controllers/surveyor\_controller.rb. SurveyorController is "unloadable", so changes in development (and any environment that does not cache classes) will be reflected immediately without restarting the app.
4
+
5
+ == Models
6
+
7
+ Surveyor's models can all be customized:
8
+
9
+ - answer
10
+ - dependency_condition
11
+ - dependency
12
+ - question_group
13
+ - question
14
+ - response_set
15
+ - response
16
+ - survey_section
17
+ - survey
18
+ - validation_condition
19
+ - validation
20
+
21
+ For example, create app/models/survey.rb with the following contents:
22
+
23
+ class Survey < ActiveRecord::Base
24
+ include Surveyor::Models::SurveyMethods
25
+ def title
26
+ "Custom #{super}"
27
+ end
28
+ end
29
+
30
+ == SurveyorHelper
31
+
32
+ The SurveyorHelper module can be customized just like the models:
33
+
34
+ module SurveyorHelper
35
+ include Surveyor::Helpers::SurveyorHelperMethods
36
+ def rc_to_as(type_sym)
37
+ case type_sym.to_s
38
+ when /(integer|float)/ then :string
39
+ when /(datetime)/ then :string
40
+ when /^date$/ then :string
41
+ else type_sym
42
+ end
43
+ end
44
+ end
45
+
46
+ == Views
47
+
48
+ Surveyor's views can be overwritten by simply creating views in app/views/surveyor
49
+
50
+ == Layout
51
+
52
+ Create a custom SurveyorController as above, and specify your custom layout in it.
@@ -0,0 +1,91 @@
1
+ == Dates, Times, and Javascript Date Picker
2
+
3
+ == Default JQuery Date Picker
4
+
5
+ By default Surveyor uses the JQuery-UI date picker (http://jqueryui.com/demos/datepicker/)
6
+ for all date and time fields (denoted by :date, :time, or :datetime for the answer in the survey).
7
+
8
+ == Using Rails Date Helpers
9
+
10
+ It is possible (and relatively easy) to use the default Rails
11
+ date helpers (http://api.rubyonrails.org/classes/ActionView/Helpers/DateHelper.html)
12
+ instead of the javascript date picker.
13
+
14
+ To do so you would need to override two methods in the SurveyorHelperMethods. Currently the
15
+ rc_to_attr and rc_to_as handle how the form fields are displayed. The formtastic input method
16
+ (https://github.com/justinfrench/formtastic) used in the _answer.html.haml partial
17
+ calls the rc_to_attr method to get the attribute for the answer object
18
+ and then calls the rc_to_as method to get the value to set the :as parameter.
19
+
20
+ ff.input rc_to_attr(a.response_class), :as => rc_to_as(a.response_class)
21
+
22
+ def rc_to_attr(type_sym)
23
+ case type_sym.to_s
24
+ when /^answer$/ then :answer_id
25
+ else "#{type_sym.to_s}_value".to_sym
26
+ end
27
+ end
28
+
29
+ def rc_to_as(type_sym)
30
+ case type_sym.to_s
31
+ when /(integer|float|date|time|datetime)/ then :string
32
+ else type_sym
33
+ end
34
+ end
35
+
36
+ First, we would need to set that the attribute to be used is the :datetime_value attribute on the
37
+ answer. (By default we use the custom date_value and time_value methods which wrap the :datetime_value
38
+ on the answer to work with the string representation of those values). To do this we would need to
39
+ change the rc_to_attr method so that either the date or time types return the :datetime_value attribute
40
+
41
+ def rc_to_attr(type_sym)
42
+ case type_sym.to_s
43
+ when /^date|time$/ then :datetime_value
44
+ when /^(string|text|integer|float|datetime)$/ then "#{type_sym.to_s}_value".to_sym
45
+ else :answer_id
46
+ end
47
+ end
48
+
49
+
50
+ Second, we would need to update the rc_to_as method so that the date, time, and/or datetime
51
+ answer types would return those values rather than string as they do by default
52
+
53
+ def rc_to_as(type_sym)
54
+ case type_sym.to_s
55
+ when /(integer|float)/ then :string
56
+ else type_sym
57
+ end
58
+ end
59
+
60
+ Of course, you could mix and match which attribute types could be show with the Rails Date Helper
61
+ methods and which ones could use the javascript date picker.
62
+
63
+ == JQuery Tools Date Input
64
+
65
+ If you would like to use JQuery Tools dateinput instead (http://jquerytools.org/demos/dateinput/index.html)
66
+ you would need to edit the
67
+ vendor/assets/javascripts/surveyor/jquery.surveyor.js file.
68
+
69
+ Replace the jquery-ui datepicker lines:
70
+
71
+ jQuery("input[type='text'].date").datepicker({
72
+ dateFormat: 'yy-mm-dd',
73
+ changeMonth: true,
74
+ changeYear: true
75
+ });
76
+
77
+ with those for the jquery tools dateinput
78
+
79
+ jQuery('li input.date').dateinput({
80
+ format: 'dd mmm yyyy'
81
+ });
82
+
83
+ (note that you may need to add the following to make the jquery tools dateinput widget to work properly)
84
+
85
+ jQuery('li.date input').change(function(){
86
+ if ( $(this).data('dateinput') ) {
87
+ var date_obj = $(this).data('dateinput').getValue();
88
+ this.value = date_obj.getFullYear() + "-" + (date_obj.getMonth()+1) + "-" +
89
+ date_obj.getDate() + " 00:00:00 UTC";
90
+ }
91
+ });
@@ -0,0 +1,16 @@
1
+ # encoding: UTF-8
2
+ survey "Date Survey" do
3
+
4
+ section "Simple date questions" do
5
+
6
+ q "What is your birth date?"
7
+ a :date
8
+
9
+ q "At what time were you born?"
10
+ a :time
11
+
12
+ q "When would you like to schedule your next appointment?"
13
+ a :datetime
14
+
15
+ end
16
+ end
@@ -0,0 +1,280 @@
1
+ # encoding: UTF-8
2
+ # Question#is_mandatory is now false by default. The default_mandatory option allows you to set
3
+ # is_mandatory for all questions in a survey.
4
+ survey "Kitchen Sink survey", :default_mandatory => false do
5
+
6
+ section "Basic questions" do
7
+ # A label is a question that accepts no answers
8
+ label "These questions are examples of the basic supported input types"
9
+
10
+ # A basic question with radio buttons
11
+ question "What is your favorite color?", :pick => :one
12
+ answer "red"
13
+ answer "blue"
14
+ answer "green"
15
+ answer "yellow"
16
+ answer :other
17
+
18
+ # A basic question with checkboxes
19
+ # The "question" and "answer" methods may be abbreviated as "q" and "a".
20
+ # Append a reference identifier (a short string used for dependencies and validations) using the "_" underscore.
21
+ # Question reference identifiers must be unique within a survey.
22
+ # Answer reference identifiers must be unique within a question
23
+ q_2 "Choose the colors you don't like", :pick => :any
24
+ a_1 "red"
25
+ a_2 "blue"
26
+ a_3 "green"
27
+ a_4 "yellow"
28
+ a :omit
29
+
30
+ # A dependent question, with conditions and rule to logically join them
31
+ # If the conditions, logically joined into the rule, are met, then the question will be shown.
32
+ q_2a "Please explain why you don't like this color?"
33
+ a_1 "explanation", :text, :help_text => "Please give an explanation for each color you don't like"
34
+ dependency :rule => "A or B or C or D"
35
+ condition_A :q_2, "==", :a_1
36
+ condition_B :q_2, "==", :a_2
37
+ condition_C :q_2, "==", :a_3
38
+ condition_D :q_2, "==", :a_4
39
+
40
+ # The count operator checks how many responses exist for the referenced question.
41
+ # It understands conditions of the form: count== count!= count> count< count>= count<=
42
+ q_2b "Please explain why you dislike so many colors?"
43
+ a_1 "explanation", :text
44
+ dependency :rule => "Z"
45
+ condition_Z :q_2, "count>2"
46
+
47
+ # When :pick isn't specified, the default is :none (no checkbox or radio button)
48
+ q_montypython3 "What... is your name? (e.g. It is 'Arthur', King of the Britons)"
49
+ a_1 :string
50
+
51
+ # Dependency conditions can refer to any value, not just answer_id. An answer_reference still needs to be specified, to know which answer you would like to check
52
+ q_montypython4 "What... is your quest? (e.g. To seek the Holy Grail)"
53
+ a_1 :string
54
+ dependency :rule => "A"
55
+ condition_A :q_montypython3, "==", {:string_value => "It is 'Arthur', King of the Britons", :answer_reference => "1"}
56
+
57
+ # http://www.imdb.com/title/tt0071853/quotes
58
+ q_montypython5 "What... is the air-speed velocity of an unladen swallow? (e.g. What do you mean? An African or European swallow?)"
59
+ a_1 :string
60
+ dependency :rule => "A"
61
+ condition_A :q_montypython4, "==", {:string_value => "To seek the Holy Grail", :answer_reference => "1"}
62
+
63
+ label "Huh? I-- I don't know that! Auuuuuuuugh!"
64
+ dependency :rule => "A"
65
+ condition_A :q_montypython5, "==", {:string_value => "What do you mean? An African or European swallow?", :answer_reference => "1"}
66
+
67
+ q_cooling_1 "How do you cool your home?", :pick => :one
68
+ a_1 "Fans"
69
+ a_2 "Window AC"
70
+ a_3 "Central AC"
71
+ a_4 "Passive"
72
+
73
+ # When using !=, also use count>0 if you want to make sure the user responds
74
+ q_cooling_2 "How much does it cost to run your non-passive cooling solutions? (This question hidden until you respond 'How do you cool your home?')"
75
+ dependency :rule => "A and B"
76
+ condition_A :q_cooling_1, "!=", :a_4
77
+ condition_B :q_cooling_1, "count>0"
78
+ a_1 "$", :float
79
+
80
+ # Using != alone means the dependent question is shown by default
81
+ label "Please consider passive cooling solutions (This question always shown, unless you respond 'Passive')"
82
+ dependency :rule => "A"
83
+ condition_A :q_cooling_1, "!=", :a_4
84
+
85
+ # Surveys, sections, questions, groups, and answers all take the following reference arguments
86
+ # :reference_identifier # used for parsing references, usually derived from the paper version
87
+ # :data_export_identifier # used for data export
88
+ # :common_namespace # maping to a common vocabulary - the namespace
89
+ # :common_identifier # maping to a common vocabulary - the identifier within the namespace
90
+ q "Get me started on an improv sketch", :reference_identifier => "improv_start", :data_export_identifier => "i_s", :common_namespace => "sketch comedy questions", :common_identifier => "get me started"
91
+ a "who", :string
92
+ a "what", :string
93
+ a "where", :string
94
+
95
+ # Various types of responses can be accepted, and validated
96
+ q "How many pets do you own?"
97
+ a :integer
98
+ validation :rule => "A"
99
+ condition_A ">=", :integer_value => 0
100
+
101
+ # Surveys, sections, questions, groups, and answers also take a custom css class for covenience in custom styling
102
+ q "What is your address?", :custom_class => 'address'
103
+ a :text, :custom_class => 'mapper'
104
+ # validations can use regexp values
105
+ validation :rule => "A"
106
+ condition_A "=~", :regexp => "[0-9a-zA-z\. #]"
107
+
108
+ # Questions, groups, and answers take a custom renderer (a partial in the application's views dir)
109
+ # defaults are "/partials/question_group", "/partials/question", "/partials/answer", so the custom renderers should have a different name
110
+ q "Pick your favorite date AND time" #, :custom_renderer => "/partials/custom_question"
111
+ a :datetime
112
+
113
+ q_time_lunch "What time do you usually take a lunch break?"
114
+ a_1 :time
115
+
116
+ q "When would you like to meet for dinner?"
117
+ a :date
118
+
119
+ # Sliders deprecate to select boxes when javascript is off
120
+ # Valid Ruby code may be used to shorten repetitive tasks
121
+ q "Adjust the slider to reflect your level of awesomeness", :pick => :one, :display_type => :slider
122
+ (1..10).to_a.each{|num| a num.to_s}
123
+
124
+ q "How much do you like Ruby?", :pick => :one, :display_type => :slider
125
+ ["not at all", "a little", "some", "a lot", "a ton"].each{|level| a level}
126
+
127
+ # The "|" pipe is used to place labels before or after the input elements
128
+ q "How much money do you want?"
129
+ a "$|USD", :float
130
+
131
+ # Questions may be grouped
132
+ group "How much oil do you use per day?", :display_type => :inline do
133
+ q "Quantity"
134
+ a :float
135
+
136
+ q "Unit", :pick => :one, :display_type => :dropdown
137
+ a "Barrels"
138
+ a "Gallons"
139
+ a "Quarts"
140
+ end
141
+
142
+ q "Choose your Illinois county", :pick => :one, :display_type => :dropdown
143
+ ["Adams","Alexander","Bond", "Boone",
144
+ "Brown","Bureau","Calhoun","Carroll","Cass",
145
+ "Champaign", "Christian", "Clark","Clay",
146
+ "Clinton", "Coles", "Cook", "Crawford","Cumberland","DeKalb",
147
+ "De Witt","Douglas","DuPage","Edgar", "Edwards",
148
+ "Effingham","Fayette", "Ford","Franklin","Fulton",
149
+ "Gallatin","Greene", "Grundy", "Hamilton","Hancock",
150
+ "Hardin","Henderson","Henry","Iroquois","Jackson",
151
+ "Jasper", "Jefferson","Jersey","Jo Daviess","Johnson",
152
+ "Kane","Kankakee","Kendall","Knox", "La Salle",
153
+ "Lake", "Lawrence", "Lee","Livingston","Logan",
154
+ "Macon","Macoupin","Madison","Marion","Marshall", "Mason",
155
+ "Massac","McDonough","McHenry","McLean","Menard",
156
+ "Mercer","Monroe", "Montgomery","Morgan","Moultrie",
157
+ "Ogle","Peoria","Perry","Piatt","Pike","Pope",
158
+ "Pulaski","Putnam","Randolph","Richland","Rock Island",
159
+ "Saline","Sangamon","Schuyler","Scott","Shelby",
160
+ "St. Clair","Stark", "Stephenson","Tazewell","Union",
161
+ "Vermilion","Wabash","Warren","Washington","Wayne",
162
+ "White","Whiteside","Will","Williamson","Winnebago","Woodford"].each{ |county| a county}
163
+
164
+ # When an is_exclusive answer is checked, it unchecks all other options and disables them (using Javascript)
165
+ q "Choose your favorite meats", :display_type => :inline, :pick => :any
166
+ a "Chicken"
167
+ a "Pork"
168
+ a "Beef"
169
+ a "Shellfish"
170
+ a "Fish"
171
+ a "I don't eat meats!!!", :is_exclusive => true
172
+
173
+ q "All out of ideas for questions?", :pick => :one, :display_type => :inline
174
+ a "yes"
175
+ a "maybe"
176
+ a "no"
177
+ a "I don't know"
178
+
179
+ # Questions may also have input masks with fancy placeholders
180
+ q "What is your phone number?"
181
+ a :string, :input_mask => '(999)999-9999', :input_mask_placeholder => '#'
182
+
183
+ end
184
+
185
+ section "Complicated questions" do
186
+
187
+ # Grids are useful for repeated questions with the same set of answers, which are specified before the questions
188
+ grid "Tell us how often do you cover these each day" do
189
+ a "1"
190
+ a "2"
191
+ a "3"
192
+ q "Head", :pick => :one
193
+ q "Knees", :pick => :one
194
+ q "Toes", :pick => :one
195
+ end
196
+
197
+ # "grid" is a shortcut for group with :display_type => :grid
198
+ # The answers will be repeated every 10 rows, but long grids aren't recommended as they are generally tedious
199
+ grid "Tell us how you feel today day" do
200
+ a "-2"
201
+ a "-1"
202
+ a "0"
203
+ a "1"
204
+ a "2"
205
+ q "down|up" , :pick => :one
206
+ q "sad|happy", :pick => :one
207
+ q "limp|perky", :pick => :one
208
+ end
209
+
210
+ grid "For each of the car types checked, what type of options would you prefer?" do
211
+ a "Leather seats"
212
+ a "Shiny rims"
213
+ a "Subwoofer"
214
+ a "Sunroof"
215
+ a "Turbocharger"
216
+ q "SUV", :pick => :any
217
+ q "Sedan", :pick => :any
218
+ q "Coupe", :pick => :any
219
+ q "Convertible", :pick => :any
220
+ q "Minivan", :pick => :any
221
+ q "Crossover", :pick => :any
222
+ q "Wagon", :pick => :any
223
+ q "Other", :pick => :any
224
+ end
225
+
226
+ q "Please rank the following foods based on how much you like them"
227
+ a "|pizza", :integer
228
+ a "|salad", :integer
229
+ a "|sushi", :integer
230
+ a "|ice cream", :integer
231
+ a "|breakfast ceral", :integer
232
+
233
+ # :other, :string allows someone to specify both the "other" and some other information
234
+ q "Choose your favorite utensils and enter frequency of use (daily, weekly, monthly, etc...)", :pick => :any
235
+ a "spoon", :string
236
+ a "fork", :string
237
+ a "knife", :string
238
+ a :other, :string
239
+
240
+ q "What is your birth date?", :pick => :one
241
+ a "I was born on", :date
242
+ a "Refused"
243
+
244
+ q "At what time were you born?", :pick => :any
245
+ a "I was born at", :time
246
+ a "This time is approximate"
247
+
248
+ q "When would you like to schedule your next appointment?"
249
+ a :datetime
250
+
251
+ q_car "Do you own a car?", :pick => :one
252
+ a_y "Yes"
253
+ a_n "No"
254
+
255
+ # Repeaters allow multiple responses to a question or set of questions
256
+ repeater "Tell us about the cars you own" do
257
+ dependency :rule => "A"
258
+ condition_A :q_car, "==", :a_y
259
+ q "Make", :pick => :one, :display_type => :dropdown
260
+ a "Toyota"
261
+ a "Ford"
262
+ a "GMChevy"
263
+ a "Ferrari"
264
+ a "Tesla"
265
+ a "Honda"
266
+ a "Other weak brand"
267
+ q "Model"
268
+ a :string
269
+ q "Year"
270
+ a :string
271
+ end
272
+
273
+ repeater "Tell us the name and age of your siblings" do
274
+ q "Sibling"
275
+ a "Name", :string
276
+ a "Age|years", :integer
277
+ end
278
+
279
+ end
280
+ end