jakewendt-surveyor 0.11.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (160) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +285 -0
  3. data/Rakefile +54 -0
  4. data/VERSION +1 -0
  5. data/app/controllers/surveyor_controller.rb +142 -0
  6. data/app/helpers/survey_form_builder.rb +37 -0
  7. data/app/helpers/surveyor_helper.rb +67 -0
  8. data/app/models/answer.rb +23 -0
  9. data/app/models/dependency.rb +50 -0
  10. data/app/models/dependency_condition.rb +47 -0
  11. data/app/models/question.rb +54 -0
  12. data/app/models/question_group.rb +33 -0
  13. data/app/models/response.rb +94 -0
  14. data/app/models/response_set.rb +316 -0
  15. data/app/models/survey.rb +172 -0
  16. data/app/models/survey_section.rb +18 -0
  17. data/app/models/validation.rb +38 -0
  18. data/app/models/validation_condition.rb +47 -0
  19. data/app/views/layouts/surveyor_default.html.erb +13 -0
  20. data/app/views/partials/_answer.html.haml +58 -0
  21. data/app/views/partials/_question.html.haml +80 -0
  22. data/app/views/partials/_question_group.html.haml +39 -0
  23. data/app/views/surveyor/edit.html.haml +38 -0
  24. data/app/views/surveyor/new.html.haml +16 -0
  25. data/app/views/surveyor/show.html.haml +12 -0
  26. data/config/routes.rb +11 -0
  27. data/features/step_definitions/surveyor_steps.rb +7 -0
  28. data/features/step_definitions/web_steps.rb +273 -0
  29. data/features/support/env.rb +57 -0
  30. data/features/support/paths.rb +25 -0
  31. data/features/surveyor.feature +11 -0
  32. data/generators/extend_surveyor/extend_surveyor_generator.rb +22 -0
  33. data/generators/extend_surveyor/templates/EXTENDING_SURVEYOR +17 -0
  34. data/generators/extend_surveyor/templates/extensions/survey_extensions.rb +24 -0
  35. data/generators/extend_surveyor/templates/extensions/surveyor_controller_extensions.rb +28 -0
  36. data/generators/extend_surveyor/templates/extensions/surveyor_custom.html.erb +13 -0
  37. data/generators/extend_surveyor/templates/extensions/surveyor_helper_extensions.rb +17 -0
  38. data/generators/surveyor/surveyor_generator.rb +67 -0
  39. data/generators/surveyor/templates/README +10 -0
  40. data/generators/surveyor/templates/assets/images/222222_11x11_icon_arrows_leftright.gif +0 -0
  41. data/generators/surveyor/templates/assets/images/222222_11x11_icon_arrows_updown.gif +0 -0
  42. data/generators/surveyor/templates/assets/images/222222_11x11_icon_close.gif +0 -0
  43. data/generators/surveyor/templates/assets/images/222222_11x11_icon_doc.gif +0 -0
  44. data/generators/surveyor/templates/assets/images/222222_11x11_icon_folder_closed.gif +0 -0
  45. data/generators/surveyor/templates/assets/images/222222_11x11_icon_folder_open.gif +0 -0
  46. data/generators/surveyor/templates/assets/images/222222_11x11_icon_minus.gif +0 -0
  47. data/generators/surveyor/templates/assets/images/222222_11x11_icon_plus.gif +0 -0
  48. data/generators/surveyor/templates/assets/images/222222_11x11_icon_resize_se.gif +0 -0
  49. data/generators/surveyor/templates/assets/images/222222_35x9_colorpicker_indicator.gif.gif +0 -0
  50. data/generators/surveyor/templates/assets/images/222222_7x7_arrow_down.gif +0 -0
  51. data/generators/surveyor/templates/assets/images/222222_7x7_arrow_left.gif +0 -0
  52. data/generators/surveyor/templates/assets/images/222222_7x7_arrow_right.gif +0 -0
  53. data/generators/surveyor/templates/assets/images/222222_7x7_arrow_up.gif +0 -0
  54. data/generators/surveyor/templates/assets/images/454545_11x11_icon_arrows_leftright.gif +0 -0
  55. data/generators/surveyor/templates/assets/images/454545_11x11_icon_arrows_updown.gif +0 -0
  56. data/generators/surveyor/templates/assets/images/454545_11x11_icon_close.gif +0 -0
  57. data/generators/surveyor/templates/assets/images/454545_11x11_icon_doc.gif +0 -0
  58. data/generators/surveyor/templates/assets/images/454545_11x11_icon_folder_closed.gif +0 -0
  59. data/generators/surveyor/templates/assets/images/454545_11x11_icon_folder_open.gif +0 -0
  60. data/generators/surveyor/templates/assets/images/454545_11x11_icon_minus.gif +0 -0
  61. data/generators/surveyor/templates/assets/images/454545_11x11_icon_plus.gif +0 -0
  62. data/generators/surveyor/templates/assets/images/454545_7x7_arrow_down.gif +0 -0
  63. data/generators/surveyor/templates/assets/images/454545_7x7_arrow_left.gif +0 -0
  64. data/generators/surveyor/templates/assets/images/454545_7x7_arrow_right.gif +0 -0
  65. data/generators/surveyor/templates/assets/images/454545_7x7_arrow_up.gif +0 -0
  66. data/generators/surveyor/templates/assets/images/888888_11x11_icon_arrows_leftright.gif +0 -0
  67. data/generators/surveyor/templates/assets/images/888888_11x11_icon_arrows_updown.gif +0 -0
  68. data/generators/surveyor/templates/assets/images/888888_11x11_icon_close.gif +0 -0
  69. data/generators/surveyor/templates/assets/images/888888_11x11_icon_doc.gif +0 -0
  70. data/generators/surveyor/templates/assets/images/888888_11x11_icon_folder_closed.gif +0 -0
  71. data/generators/surveyor/templates/assets/images/888888_11x11_icon_folder_open.gif +0 -0
  72. data/generators/surveyor/templates/assets/images/888888_11x11_icon_minus.gif +0 -0
  73. data/generators/surveyor/templates/assets/images/888888_11x11_icon_plus.gif +0 -0
  74. data/generators/surveyor/templates/assets/images/888888_7x7_arrow_down.gif +0 -0
  75. data/generators/surveyor/templates/assets/images/888888_7x7_arrow_left.gif +0 -0
  76. data/generators/surveyor/templates/assets/images/888888_7x7_arrow_right.gif +0 -0
  77. data/generators/surveyor/templates/assets/images/888888_7x7_arrow_up.gif +0 -0
  78. data/generators/surveyor/templates/assets/images/dadada_40x100_textures_02_glass_75.png +0 -0
  79. data/generators/surveyor/templates/assets/images/e6e6e6_40x100_textures_02_glass_75.png +0 -0
  80. data/generators/surveyor/templates/assets/images/ffffff_40x100_textures_01_flat_0.png +0 -0
  81. data/generators/surveyor/templates/assets/images/ffffff_40x100_textures_02_glass_65.png +0 -0
  82. data/generators/surveyor/templates/assets/javascripts/accessibleUISlider.jQuery.js +201 -0
  83. data/generators/surveyor/templates/assets/javascripts/jquery-1.2.6.js +3549 -0
  84. data/generators/surveyor/templates/assets/javascripts/jquery-ui-personalized-1.5.3.js +7616 -0
  85. data/generators/surveyor/templates/assets/javascripts/jquery.form.js +637 -0
  86. data/generators/surveyor/templates/assets/javascripts/surveyor.js +47 -0
  87. data/generators/surveyor/templates/assets/stylesheets/jquery-ui-slider-additions.css +71 -0
  88. data/generators/surveyor/templates/assets/stylesheets/reset.css +50 -0
  89. data/generators/surveyor/templates/assets/stylesheets/sass/surveyor.sass +243 -0
  90. data/generators/surveyor/templates/assets/stylesheets/surveyor.css +235 -0
  91. data/generators/surveyor/templates/assets/stylesheets/ui.theme.css +851 -0
  92. data/generators/surveyor/templates/initializers/haml.rb +8 -0
  93. data/generators/surveyor/templates/initializers/surveyor.rb +10 -0
  94. data/generators/surveyor/templates/migrate/add_correct_answer_id_to_questions.rb +9 -0
  95. data/generators/surveyor/templates/migrate/add_display_order_to_surveys.rb +9 -0
  96. data/generators/surveyor/templates/migrate/add_index_to_response_sets.rb +9 -0
  97. data/generators/surveyor/templates/migrate/add_index_to_surveys.rb +9 -0
  98. data/generators/surveyor/templates/migrate/add_manual_numbering.rb +11 -0
  99. data/generators/surveyor/templates/migrate/add_unique_indicies.rb +17 -0
  100. data/generators/surveyor/templates/migrate/create_answers.rb +37 -0
  101. data/generators/surveyor/templates/migrate/create_dependencies.rb +22 -0
  102. data/generators/surveyor/templates/migrate/create_dependency_conditions.rb +29 -0
  103. data/generators/surveyor/templates/migrate/create_question_groups.rb +27 -0
  104. data/generators/surveyor/templates/migrate/create_questions.rb +36 -0
  105. data/generators/surveyor/templates/migrate/create_response_sets.rb +22 -0
  106. data/generators/surveyor/templates/migrate/create_responses.rb +33 -0
  107. data/generators/surveyor/templates/migrate/create_survey_sections.rb +29 -0
  108. data/generators/surveyor/templates/migrate/create_surveys.rb +31 -0
  109. data/generators/surveyor/templates/migrate/create_validation_conditions.rb +32 -0
  110. data/generators/surveyor/templates/migrate/create_validations.rb +20 -0
  111. data/generators/surveyor/templates/surveys/kitchen_sink_survey.rb +218 -0
  112. data/generators/surveyor/templates/tasks/surveyor.rb +4 -0
  113. data/generators/test_surveyor/templates/TESTING_SURVEYOR +0 -0
  114. data/generators/test_surveyor/templates/environments/cucumber.rb +21 -0
  115. data/generators/test_surveyor/test_surveyor_generator.rb +15 -0
  116. data/jakewendt-surveyor.gemspec +212 -0
  117. data/lib/fixtures_extensions.rb +6 -0
  118. data/lib/jakewendt-surveyor.rb +1 -0
  119. data/lib/surveyor.rb +44 -0
  120. data/lib/surveyor/acts_as_response.rb +33 -0
  121. data/lib/surveyor/config.rb +45 -0
  122. data/lib/tasks/surveyor_tasks.rake +33 -0
  123. data/lib/xml_formatter.rb +12 -0
  124. data/rails/init.rb +1 -0
  125. data/script/surveyor/answer.rb +54 -0
  126. data/script/surveyor/base.rb +77 -0
  127. data/script/surveyor/dependency.rb +13 -0
  128. data/script/surveyor/dependency_condition.rb +40 -0
  129. data/script/surveyor/parser.rb +207 -0
  130. data/script/surveyor/question.rb +37 -0
  131. data/script/surveyor/question_group.rb +26 -0
  132. data/script/surveyor/specs/answer_spec.rb +29 -0
  133. data/script/surveyor/specs/question_spec.rb +63 -0
  134. data/script/surveyor/specs/spec_helper.rb +7 -0
  135. data/script/surveyor/specs/survey_section_spec.rb +23 -0
  136. data/script/surveyor/specs/validation_condition_spec.rb +20 -0
  137. data/script/surveyor/specs/validation_spec.rb +20 -0
  138. data/script/surveyor/survey.rb +35 -0
  139. data/script/surveyor/survey_section.rb +21 -0
  140. data/script/surveyor/validation.rb +21 -0
  141. data/script/surveyor/validation_condition.rb +21 -0
  142. data/script/surveyor/whr_dsl.tmproj +244 -0
  143. data/spec/controllers/surveyor_controller_spec.rb +193 -0
  144. data/spec/factories.rb +145 -0
  145. data/spec/lib/surveyor_spec.rb +44 -0
  146. data/spec/models/answer_spec.rb +29 -0
  147. data/spec/models/dependency_condition_spec.rb +321 -0
  148. data/spec/models/dependency_spec.rb +81 -0
  149. data/spec/models/question_group_spec.rb +35 -0
  150. data/spec/models/question_spec.rb +75 -0
  151. data/spec/models/response_set_spec.rb +245 -0
  152. data/spec/models/response_spec.rb +76 -0
  153. data/spec/models/survey_section_spec.rb +32 -0
  154. data/spec/models/survey_spec.rb +71 -0
  155. data/spec/models/validation_condition_spec.rb +105 -0
  156. data/spec/models/validation_spec.rb +59 -0
  157. data/spec/rcov.opts +2 -0
  158. data/spec/spec.opts +4 -0
  159. data/spec/spec_helper.rb +12 -0
  160. metadata +254 -0
