fe 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +20 -0
  4. data/Rakefile +48 -0
  5. data/app/assets/images/fe/ajax-loader.gif +0 -0
  6. data/app/assets/images/fe/butgrad.png +0 -0
  7. data/app/assets/images/fe/icons/add.png +0 -0
  8. data/app/assets/images/fe/icons/application_form.png +0 -0
  9. data/app/assets/images/fe/icons/application_form_add.png +0 -0
  10. data/app/assets/images/fe/icons/arrow-move.png +0 -0
  11. data/app/assets/images/fe/icons/arrow_out.png +0 -0
  12. data/app/assets/images/fe/icons/asterisk_yellow.png +0 -0
  13. data/app/assets/images/fe/icons/book-open-list.png +0 -0
  14. data/app/assets/images/fe/icons/book_open.png +0 -0
  15. data/app/assets/images/fe/icons/briefcase.png +0 -0
  16. data/app/assets/images/fe/icons/calendar_view_day.png +0 -0
  17. data/app/assets/images/fe/icons/checkbox.png +0 -0
  18. data/app/assets/images/fe/icons/copy_paste.gif +0 -0
  19. data/app/assets/images/fe/icons/disk.png +0 -0
  20. data/app/assets/images/fe/icons/document--pencil.png +0 -0
  21. data/app/assets/images/fe/icons/document-copy.png +0 -0
  22. data/app/assets/images/fe/icons/map_magnify.png +0 -0
  23. data/app/assets/images/fe/icons/minus-button.png +0 -0
  24. data/app/assets/images/fe/icons/move.png +0 -0
  25. data/app/assets/images/fe/icons/page_error.png +0 -0
  26. data/app/assets/images/fe/icons/page_valid.png +0 -0
  27. data/app/assets/images/fe/icons/page_white.png +0 -0
  28. data/app/assets/images/fe/icons/page_white_add.png +0 -0
  29. data/app/assets/images/fe/icons/page_white_error.png +0 -0
  30. data/app/assets/images/fe/icons/paper-clip.png +0 -0
  31. data/app/assets/images/fe/icons/pencil-small.png +0 -0
  32. data/app/assets/images/fe/icons/pencil.png +0 -0
  33. data/app/assets/images/fe/icons/question-balloon.png +0 -0
  34. data/app/assets/images/fe/icons/radio.png +0 -0
  35. data/app/assets/images/fe/icons/star-small.png +0 -0
  36. data/app/assets/images/fe/icons/table.png +0 -0
  37. data/app/assets/images/fe/icons/text_align_left.png +0 -0
  38. data/app/assets/images/fe/icons/text_horizontalrule.png +0 -0
  39. data/app/assets/images/fe/icons/textfield.png +0 -0
  40. data/app/assets/images/fe/indent.png +0 -0
  41. data/app/assets/images/fe/overlay.png +0 -0
  42. data/app/assets/images/fe/selected_bg.jpg +0 -0
  43. data/app/assets/images/fe/status.gif +0 -0
  44. data/app/assets/images/fe/tooltip/black.png +0 -0
  45. data/app/assets/images/fe/tooltip/black_arrow.png +0 -0
  46. data/app/assets/images/fe/tooltip/black_arrow_big.png +0 -0
  47. data/app/assets/images/fe/tooltip/black_big.png +0 -0
  48. data/app/assets/images/fe/tooltip/white.png +0 -0
  49. data/app/assets/images/fe/tooltip/white_arrow.png +0 -0
  50. data/app/assets/images/fe/tooltip/white_arrow_big.png +0 -0
  51. data/app/assets/images/fe/tooltip/white_big.png +0 -0
  52. data/app/assets/images/fe/uploadify/cancel.png +0 -0
  53. data/app/assets/images/fe/uploadify/uploadify.swf +0 -0
  54. data/app/assets/javascripts/fe/admin.js +7 -0
  55. data/app/assets/javascripts/fe/jquery.metadata.js +122 -0
  56. data/app/assets/javascripts/fe/jquery.scrollTo-min.js +7 -0
  57. data/app/assets/javascripts/fe/jquery.uploadify.v2.1.0.js +258 -0
  58. data/app/assets/javascripts/fe/jquery.validate.pack.js +15 -0
  59. data/app/assets/javascripts/fe/qe.admin.js +115 -0
  60. data/app/assets/javascripts/fe/qe.common.js +57 -0
  61. data/app/assets/javascripts/fe/qe.public.js +331 -0
  62. data/app/assets/javascripts/fe/swfobject.js +4 -0
  63. data/app/assets/stylesheets/fe/qe.screen.css.scss.erb +552 -0
  64. data/app/assets/stylesheets/fe/reset.css +55 -0
  65. data/app/assets/stylesheets/fe/validation.css +91 -0
  66. data/app/controllers/fe/admin/elements_controller.rb +185 -0
  67. data/app/controllers/fe/admin/email_templates_controller.rb +61 -0
  68. data/app/controllers/fe/admin/question_pages_controller.rb +113 -0
  69. data/app/controllers/fe/admin/question_sheets_controller.rb +106 -0
  70. data/app/controllers/fe/answer_pages_controller.rb +3 -0
  71. data/app/controllers/fe/answer_sheets_controller.rb +3 -0
  72. data/app/controllers/fe/concerns/answer_pages_controller_concern.rb +80 -0
  73. data/app/controllers/fe/concerns/answer_sheets_controller_concern.rb +84 -0
  74. data/app/controllers/fe/reference_sheets_controller.rb +29 -0
  75. data/app/helpers/fe/answer_pages_helper.rb +19 -0
  76. data/app/helpers/fe/application_helper.rb +49 -0
  77. data/app/mailers/fe/notifier.rb +22 -0
  78. data/app/models/fe/answer.rb +13 -0
  79. data/app/models/fe/answer_pages_presenter.rb +13 -0
  80. data/app/models/fe/answer_sheet.rb +10 -0
  81. data/app/models/fe/answer_sheet_question_sheet.rb +7 -0
  82. data/app/models/fe/attachment_field.rb +7 -0
  83. data/app/models/fe/choice_field.rb +7 -0
  84. data/app/models/fe/concerns/answer_concern.rb +36 -0
  85. data/app/models/fe/concerns/answer_pages_presenter_concern.rb +99 -0
  86. data/app/models/fe/concerns/answer_sheet_concern.rb +61 -0
  87. data/app/models/fe/concerns/choice_field_concern.rb +131 -0
  88. data/app/models/fe/condition.rb +53 -0
  89. data/app/models/fe/date_field.rb +52 -0
  90. data/app/models/fe/element.rb +164 -0
  91. data/app/models/fe/email_template.rb +7 -0
  92. data/app/models/fe/option.rb +10 -0
  93. data/app/models/fe/option_group.rb +10 -0
  94. data/app/models/fe/page.rb +101 -0
  95. data/app/models/fe/page_element.rb +9 -0
  96. data/app/models/fe/page_link.rb +15 -0
  97. data/app/models/fe/paragraph.rb +10 -0
  98. data/app/models/fe/payment.rb +52 -0
  99. data/app/models/fe/payment_question.rb +22 -0
  100. data/app/models/fe/presenter.rb +23 -0
  101. data/app/models/fe/question.rb +256 -0
  102. data/app/models/fe/question_grid.rb +26 -0
  103. data/app/models/fe/question_grid_with_total.rb +11 -0
  104. data/app/models/fe/question_set.rb +82 -0
  105. data/app/models/fe/question_sheet.rb +73 -0
  106. data/app/models/fe/reference_question.rb +42 -0
  107. data/app/models/fe/reference_sheet.rb +149 -0
  108. data/app/models/fe/section.rb +12 -0
  109. data/app/models/fe/state_chooser.rb +10 -0
  110. data/app/models/fe/text_field.rb +29 -0
  111. data/app/views/fe/admin/elements/_errors.html.erb +1 -0
  112. data/app/views/fe/admin/elements/create.js.erb +11 -0
  113. data/app/views/fe/admin/elements/destroy.js.erb +4 -0
  114. data/app/views/fe/admin/elements/drop.js.erb +2 -0
  115. data/app/views/fe/admin/elements/duplicate.js.erb +2 -0
  116. data/app/views/fe/admin/elements/edit.js.erb +4 -0
  117. data/app/views/fe/admin/elements/error.js.erb +4 -0
  118. data/app/views/fe/admin/elements/new.js.erb +10 -0
  119. data/app/views/fe/admin/elements/reorder.js.erb +0 -0
  120. data/app/views/fe/admin/elements/update.js.erb +9 -0
  121. data/app/views/fe/admin/email_templates/_form.html.erb +8 -0
  122. data/app/views/fe/admin/email_templates/edit.html.erb +13 -0
  123. data/app/views/fe/admin/email_templates/index.html.erb +20 -0
  124. data/app/views/fe/admin/email_templates/new.html.erb +11 -0
  125. data/app/views/fe/admin/panels/_advanced_options.html.erb +16 -0
  126. data/app/views/fe/admin/panels/_common_fields.html.erb +24 -0
  127. data/app/views/fe/admin/panels/_condition.html.erb +6 -0
  128. data/app/views/fe/admin/panels/_insert.html.erb +39 -0
  129. data/app/views/fe/admin/panels/_nav_controls.html.erb +6 -0
  130. data/app/views/fe/admin/panels/_page.html.erb +3 -0
  131. data/app/views/fe/admin/panels/_pages_list.html.erb +16 -0
  132. data/app/views/fe/admin/panels/_prop_attachment_field.html.erb +2 -0
  133. data/app/views/fe/admin/panels/_prop_choice_field.html.erb +46 -0
  134. data/app/views/fe/admin/panels/_prop_date_field.html.erb +7 -0
  135. data/app/views/fe/admin/panels/_prop_element.html.erb +30 -0
  136. data/app/views/fe/admin/panels/_prop_page.html.erb +21 -0
  137. data/app/views/fe/admin/panels/_prop_paragraph.html.erb +32 -0
  138. data/app/views/fe/admin/panels/_prop_question_grid.html.erb +23 -0
  139. data/app/views/fe/admin/panels/_prop_question_grid_with_total.html.erb +14 -0
  140. data/app/views/fe/admin/panels/_prop_reference_question.html.erb +12 -0
  141. data/app/views/fe/admin/panels/_prop_section.html.erb +2 -0
  142. data/app/views/fe/admin/panels/_prop_sheet.html.erb +17 -0
  143. data/app/views/fe/admin/panels/_prop_text_field.html.erb +20 -0
  144. data/app/views/fe/admin/question_pages/_element.html.erb +18 -0
  145. data/app/views/fe/admin/question_pages/_element_show.html.erb +10 -0
  146. data/app/views/fe/admin/question_pages/_errors.html.erb +1 -0
  147. data/app/views/fe/admin/question_pages/_question_page.html.erb +13 -0
  148. data/app/views/fe/admin/question_pages/create.js.erb +11 -0
  149. data/app/views/fe/admin/question_pages/destroy.js.erb +5 -0
  150. data/app/views/fe/admin/question_pages/edit.js.erb +3 -0
  151. data/app/views/fe/admin/question_pages/error.js.erb +4 -0
  152. data/app/views/fe/admin/question_pages/show.js.erb +8 -0
  153. data/app/views/fe/admin/question_pages/show_panel.js.erb +3 -0
  154. data/app/views/fe/admin/question_pages/update.js.erb +2 -0
  155. data/app/views/fe/admin/question_sheets/_errors.html.erb +1 -0
  156. data/app/views/fe/admin/question_sheets/edit.js.erb +3 -0
  157. data/app/views/fe/admin/question_sheets/error.js.erb +5 -0
  158. data/app/views/fe/admin/question_sheets/index.html.erb +41 -0
  159. data/app/views/fe/admin/question_sheets/new.html.erb +15 -0
  160. data/app/views/fe/admin/question_sheets/show.html.erb +27 -0
  161. data/app/views/fe/admin/question_sheets/update.js.erb +2 -0
  162. data/app/views/fe/answer_pages/_answer_page.html.erb +56 -0
  163. data/app/views/fe/answer_pages/_element.html.erb +9 -0
  164. data/app/views/fe/answer_pages/update.js.erb +5 -0
  165. data/app/views/fe/answer_sheets/_answer_sheet.html.erb +24 -0
  166. data/app/views/fe/answer_sheets/_element.html.erb +54 -0
  167. data/app/views/fe/answer_sheets/_incomplete.html.erb +10 -0
  168. data/app/views/fe/answer_sheets/_page_link.html.erb +7 -0
  169. data/app/views/fe/answer_sheets/_pages_list.html.erb +11 -0
  170. data/app/views/fe/answer_sheets/_title.html.erb +1 -0
  171. data/app/views/fe/answer_sheets/edit.html.erb +60 -0
  172. data/app/views/fe/answer_sheets/incomplete.js.erb +5 -0
  173. data/app/views/fe/answer_sheets/index.html.erb +18 -0
  174. data/app/views/fe/answer_sheets/send_reference_invite.js.erb +8 -0
  175. data/app/views/fe/answer_sheets/show.html.erb +13 -0
  176. data/app/views/fe/help/builder.html +33 -0
  177. data/app/views/fe/help/question_grid.html +18 -0
  178. data/app/views/fe/questions/_acceptance.html.erb +13 -0
  179. data/app/views/fe/questions/_attachment_field.html.erb +42 -0
  180. data/app/views/fe/questions/_checkbox_field.html.erb +49 -0
  181. data/app/views/fe/questions/_country.html.erb +7 -0
  182. data/app/views/fe/questions/_date_field.html.erb +7 -0
  183. data/app/views/fe/questions/_date_field_mmyy.html.erb +9 -0
  184. data/app/views/fe/questions/_drop_down_field.html.erb +7 -0
  185. data/app/views/fe/questions/_paragraph.html.erb +1 -0
  186. data/app/views/fe/questions/_question_grid.html.erb +65 -0
  187. data/app/views/fe/questions/_question_grid_with_total.html.erb +57 -0
  188. data/app/views/fe/questions/_questions.html.erb +9 -0
  189. data/app/views/fe/questions/_radio_button_field.html.erb +41 -0
  190. data/app/views/fe/questions/_rating.html.erb +25 -0
  191. data/app/views/fe/questions/_reference_discipler.html.erb +1 -0
  192. data/app/views/fe/questions/_reference_friend.html.erb +1 -0
  193. data/app/views/fe/questions/_reference_parent.html.erb +1 -0
  194. data/app/views/fe/questions/_reference_peer.html.erb +1 -0
  195. data/app/views/fe/questions/_reference_question.html.erb +38 -0
  196. data/app/views/fe/questions/_reference_roommate.html.erb +1 -0
  197. data/app/views/fe/questions/_reference_spiritual.html.erb +1 -0
  198. data/app/views/fe/questions/_reference_staff.html.erb +1 -0
  199. data/app/views/fe/questions/_section.html.erb +1 -0
  200. data/app/views/fe/questions/_state_chooser.html.erb +7 -0
  201. data/app/views/fe/questions/_text_area_field.html.erb +6 -0
  202. data/app/views/fe/questions/_text_field.html.erb +8 -0
  203. data/app/views/fe/questions/_yes_no.html.erb +17 -0
  204. data/app/views/fe/questions/_yes_no_field.erb +17 -0
  205. data/app/views/fe/reference_sheets/not_found.html.erb +5 -0
  206. data/app/views/layouts/fe/application.html.erb +31 -0
  207. data/app/views/layouts/fe/qe.admin.html.erb +30 -0
  208. data/config/routes.rb +49 -0
  209. data/db/migrate/20131003041856_core.rb +91 -0
  210. data/db/migrate/20131003044250_create_reference_sheets.rb +23 -0
  211. data/db/migrate/20131003044436_add_element_and_answer_fields.rb +10 -0
  212. data/db/migrate/20131003044518_create_email_templates.rb +17 -0
  213. data/db/migrate/20131003044621_add_max_lengths.rb +8 -0
  214. data/db/migrate/20131003044714_create_join_table.rb +11 -0
  215. data/db/migrate/20131016162128_remove_question_id_from_element.rb +9 -0
  216. data/lib/fe.rb +22 -0
  217. data/lib/fe/engine.rb +19 -0
  218. data/lib/fe/version.rb +3 -0
  219. data/lib/generators/fe/install_generator.rb +132 -0
  220. data/lib/tasks/qe_tasks.rake +4 -0
  221. data/spec/controllers/fe/admin/elements_controller_spec.rb +4 -0
  222. data/spec/controllers/fe/admin/email_templates_controller_spec.rb +4 -0
  223. data/spec/controllers/fe/admin/question_pages_controller_spec.rb +4 -0
  224. data/spec/controllers/fe/admin/question_sheets_controller_spec.rb +4 -0
  225. data/spec/controllers/fe/answer_pages_controller_spec.rb +4 -0
  226. data/spec/controllers/fe/answer_sheets_controller_spec.rb +4 -0
  227. data/spec/controllers/fe/reference_sheets_controller_spec.rb +4 -0
  228. data/spec/factories/answer_sheets.rb +5 -0
  229. data/spec/factories/answers.rb +4 -0
  230. data/spec/factories/paragraphs.rb +4 -0
  231. data/spec/factories/question_sheet.rb +5 -0
  232. data/spec/factories/reference_questions.rb +4 -0
  233. data/spec/models/fe/answer_sheet_question_sheet_spec.rb +6 -0
  234. data/spec/models/fe/answer_sheet_spec.rb +8 -0
  235. data/spec/models/fe/answer_spec.rb +13 -0
  236. data/spec/models/fe/attachment_field_spec.rb +4 -0
  237. data/spec/models/fe/choice_field_spec.rb +5 -0
  238. data/spec/models/fe/condition_spec.rb +8 -0
  239. data/spec/models/fe/date_field_spec.rb +49 -0
  240. data/spec/models/fe/element_spec.rb +12 -0
  241. data/spec/models/fe/email_template_spec.rb +5 -0
  242. data/spec/models/fe/option_group_spec.rb +4 -0
  243. data/spec/models/fe/option_spec.rb +4 -0
  244. data/spec/models/fe/page_element_spec.rb +6 -0
  245. data/spec/models/fe/page_link_spec.rb +4 -0
  246. data/spec/models/fe/page_spec.rb +14 -0
  247. data/spec/models/fe/paragraph_spec.rb +17 -0
  248. data/spec/models/fe/question_grid_spec.rb +4 -0
  249. data/spec/models/fe/question_grid_with_total_spec.rb +4 -0
  250. data/spec/models/fe/question_set_spec.rb +4 -0
  251. data/spec/models/fe/question_sheet_spec.rb +8 -0
  252. data/spec/models/fe/question_spec.rb +20 -0
  253. data/spec/models/fe/reference_question_spec.rb +17 -0
  254. data/spec/models/fe/reference_sheet_spec.rb +11 -0
  255. data/spec/models/fe/section_spec.rb +4 -0
  256. data/spec/models/fe/state_chooser_spec.rb +4 -0
  257. data/spec/models/fe/text_field_spec.rb +17 -0
  258. data/spec/spec_helper.rb +66 -0
  259. data/spec/support/database.txt +28 -0
  260. metadata +508 -0
@@ -0,0 +1,106 @@
1
+ # QuestionSheets is used exclusively on the administration side to design a Questionniare
2
+ # which can than be instantiated as an AnswerSheet for data capture on the front-end
3
+
4
+ class Fe::Admin::QuestionSheetsController < ApplicationController
5
+ before_filter :check_valid_user
6
+ before_filter :get_question_sheet, :only => [:show, :archive, :unarchive, :destroy, :edit, :update, :duplicate]
7
+ layout 'fe.admin'
8
+
9
+ # list of all questionnaires/forms to edit
10
+ # GET /question_sheets
11
+ def index
12
+ @active_question_sheets = Fe::QuestionSheet.active.order('label')
13
+ @archived_question_sheets = Fe::QuestionSheet.archived.order('label')
14
+
15
+ respond_to do |format|
16
+ format.html # index.rhtml
17
+ format.xml { render :xml => @question_sheets.to_xml }
18
+ end
19
+ end
20
+
21
+ def archive
22
+ @question_sheet.update_attribute(:archived, true)
23
+ redirect_to :back
24
+ end
25
+
26
+ def unarchive
27
+ @question_sheet.update_attribute(:archived, false)
28
+ redirect_to :back
29
+ end
30
+
31
+ def duplicate
32
+ @question_sheet.duplicate
33
+ redirect_to :back
34
+ end
35
+
36
+ # entry point: display form designer with page 1 and panels loaded
37
+ # GET /question_sheets/1
38
+ def show
39
+ @all_pages = @question_sheet.pages
40
+ @page = @all_pages[0]
41
+
42
+ respond_to do |format|
43
+ format.html # show.rhtml
44
+ format.xml { render :xml => @question_sheet.to_xml }
45
+ end
46
+ end
47
+
48
+ # create sheet with inital page, redirect to show
49
+ # POST /question_sheets
50
+ def create
51
+ @question_sheet = Fe::QuestionSheet.new_with_page
52
+
53
+ respond_to do |format|
54
+ if @question_sheet.save
55
+ format.html { redirect_to admin_question_sheet_path(@question_sheet) }
56
+ format.xml { head :created, :location => admin_question_sheet_path(@question_sheet) }
57
+ else
58
+ format.html { render :action => "new" }
59
+ format.xml { render :xml => @question_sheet.errors.to_xml }
60
+ end
61
+ end
62
+ end
63
+
64
+
65
+ # display sheet properties panel
66
+ # GET /question_sheets/1/edit
67
+ def edit
68
+
69
+ respond_to do |format|
70
+ format.js
71
+ end
72
+ end
73
+
74
+ # save changes to properties panel (label, language)
75
+ # PUT /question_sheets/1
76
+ def update
77
+
78
+ respond_to do |format|
79
+ if @question_sheet.update_attributes(params[:question_sheet])
80
+ format.html { redirect_to admin_question_sheet_path(@question_sheet) }
81
+ format.js
82
+ format.xml { head :ok }
83
+ else
84
+ format.html { render :action => "edit" }
85
+ format.js { render :action => "error.rjs"}
86
+ format.xml { render :xml => @question_sheet.errors.to_xml }
87
+ end
88
+ end
89
+ end
90
+
91
+ # mark sheet as destroyed
92
+ # DELETE /question_sheets/1
93
+ def destroy
94
+ @question_sheet.destroy
95
+
96
+ respond_to do |format|
97
+ format.html { redirect_to admin_question_sheets_path }
98
+ format.xml { head :ok }
99
+ end
100
+ end
101
+
102
+ protected
103
+ def get_question_sheet
104
+ @question_sheet = Fe::QuestionSheet.find(params[:id])
105
+ end
106
+ end
@@ -0,0 +1,3 @@
1
+ class Fe::AnswerPagesController < ApplicationController
2
+ include Fe::AnswerPagesControllerConcern
3
+ end
@@ -0,0 +1,3 @@
1
+ class Fe::AnswerSheetsController < ApplicationController
2
+ include Fe::AnswerSheetsControllerConcern
3
+ end
@@ -0,0 +1,80 @@
1
+ module Fe::AnswerPagesControllerConcern
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ before_filter :get_answer_sheet, :only => [:edit, :update, :save_file, :index]
6
+ end
7
+
8
+ def edit
9
+ @elements = @presenter.questions_for_page(params[:id]).elements
10
+ @page = Fe::Page.find(params[:id]) || Fe::Page.find_by_number(1)
11
+
12
+ render :partial => 'answer_page', :locals => { :show_first => nil }
13
+ end
14
+
15
+ # validate and save captured data for a given page
16
+ # PUT /answer_sheets/1/pages/1
17
+ def update
18
+ @page = Fe::Page.find(params[:id])
19
+ questions = @presenter.all_questions_for_page(params[:id])
20
+ questions.post(answer_params, @answer_sheet)
21
+
22
+ questions.save
23
+
24
+ @elements = questions.elements
25
+
26
+ # Save references
27
+
28
+ if params[:reference].present?
29
+ params[:reference].keys.each do |id|
30
+ reference_params = params.fetch(:reference)[id].permit(:relationship, :title, :first_name, :last_name, :phone, :email, :is_staff)
31
+
32
+ ref = @answer_sheet.reference_sheets.find(id)
33
+ # if the email address has changed, we have to trash the old reference answers
34
+ ref.attributes = reference_params
35
+ ref.save(:validate => false)
36
+ end
37
+ end
38
+ @presenter.active_page = nil
39
+ @answer_sheet.touch
40
+ respond_to do |format|
41
+ format.js
42
+ #format.html
43
+ end
44
+ end
45
+
46
+ def save_file
47
+ params.permit(:Filedata)
48
+
49
+ if params[:Filedata]
50
+ @page = Fe::Page.find(params[:id])
51
+ @presenter.active_page = @page
52
+ question = Fe::Element.find(params[:question_id])
53
+ answer = Fe::Answer.where(:answer_sheet_id => @answer_sheet.id, :question_id => question.id).first
54
+ question.answers = [answer] if answer
55
+
56
+ @answer = question.save_file(@answer_sheet, params[:Filedata])
57
+
58
+ render action: :update
59
+ else
60
+ respond_to do |format|
61
+ format.js { head :ok }
62
+ end
63
+ end
64
+ end
65
+
66
+ protected
67
+
68
+ def get_answer_sheet
69
+ @answer_sheet = answer_sheet_type.find(params[:answer_sheet_id])
70
+ @presenter = Fe::AnswerPagesPresenter.new(self, @answer_sheet, params[:a])
71
+ end
72
+
73
+ def answer_sheet_type
74
+ (params[:answer_sheet_type] || Fe.answer_sheet_class || 'AnswerSheet').constantize
75
+ end
76
+
77
+ def answer_params
78
+ params.fetch(:answers, {}).permit!
79
+ end
80
+ end
@@ -0,0 +1,84 @@
1
+ module Fe::AnswerSheetsControllerConcern
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ layout 'application'
6
+ before_filter :get_answer_sheet, :only => [:edit, :show, :send_reference_invite, :submit]
7
+ end
8
+
9
+ # list existing answer sheets
10
+ def index
11
+
12
+ @answer_sheets = answer_sheet_type.order('created_at')
13
+
14
+ # drop down of sheets to capture data for
15
+ @question_sheets = Fe::QuestionSheet.order('label').collect {|s| [s.label, s.id]}
16
+ end
17
+
18
+ def create
19
+ @question_sheet = Fe::QuestionSheet.find(params[:question_sheet_id])
20
+ @answer_sheet = @question_sheet.answer_sheets.create
21
+
22
+ redirect_to edit_answer_sheet_path(@answer_sheet)
23
+ end
24
+
25
+ # display answer sheet for data capture (page 1)
26
+ def edit
27
+ @presenter = Fe::AnswerPagesPresenter.new(self, @answer_sheet, params[:a])
28
+ unless @presenter.active_answer_sheet.pages.present?
29
+ flash[:error] = "Sorry, there are no questions for this form yet."
30
+ if request.env["HTTP_REFERER"]
31
+ redirect_to :back
32
+ else
33
+ render :text => "", :layout => true
34
+ end
35
+ else
36
+ @elements = @presenter.questions_for_page(:first).elements
37
+ @page = @presenter.pages.first
38
+ end
39
+ end
40
+
41
+ # display captured answers (read-only)
42
+ def show
43
+ @question_sheet = @answer_sheet.question_sheet
44
+ pf = Fe.table_name_prefix
45
+ @elements = @question_sheet.pages.collect {|p| p.elements.includes(:pages).order("#{pf}pages.number,#{pf}page_elements.position").all}.flatten
46
+ @elements = Fe::QuestionSet.new(@elements, @answer_sheet).elements.group_by{ |e| e.pages.first }
47
+ end
48
+
49
+ def send_reference_invite
50
+ @reference = @answer_sheet.reference_sheets.find(params[:reference_id])
51
+ if params[:reference]
52
+ reference_params = params.fetch(:reference)[@reference.id.to_s].permit(:relationship, :title, :first_name, :last_name, :phone, :email, :is_staff)
53
+
54
+ @reference.update_attributes(reference_params)
55
+ end
56
+ if @reference.valid?
57
+ @reference.send_invite
58
+ end
59
+ end
60
+
61
+ def submit
62
+ return false unless validate_sheet
63
+ flash[:notice] = "Your form has been submitted. Thanks!"
64
+ redirect_to root_path
65
+ end
66
+
67
+ protected
68
+ def answer_sheet_type
69
+ (params[:answer_sheet_type] || Fe.answer_sheet_class || 'AnswerSheet').constantize
70
+ end
71
+
72
+ def get_answer_sheet
73
+ @answer_sheet = answer_sheet_type.find(params[:id])
74
+ end
75
+
76
+ def validate_sheet
77
+ unless @answer_sheet.completely_filled_out?
78
+ @presenter = Fe::AnswerPagesPresenter.new(self, @answer_sheet, params[:a])
79
+ render 'incomplete'
80
+ return false
81
+ end
82
+ return true
83
+ end
84
+ end
@@ -0,0 +1,29 @@
1
+ class Fe::ReferenceSheetsController < Fe::AnswerSheetsController
2
+ skip_before_filter :ssm_login_required, :login
3
+ before_filter :edit_only, :except => [:edit]
4
+ def edit
5
+ @reference_sheet = @answer_sheet
6
+ unless @answer_sheet
7
+ render :not_found and return
8
+ end
9
+ @answer_sheet.start! if @answer_sheet.created?
10
+ # Set up question_sheet if needed
11
+ if @answer_sheet.question_sheets.empty?
12
+ @answer_sheet.question_sheets << Fe::QuestionSheet.find(@answer_sheet.question.related_question_sheet)
13
+ end
14
+ @presenter = Fe::AnswerPagesPresenter.new(self, @answer_sheet, params[:a])
15
+ @elements = @presenter.questions_for_page(:first).elements
16
+ @page = @presenter.pages.first
17
+ render 'answer_sheets/edit'
18
+ end
19
+
20
+ protected
21
+ def get_answer_sheet
22
+ @answer_sheet ||= Fe::ReferenceSheet.find_by_id_and_access_key(params[:id], params[:a])
23
+ return false unless @answer_sheet
24
+ end
25
+
26
+ def edit_only
27
+ return false
28
+ end
29
+ end
@@ -0,0 +1,19 @@
1
+ module Fe::AnswerPagesHelper
2
+
3
+ # page sidebar navigation
4
+ def li_page_active_if(condition, attributes = {}, &block)
5
+ if condition
6
+ attributes[:class] ||= ''
7
+ attributes[:class] += " active"
8
+ end
9
+ content_tag("li", attributes, &block)
10
+ end
11
+
12
+ # prepares the javascript function call to load a page
13
+ def load_page_js(page_link)
14
+ return '' if page_link.nil?
15
+
16
+ %{$.fe.pageHandler.loadPage('#{page_link.dom_id}','#{page_link.load_path}')}
17
+ end
18
+
19
+ end
@@ -0,0 +1,49 @@
1
+ module Fe
2
+ module ApplicationHelper
3
+ include AnswerPagesHelper
4
+ def pretty_tag(txt)
5
+ txt.to_s.gsub(/\s/, "_").gsub(/(?!-)\W/, "").downcase
6
+ end
7
+
8
+ def flatten_hash(hash = params, ancestor_names = [])
9
+ flat_hash = {}
10
+ hash.each do |k, v|
11
+ names = Array.new(ancestor_names)
12
+ names << k
13
+ if v.is_a?(Hash)
14
+ flat_hash.merge!(flatten_hash(v, names))
15
+ else
16
+ key = flat_hash_key(names)
17
+ key += "[]" if v.is_a?(Array)
18
+ flat_hash[key] = v
19
+ end
20
+ end
21
+
22
+ flat_hash
23
+ end
24
+
25
+ def flat_hash_key(names)
26
+ names = Array.new(names)
27
+ name = names.shift.to_s.dup
28
+ names.each do |n|
29
+ name << "[#{n}]"
30
+ end
31
+ name
32
+ end
33
+
34
+ #def calendar_date_select_tag(name, value = nil, options = {})
35
+ # options.merge!({'data-calendar' => true})
36
+ # text_field_tag(name, value, options )
37
+ #end
38
+
39
+ def tip(t)
40
+ image_tag('fe/icons/question-balloon.png', :title => t, :class => 'tip')
41
+ end
42
+
43
+ def spinner(extra = nil)
44
+ e = extra ? "spinner_#{extra}" : 'spinner'
45
+ image_tag('spinner.gif', :id => e, :style => 'display:none', :class => 'spinner')
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,22 @@
1
+ module Fe
2
+ class Notifier < ActionMailer::Base
3
+
4
+ # call Notifier.deliver_notification
5
+ def notification(p_recipients, p_from, template_name, template_params = {}, options = {})
6
+ email_template = EmailTemplate.find_by_name(template_name)
7
+
8
+ if email_template.nil?
9
+ raise "Email Template #{template_name} could not be found"
10
+ else
11
+ mail(:to => p_recipients,
12
+ :from => p_from,
13
+ :subject => Liquid::Template.parse(email_template.subject).render(template_params),
14
+ :body => Liquid::Template.parse(email_template.content).render(template_params))
15
+ @recipients = p_recipients
16
+ @from = p_from
17
+ @subject = Liquid::Template.parse(email_template.subject).render(template_params)
18
+ @body = Liquid::Template.parse(email_template.content).render(template_params)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,13 @@
1
+ # Answer
2
+ # - a single answer to a given question for a specific answer sheet (instance of capturing answers)
3
+ # - there may be multiple answers to a question for "choose many" (checkboxes)
4
+
5
+ # short value is indexed for finding the value (reporting)
6
+ # essay questions have a nil short value
7
+ # may want special handling for ChoiceFields to store both id/slug and text representations
8
+
9
+ module Fe
10
+ class Answer < ActiveRecord::Base
11
+ include Fe::AnswerConcern
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # A presenter is a class representation of a view, which consolidates data from multiple models
2
+ # Pages editing can be initiated from 3 different controllers, AnswerSheets for the initial load,
3
+ # AnswerPages to AJAX load in another page, and (in BOAT) the ApplicationsController for multiple sheets.
4
+ # Rather than duplicate code from controller to controller, each place can simply reference this Presenter.
5
+
6
+ # We always need data to render the current page for editing.
7
+ # On the initial load, we need data for the page list (sidebar).
8
+ # On later page loads, we need to determine the "next page" which basically requires the page list again.
9
+ module Fe
10
+ class AnswerPagesPresenter < Presenter
11
+ include Fe::AnswerPagesPresenterConcern
12
+ end
13
+ end
@@ -0,0 +1,10 @@
1
+ module Fe
2
+ class AnswerSheet < ActiveRecord::Base
3
+ if Fe.answer_sheet_class.constantize == 'Fe::AnswerSheet'
4
+ self.table_name = self.table_name.sub('fe_', Fe.table_name_prefix)
5
+ else
6
+ self.table_name = Fe.answer_sheet_class.constantize.table_name
7
+ end
8
+ include Fe::AnswerSheetConcern
9
+ end
10
+ end