@@ -0,0 +1,8 @@
1
+ begin
2
+ require File.join(File.dirname(__FILE__), 'lib', 'haml') # From here
3
+ rescue LoadError
4
+ require 'haml' # From gem
5
+ end
6
+
7
+ # Load Haml and Sass
8
+ Haml.init_rails(binding)
@@ -0,0 +1,10 @@
1
+ # Loaded once. Restart your app (even in development) to apply changes made here
2
+ Surveyor::Config.run do |config|
3
+ config['default.relative_url_root'] = nil # "surveys"
4
+ config['default.title'] = nil # "You can take these surveys:"
5
+ config['default.layout'] = nil # "surveyor_default"
6
+ config['default.index'] = nil # "/surveys" # or :index_path_method
7
+ config['default.finish'] = nil # "/surveys" # or :finish_path_method
8
+ config['use_restful_authentication'] = false # set to true to use restful authentication
9
+ config['extend'] = %w() # %w(survey surveyor_helper surveyor_controller)
10
+ end
@@ -0,0 +1,9 @@
1
+ class AddCorrectAnswerIdToQuestions < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :questions, :correct_answer_id, :integer
4
+ end
5
+
6
+ def self.down
7
+ remove_column :questions, :correct_answer_id
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class AddDisplayOrderToSurveys < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :surveys, :display_order, :integer
4
+ end
5
+
6
+ def self.down
7
+ remove_column :surveys, :display_order
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class AddIndexToResponseSets < ActiveRecord::Migration
2
+ def self.up
3
+ add_index(:response_sets, :access_code, :name => 'response_sets_ac_idx')
4
+ end
5
+
6
+ def self.down
7
+ remove_index(:response_sets, :name => 'response_sets_ac_idx')
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class AddIndexToSurveys < ActiveRecord::Migration
2
+ def self.up
3
+ add_index(:surveys, :access_code, :name => 'surveys_ac_idx')
4
+ end
5
+
6
+ def self.down
7
+ remove_index(:surveys, :name => 'surveys_ac_idx')
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ class AddManualNumbering < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :surveys, :manual_numbering, :boolean
4
+ add_column :questions, :number, :string
5
+ end
6
+
7
+ def self.down
8
+ remove_column :surveys, :manual_numbering
9
+ remove_column :questions, :number
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ class AddUniqueIndicies < ActiveRecord::Migration
2
+ def self.up
3
+ remove_index(:response_sets, :name => 'response_sets_ac_idx')
4
+ add_index(:response_sets, :access_code, :name => 'response_sets_ac_idx', :unique => true)
5
+
6
+ remove_index(:surveys, :name => 'surveys_ac_idx')
7
+ add_index(:surveys, :access_code, :name => 'surveys_ac_idx', :unique => true)
8
+ end
9
+
10
+ def self.down
11
+ remove_index(:response_sets, :name => 'response_sets_ac_idx')
12
+ add_index(:response_sets, :access_code, :name => 'response_sets_ac_idx')
13
+
14
+ remove_index(:surveys, :name => 'surveys_ac_idx')
15
+ add_index(:surveys, :access_code, :name => 'surveys_ac_idx')
16
+ end
17
+ end
@@ -0,0 +1,37 @@
1
+ class CreateAnswers < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :answers do |t|
4
+ # Context
5
+ t.integer :question_id
6
+
7
+ # Content
8
+ t.text :text
9
+ t.text :short_text #Used for presenting responses to experts (ie non-survey takers). Just a shorted version of the string
10
+ t.text :help_text
11
+ t.integer :weight # Used to assign a weight to an answer object (used for computing surveys that have numerical results) (I added this to support the Urology questionnaire -BLC)
12
+ t.string :response_class # What kind of additional data does this answer accept?
13
+
14
+ # Reference
15
+ t.string :reference_identifier # from paper
16
+ t.string :data_export_identifier # data export
17
+ t.string :common_namespace # maping to a common vocab
18
+ t.string :common_identifier # maping to a common vocab
19
+
20
+ # Display
21
+ t.integer :display_order
22
+ t.boolean :is_exclusive # If set it causes some UI trigger to remove (and disable) all the other answer choices selected for a question (needed for the WHR)
23
+ t.boolean :hide_label
24
+ t.integer :display_length # if smaller than answer.length the html input length will be this value
25
+
26
+ t.string :custom_class
27
+ t.string :custom_renderer
28
+
29
+ t.timestamps
30
+
31
+ end
32
+ end
33
+
34
+ def self.down
35
+ drop_table :answers
36
+ end
37
+ end
@@ -0,0 +1,22 @@
1
+ class CreateDependencies < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :dependencies do |t|
4
+ # Context
5
+ t.integer :question_id # the dependent question
6
+ t.integer :question_group_id
7
+
8
+ # Conditional
9
+ t.string :rule
10
+
11
+ # Result - TODO: figure out the dependency hook presentation options
12
+ # t.string :property_to_toggle # visibility, class_name,
13
+ # t.string :effect #blind, opacity
14
+
15
+ t.timestamps
16
+ end
17
+ end
18
+
19
+ def self.down
20
+ drop_table :dependencies
21
+ end
22
+ end
@@ -0,0 +1,29 @@
1
+ class CreateDependencyConditions < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :dependency_conditions do |t|
4
+ # Context
5
+ t.integer :dependency_id
6
+ t.string :rule_key
7
+
8
+ # Conditional
9
+ t.integer :question_id # the conditional question
10
+ t.string :operator
11
+
12
+ # Value
13
+ t.integer :answer_id
14
+ t.datetime :datetime_value
15
+ t.integer :integer_value
16
+ t.float :float_value
17
+ t.string :unit
18
+ t.text :text_value
19
+ t.string :string_value
20
+ t.string :response_other
21
+
22
+ t.timestamps
23
+ end
24
+ end
25
+
26
+ def self.down
27
+ drop_table :dependency_conditions
28
+ end
29
+ end
@@ -0,0 +1,27 @@
1
+ class CreateQuestionGroups < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :question_groups do |t|
4
+ # Content
5
+ t.text :text
6
+ t.text :help_text
7
+
8
+ # Reference
9
+ t.string :reference_identifier # from paper
10
+ t.string :data_export_identifier # data export
11
+ t.string :common_namespace # maping to a common vocab
12
+ t.string :common_identifier # maping to a common vocab
13
+
14
+ # Display
15
+ t.string :display_type
16
+
17
+ t.string :custom_class
18
+ t.string :custom_renderer
19
+
20
+ t.timestamps
21
+ end
22
+ end
23
+
24
+ def self.down
25
+ drop_table :question_groups
26
+ end
27
+ end
@@ -0,0 +1,36 @@
1
+ class CreateQuestions < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :questions do |t|
4
+ # Context
5
+ t.integer :survey_section_id
6
+ t.integer :question_group_id
7
+
8
+ # Content
9
+ t.text :text
10
+ t.text :short_text # For experts (ie non-survey takers). Short version of text
11
+ t.text :help_text
12
+ t.string :pick
13
+
14
+ # Reference
15
+ t.string :reference_identifier # from paper
16
+ t.string :data_export_identifier # data export
17
+ t.string :common_namespace # maping to a common vocab
18
+ t.string :common_identifier # maping to a common vocab
19
+
20
+ # Display
21
+ t.integer :display_order
22
+ t.string :display_type
23
+ t.boolean :is_mandatory
24
+ t.integer :display_width # used only for slider component (if needed)
25
+
26
+ t.string :custom_class
27
+ t.string :custom_renderer
28
+
29
+ t.timestamps
30
+ end
31
+ end
32
+
33
+ def self.down
34
+ drop_table :questions
35
+ end
36
+ end
@@ -0,0 +1,22 @@
1
+ class CreateResponseSets < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :response_sets do |t|
4
+ # Context
5
+ t.integer :user_id
6
+ t.integer :survey_id
7
+
8
+ # Content
9
+ t.string :access_code #unique id for the object used in urls
10
+
11
+ # Expiry
12
+ t.datetime :started_at
13
+ t.datetime :completed_at
14
+
15
+ t.timestamps
16
+ end
17
+ end
18
+
19
+ def self.down
20
+ drop_table :response_sets
21
+ end
22
+ end
@@ -0,0 +1,33 @@
1
+ class CreateResponses < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :responses do |t|
4
+ # Context
5
+ t.integer :response_set_id
6
+ t.integer :question_id
7
+
8
+ # Content
9
+ t.integer :answer_id
10
+ t.datetime :datetime_value # handles date, time, and datetime (segregate by answer.response_class)
11
+
12
+ #t.datetime :time_value
13
+ t.integer :integer_value
14
+ t.float :float_value
15
+ t.string :unit
16
+ t.text :text_value
17
+ t.string :string_value
18
+ t.string :response_other #used to hold the string entered with "Other" type answers in multiple choice questions
19
+
20
+ # arbitrary identifier used to group responses
21
+ # the pertinent example here is Q: What's your car's make/model/year
22
+ # group 1: Ford/Focus/2007
23
+ # group 2: Toyota/Prius/2006
24
+ t.string :response_group
25
+
26
+ t.timestamps
27
+ end
28
+ end
29
+
30
+ def self.down
31
+ drop_table :responses
32
+ end
33
+ end
@@ -0,0 +1,29 @@
1
+ class CreateSurveySections < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :survey_sections do |t|
4
+ # Context
5
+ t.integer :survey_id
6
+
7
+ # Content
8
+ t.string :title
9
+ t.text :description
10
+
11
+ # Reference
12
+ t.string :reference_identifier # from paper
13
+ t.string :data_export_identifier # data export
14
+ t.string :common_namespace # maping to a common vocab
15
+ t.string :common_identifier # maping to a common vocab
16
+
17
+ # Display
18
+ t.integer :display_order
19
+
20
+ t.string :custom_class
21
+
22
+ t.timestamps
23
+ end
24
+ end
25
+
26
+ def self.down
27
+ drop_table :survey_sections
28
+ end
29
+ end
@@ -0,0 +1,31 @@
1
+ class CreateSurveys < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :surveys do |t|
4
+ # Content
5
+ t.string :title
6
+ t.text :description
7
+
8
+ # Reference
9
+ t.string :access_code
10
+ t.string :reference_identifier # from paper
11
+ t.string :data_export_identifier # data export
12
+ t.string :common_namespace # maping to a common vocab
13
+ t.string :common_identifier # maping to a common vocab
14
+
15
+ # Expiry
16
+ t.datetime :active_at
17
+ t.datetime :inactive_at
18
+
19
+ # Display
20
+ t.string :css_url
21
+
22
+ t.string :custom_class
23
+
24
+ t.timestamps
25
+ end
26
+ end
27
+
28
+ def self.down
29
+ drop_table :surveys
30
+ end
31
+ end
@@ -0,0 +1,32 @@
1
+ class CreateValidationConditions < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :validation_conditions do |t|
4
+ # Context
5
+ t.integer :validation_id
6
+ t.string :rule_key
7
+
8
+ # Conditional
9
+ t.string :operator
10
+
11
+ # Optional external reference
12
+ t.integer :question_id
13
+ t.integer :answer_id
14
+
15
+ # Value
16
+ t.datetime :datetime_value
17
+ t.integer :integer_value
18
+ t.float :float_value
19
+ t.string :unit
20
+ t.text :text_value
21
+ t.string :string_value
22
+ t.string :response_other
23
+ t.string :regexp
24
+
25
+ t.timestamps
26
+ end
27
+ end
28
+
29
+ def self.down
30
+ drop_table :validation_conditions
31
+ end
32
+ end
@@ -0,0 +1,20 @@
1
+ class CreateValidations < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :validations do |t|
4
+ # Context
5
+ t.integer :answer_id # the answer to validate
6
+
7
+ # Conditional
8
+ t.string :rule
9
+
10
+ # Message
11
+ t.string :message
12
+
13
+ t.timestamps
14
+ end
15
+ end
16
+
17
+ def self.down
18
+ drop_table :validations
19
+ end
20
+ end
@@ -0,0 +1,218 @@
1
+ survey "&#8220;Kitchen Sink&#8221; survey" do
2
+
3
+ section "Basic questions" do
4
+ # A label is a question that accepts no answers
5
+ label "These questions are examples of the basic supported input types"
6
+
7
+ # A basic question with radio buttons
8
+ question_1 "What is your favorite color?", :pick => :one
9
+ answer "red"
10
+ answer "blue"
11
+ answer "green"
12
+ answer "yellow"
13
+ answer :other
14
+
15
+ # A basic question with checkboxes
16
+ # "question" and "answer" may be abbreviated as "q" and "a"
17
+ q_2 "Choose the colors you don't like", :pick => :any
18
+ a_1 "red"
19
+ a_2 "blue"
20
+ a_3 "green"
21
+ a_4 "yellow"
22
+ a :omit
23
+
24
+ # A dependent question, with conditions and rule to logically join them
25
+ # the question's reference identifier is "2a", and the answer's reference_identifier is "1"
26
+ # question reference identifiers used in conditions need to be unique on a survey for the lookups to work
27
+ q_2a "Please explain why you don't like this color?"
28
+ a_1 "explanation", :text
29
+ dependency :rule => "A or B or C or D"
30
+ condition_A :q_2, "==", :a_1
31
+ condition_B :q_2, "==", :a_2
32
+ condition_C :q_2, "==", :a_3
33
+ condition_D :q_2, "==", :a_4
34
+
35
+ # When :pick isn't specified, the default is :none (no checkbox or radio button)
36
+ q_montypython3 "What... is your name? (e.g. It is 'Arthur', King of the Britons)"
37
+ a_1 :string
38
+
39
+ # 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
40
+ q_montypython4 "What... is your quest? (e.g. To seek the Holy Grail)"
41
+ a_1 :string
42
+ dependency :rule => "A"
43
+ condition_A :q_montypython3, "==", {:string_value => "It is 'Arthur', King of the Britons", :answer_reference => "1"}
44
+
45
+ # http://www.imdb.com/title/tt0071853/quotes
46
+ q_montypython5 "What... is the air-speed velocity of an unladen swallow? (e.g. What do you mean? An African or European swallow?)"
47
+ a_1 :string
48
+ dependency :rule => "A"
49
+ condition_A :q_montypython4, "==", {:string_value => "To seek the Holy Grail", :answer_reference => "1"}
50
+
51
+ label "Huh? I-- I don't know that! Auuuuuuuugh!"
52
+ dependency :rule => "A"
53
+ condition_A :q_montypython5, "==", {:string_value => "What do you mean? An African or European swallow?", :answer_reference => "1"}
54
+
55
+ # Surveys, sections, questions, groups, and answers all take the following reference arguments
56
+ # :reference_identifier # usually from paper
57
+ # :data_export_identifier # data export
58
+ # :common_namespace # maping to a common vocab
59
+ # :common_identifier # maping to a common vocab
60
+ 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"
61
+ a "who", :string
62
+ a "what", :string
63
+ a "where", :string
64
+
65
+ # Various types of responses can be accepted, and validated
66
+ q "How many pets do you own?"
67
+ a :integer
68
+ validation :rule => "A"
69
+ condition_A ">=", :integer_value => 0
70
+
71
+ # Surveys, sections, questions, groups, and answers also take a custom css class for covenience in custom styling
72
+ q "What is your address?", :custom_class => 'address'
73
+ a :text, :custom_class => 'mapper'
74
+ # validations can use regexp values
75
+ validation :rule => "A"
76
+ condition_A "=~", :regexp => /[0-9a-zA-z\. #]/
77
+
78
+ # Questions, groups, and answers take a custom renderer (a partial in the application's views dir)
79
+ # defaults are "/partials/question_group", "/partials/question", "/partials/answer", so the custom renderers should have a different name
80
+ q "Pick your favorite date AND time" #, :custom_renderer => "/partials/custom_question"
81
+ a :datetime
82
+
83
+ q_time_lunch "What time do you usually take a lunch break?"
84
+ a_1 :time
85
+
86
+ # # validation conditions can look up the response to another question/answer pair
87
+ # q_time_dinner "What time do you usually take a dinner break?"
88
+ # a :time
89
+ # validation :rule => "A"
90
+ # condition_A ">=", :question_reference => "time_lunch", :answer_reference => "1"
91
+
92
+ q "When would you like to meet for dinner?"
93
+ a :date
94
+
95
+ # Sliders deprecate to select boxes when javascript is off
96
+ # Valid Ruby code may be used to shorted repetitive tasks
97
+ q "Adjust the slider to reflect your level of awesomeness", :pick => :one, :display_type => :slider
98
+ (1..10).to_a.each{|num| a num.to_s}
99
+
100
+ q "How much do you like Ruby?", :pick => :one, :display_type => :slider
101
+ ["not at all", "a little", "some", "a lot", "a ton"].each{|level| a level}
102
+
103
+ # The "|" pipe is used to place labels before or after the input elements
104
+ q "How much money do you want?"
105
+ a "$|USD", :float
106
+
107
+ # Questions may be grouped
108
+ group "How much oil do you use per day?", :display_type => :inline do
109
+ q "Quantity"
110
+ a "Quantity", :float
111
+
112
+ q "Unit", :pick => :one, :display_type => :dropdown
113
+ a "Barrels"
114
+ a "Gallons"
115
+ a "Quarts"
116
+ end
117
+
118
+ q "Choose your Illinois county", :pick => :one, :display_type => :dropdown
119
+ ["Adams","Alexander","Bond", "Boone",
120
+ "Brown","Bureau","Calhoun","Carroll","Cass",
121
+ "Champaign", "Christian", "Clark","Clay",
122
+ "Clinton", "Coles", "Cook", "Crawford","Cumberland","DeKalb",
123
+ "De Witt","Douglas","DuPage","Edgar", "Edwards",
124
+ "Effingham","Fayette", "Ford","Franklin","Fulton",
125
+ "Gallatin","Greene", "Grundy", "Hamilton","Hancock",
126
+ "Hardin","Henderson","Henry","Iroquois","Jackson",
127
+ "Jasper", "Jefferson","Jersey","Jo Daviess","Johnson",
128
+ "Kane","Kankakee","Kendall","Knox", "La Salle",
129
+ "Lake", "Lawrence", "Lee","Livingston","Logan",
130
+ "Macon","Macoupin","Madison","Marion","Marshall", "Mason",
131
+ "Massac","McDonough","McHenry","McLean","Menard",
132
+ "Mercer","Monroe", "Montgomery","Morgan","Moultrie",
133
+ "Ogle","Peoria","Perry","Piatt","Pike","Pope",
134
+ "Pulaski","Putnam","Randolph","Richland","Rock Island",
135
+ "Saline","Sangamon","Schuyler","Scott","Shelby",
136
+ "St. Clair","Stark", "Stephenson","Tazewell","Union",
137
+ "Vermilion","Wabash","Warren","Washington","Wayne",
138
+ "White","Whiteside","Will","Williamson","Winnebago","Woodford"].each{ |county| a county}
139
+
140
+ # When an is_exclusive answer is checked, it unchecks all other options and disables them (using Javascript)
141
+ q "Choose your favorite meats", :display_type => :inline, :pick => :any
142
+ a "Chicken"
143
+ a "Pork"
144
+ a "Beef"
145
+ a "Shellfish"
146
+ a "Fish"
147
+ a "I don't eat meats!!!", :is_exclusive => true
148
+
149
+ q "All out of ideas for questions?", :pick => :one, :display_type => :inline
150
+ a "yes"
151
+ a "maybe"
152
+ a "no"
153
+ a "I don't know"
154
+ end
155
+
156
+ section "Complicated questions" do
157
+
158
+ # Grids are useful for repeated questions with the same set of answers, which are specified before the questions
159
+ grid "Tell us how often do you cover these each day" do
160
+ a "1"
161
+ a "2"
162
+ a "3"
163
+ q "Head", :pick => :one
164
+ q "Knees", :pick => :one
165
+ q "Toes", :pick => :one
166
+ end
167
+
168
+ # "grid" is a shortcut for group with :display_type => :grid
169
+ # The answers will be repeated every 10 rows, but long grids aren't recommended as they are generally tedious
170
+ grid "Tell us how you feel today day" do
171
+ a "-2"
172
+ a "-1"
173
+ a "0"
174
+ a "1"
175
+ a "2"
176
+ q "down|up" , :pick => :one
177
+ q "sad|happy", :pick => :one
178
+ q "limp|perky", :pick => :one
179
+ end
180
+
181
+ q "Please rank the following foods based on how much you like them"
182
+ a "|pizza", :integer
183
+ a "|salad", :integer
184
+ a "|sushi", :integer
185
+ a "|ice cream", :integer
186
+ a "|breakfast ceral", :integer
187
+
188
+ # :other, :string allows someone to specify both the "other" and some other information
189
+ q "Choose your favorite utensils and enter frequency of use (daily, weekly, monthly, etc...)", :pick => :any
190
+ a "spoon", :string
191
+ a "fork", :string
192
+ a "knife", :string
193
+ a :other, :string
194
+
195
+ # Repeaters allow multiple responses to a question or set of questions
196
+ repeater "Tell us about the cars you own" do
197
+ q "Make", :pick => :one, :display_type => :dropdown
198
+ a "Toyota"
199
+ a "Ford"
200
+ a "GMChevy"
201
+ a "Ferrari"
202
+ a "Tesla"
203
+ a "Honda"
204
+ a "Other weak brand"
205
+ q "Model"
206
+ a :string
207
+ q "Year"
208
+ a :string
209
+ end
210
+
211
+ repeater "Tell us the name and age of your siblings" do
212
+ q "Sibling"
213
+ a "Name", :string
214
+ a "Age|years", :integer
215
+ end
216
+
217
+ end
218
+ end