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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +20 -0
- data/Rakefile +48 -0
- data/app/assets/images/fe/ajax-loader.gif +0 -0
- data/app/assets/images/fe/butgrad.png +0 -0
- data/app/assets/images/fe/icons/add.png +0 -0
- data/app/assets/images/fe/icons/application_form.png +0 -0
- data/app/assets/images/fe/icons/application_form_add.png +0 -0
- data/app/assets/images/fe/icons/arrow-move.png +0 -0
- data/app/assets/images/fe/icons/arrow_out.png +0 -0
- data/app/assets/images/fe/icons/asterisk_yellow.png +0 -0
- data/app/assets/images/fe/icons/book-open-list.png +0 -0
- data/app/assets/images/fe/icons/book_open.png +0 -0
- data/app/assets/images/fe/icons/briefcase.png +0 -0
- data/app/assets/images/fe/icons/calendar_view_day.png +0 -0
- data/app/assets/images/fe/icons/checkbox.png +0 -0
- data/app/assets/images/fe/icons/copy_paste.gif +0 -0
- data/app/assets/images/fe/icons/disk.png +0 -0
- data/app/assets/images/fe/icons/document--pencil.png +0 -0
- data/app/assets/images/fe/icons/document-copy.png +0 -0
- data/app/assets/images/fe/icons/map_magnify.png +0 -0
- data/app/assets/images/fe/icons/minus-button.png +0 -0
- data/app/assets/images/fe/icons/move.png +0 -0
- data/app/assets/images/fe/icons/page_error.png +0 -0
- data/app/assets/images/fe/icons/page_valid.png +0 -0
- data/app/assets/images/fe/icons/page_white.png +0 -0
- data/app/assets/images/fe/icons/page_white_add.png +0 -0
- data/app/assets/images/fe/icons/page_white_error.png +0 -0
- data/app/assets/images/fe/icons/paper-clip.png +0 -0
- data/app/assets/images/fe/icons/pencil-small.png +0 -0
- data/app/assets/images/fe/icons/pencil.png +0 -0
- data/app/assets/images/fe/icons/question-balloon.png +0 -0
- data/app/assets/images/fe/icons/radio.png +0 -0
- data/app/assets/images/fe/icons/star-small.png +0 -0
- data/app/assets/images/fe/icons/table.png +0 -0
- data/app/assets/images/fe/icons/text_align_left.png +0 -0
- data/app/assets/images/fe/icons/text_horizontalrule.png +0 -0
- data/app/assets/images/fe/icons/textfield.png +0 -0
- data/app/assets/images/fe/indent.png +0 -0
- data/app/assets/images/fe/overlay.png +0 -0
- data/app/assets/images/fe/selected_bg.jpg +0 -0
- data/app/assets/images/fe/status.gif +0 -0
- data/app/assets/images/fe/tooltip/black.png +0 -0
- data/app/assets/images/fe/tooltip/black_arrow.png +0 -0
- data/app/assets/images/fe/tooltip/black_arrow_big.png +0 -0
- data/app/assets/images/fe/tooltip/black_big.png +0 -0
- data/app/assets/images/fe/tooltip/white.png +0 -0
- data/app/assets/images/fe/tooltip/white_arrow.png +0 -0
- data/app/assets/images/fe/tooltip/white_arrow_big.png +0 -0
- data/app/assets/images/fe/tooltip/white_big.png +0 -0
- data/app/assets/images/fe/uploadify/cancel.png +0 -0
- data/app/assets/images/fe/uploadify/uploadify.swf +0 -0
- data/app/assets/javascripts/fe/admin.js +7 -0
- data/app/assets/javascripts/fe/jquery.metadata.js +122 -0
- data/app/assets/javascripts/fe/jquery.scrollTo-min.js +7 -0
- data/app/assets/javascripts/fe/jquery.uploadify.v2.1.0.js +258 -0
- data/app/assets/javascripts/fe/jquery.validate.pack.js +15 -0
- data/app/assets/javascripts/fe/qe.admin.js +115 -0
- data/app/assets/javascripts/fe/qe.common.js +57 -0
- data/app/assets/javascripts/fe/qe.public.js +331 -0
- data/app/assets/javascripts/fe/swfobject.js +4 -0
- data/app/assets/stylesheets/fe/qe.screen.css.scss.erb +552 -0
- data/app/assets/stylesheets/fe/reset.css +55 -0
- data/app/assets/stylesheets/fe/validation.css +91 -0
- data/app/controllers/fe/admin/elements_controller.rb +185 -0
- data/app/controllers/fe/admin/email_templates_controller.rb +61 -0
- data/app/controllers/fe/admin/question_pages_controller.rb +113 -0
- data/app/controllers/fe/admin/question_sheets_controller.rb +106 -0
- data/app/controllers/fe/answer_pages_controller.rb +3 -0
- data/app/controllers/fe/answer_sheets_controller.rb +3 -0
- data/app/controllers/fe/concerns/answer_pages_controller_concern.rb +80 -0
- data/app/controllers/fe/concerns/answer_sheets_controller_concern.rb +84 -0
- data/app/controllers/fe/reference_sheets_controller.rb +29 -0
- data/app/helpers/fe/answer_pages_helper.rb +19 -0
- data/app/helpers/fe/application_helper.rb +49 -0
- data/app/mailers/fe/notifier.rb +22 -0
- data/app/models/fe/answer.rb +13 -0
- data/app/models/fe/answer_pages_presenter.rb +13 -0
- data/app/models/fe/answer_sheet.rb +10 -0
- data/app/models/fe/answer_sheet_question_sheet.rb +7 -0
- data/app/models/fe/attachment_field.rb +7 -0
- data/app/models/fe/choice_field.rb +7 -0
- data/app/models/fe/concerns/answer_concern.rb +36 -0
- data/app/models/fe/concerns/answer_pages_presenter_concern.rb +99 -0
- data/app/models/fe/concerns/answer_sheet_concern.rb +61 -0
- data/app/models/fe/concerns/choice_field_concern.rb +131 -0
- data/app/models/fe/condition.rb +53 -0
- data/app/models/fe/date_field.rb +52 -0
- data/app/models/fe/element.rb +164 -0
- data/app/models/fe/email_template.rb +7 -0
- data/app/models/fe/option.rb +10 -0
- data/app/models/fe/option_group.rb +10 -0
- data/app/models/fe/page.rb +101 -0
- data/app/models/fe/page_element.rb +9 -0
- data/app/models/fe/page_link.rb +15 -0
- data/app/models/fe/paragraph.rb +10 -0
- data/app/models/fe/payment.rb +52 -0
- data/app/models/fe/payment_question.rb +22 -0
- data/app/models/fe/presenter.rb +23 -0
- data/app/models/fe/question.rb +256 -0
- data/app/models/fe/question_grid.rb +26 -0
- data/app/models/fe/question_grid_with_total.rb +11 -0
- data/app/models/fe/question_set.rb +82 -0
- data/app/models/fe/question_sheet.rb +73 -0
- data/app/models/fe/reference_question.rb +42 -0
- data/app/models/fe/reference_sheet.rb +149 -0
- data/app/models/fe/section.rb +12 -0
- data/app/models/fe/state_chooser.rb +10 -0
- data/app/models/fe/text_field.rb +29 -0
- data/app/views/fe/admin/elements/_errors.html.erb +1 -0
- data/app/views/fe/admin/elements/create.js.erb +11 -0
- data/app/views/fe/admin/elements/destroy.js.erb +4 -0
- data/app/views/fe/admin/elements/drop.js.erb +2 -0
- data/app/views/fe/admin/elements/duplicate.js.erb +2 -0
- data/app/views/fe/admin/elements/edit.js.erb +4 -0
- data/app/views/fe/admin/elements/error.js.erb +4 -0
- data/app/views/fe/admin/elements/new.js.erb +10 -0
- data/app/views/fe/admin/elements/reorder.js.erb +0 -0
- data/app/views/fe/admin/elements/update.js.erb +9 -0
- data/app/views/fe/admin/email_templates/_form.html.erb +8 -0
- data/app/views/fe/admin/email_templates/edit.html.erb +13 -0
- data/app/views/fe/admin/email_templates/index.html.erb +20 -0
- data/app/views/fe/admin/email_templates/new.html.erb +11 -0
- data/app/views/fe/admin/panels/_advanced_options.html.erb +16 -0
- data/app/views/fe/admin/panels/_common_fields.html.erb +24 -0
- data/app/views/fe/admin/panels/_condition.html.erb +6 -0
- data/app/views/fe/admin/panels/_insert.html.erb +39 -0
- data/app/views/fe/admin/panels/_nav_controls.html.erb +6 -0
- data/app/views/fe/admin/panels/_page.html.erb +3 -0
- data/app/views/fe/admin/panels/_pages_list.html.erb +16 -0
- data/app/views/fe/admin/panels/_prop_attachment_field.html.erb +2 -0
- data/app/views/fe/admin/panels/_prop_choice_field.html.erb +46 -0
- data/app/views/fe/admin/panels/_prop_date_field.html.erb +7 -0
- data/app/views/fe/admin/panels/_prop_element.html.erb +30 -0
- data/app/views/fe/admin/panels/_prop_page.html.erb +21 -0
- data/app/views/fe/admin/panels/_prop_paragraph.html.erb +32 -0
- data/app/views/fe/admin/panels/_prop_question_grid.html.erb +23 -0
- data/app/views/fe/admin/panels/_prop_question_grid_with_total.html.erb +14 -0
- data/app/views/fe/admin/panels/_prop_reference_question.html.erb +12 -0
- data/app/views/fe/admin/panels/_prop_section.html.erb +2 -0
- data/app/views/fe/admin/panels/_prop_sheet.html.erb +17 -0
- data/app/views/fe/admin/panels/_prop_text_field.html.erb +20 -0
- data/app/views/fe/admin/question_pages/_element.html.erb +18 -0
- data/app/views/fe/admin/question_pages/_element_show.html.erb +10 -0
- data/app/views/fe/admin/question_pages/_errors.html.erb +1 -0
- data/app/views/fe/admin/question_pages/_question_page.html.erb +13 -0
- data/app/views/fe/admin/question_pages/create.js.erb +11 -0
- data/app/views/fe/admin/question_pages/destroy.js.erb +5 -0
- data/app/views/fe/admin/question_pages/edit.js.erb +3 -0
- data/app/views/fe/admin/question_pages/error.js.erb +4 -0
- data/app/views/fe/admin/question_pages/show.js.erb +8 -0
- data/app/views/fe/admin/question_pages/show_panel.js.erb +3 -0
- data/app/views/fe/admin/question_pages/update.js.erb +2 -0
- data/app/views/fe/admin/question_sheets/_errors.html.erb +1 -0
- data/app/views/fe/admin/question_sheets/edit.js.erb +3 -0
- data/app/views/fe/admin/question_sheets/error.js.erb +5 -0
- data/app/views/fe/admin/question_sheets/index.html.erb +41 -0
- data/app/views/fe/admin/question_sheets/new.html.erb +15 -0
- data/app/views/fe/admin/question_sheets/show.html.erb +27 -0
- data/app/views/fe/admin/question_sheets/update.js.erb +2 -0
- data/app/views/fe/answer_pages/_answer_page.html.erb +56 -0
- data/app/views/fe/answer_pages/_element.html.erb +9 -0
- data/app/views/fe/answer_pages/update.js.erb +5 -0
- data/app/views/fe/answer_sheets/_answer_sheet.html.erb +24 -0
- data/app/views/fe/answer_sheets/_element.html.erb +54 -0
- data/app/views/fe/answer_sheets/_incomplete.html.erb +10 -0
- data/app/views/fe/answer_sheets/_page_link.html.erb +7 -0
- data/app/views/fe/answer_sheets/_pages_list.html.erb +11 -0
- data/app/views/fe/answer_sheets/_title.html.erb +1 -0
- data/app/views/fe/answer_sheets/edit.html.erb +60 -0
- data/app/views/fe/answer_sheets/incomplete.js.erb +5 -0
- data/app/views/fe/answer_sheets/index.html.erb +18 -0
- data/app/views/fe/answer_sheets/send_reference_invite.js.erb +8 -0
- data/app/views/fe/answer_sheets/show.html.erb +13 -0
- data/app/views/fe/help/builder.html +33 -0
- data/app/views/fe/help/question_grid.html +18 -0
- data/app/views/fe/questions/_acceptance.html.erb +13 -0
- data/app/views/fe/questions/_attachment_field.html.erb +42 -0
- data/app/views/fe/questions/_checkbox_field.html.erb +49 -0
- data/app/views/fe/questions/_country.html.erb +7 -0
- data/app/views/fe/questions/_date_field.html.erb +7 -0
- data/app/views/fe/questions/_date_field_mmyy.html.erb +9 -0
- data/app/views/fe/questions/_drop_down_field.html.erb +7 -0
- data/app/views/fe/questions/_paragraph.html.erb +1 -0
- data/app/views/fe/questions/_question_grid.html.erb +65 -0
- data/app/views/fe/questions/_question_grid_with_total.html.erb +57 -0
- data/app/views/fe/questions/_questions.html.erb +9 -0
- data/app/views/fe/questions/_radio_button_field.html.erb +41 -0
- data/app/views/fe/questions/_rating.html.erb +25 -0
- data/app/views/fe/questions/_reference_discipler.html.erb +1 -0
- data/app/views/fe/questions/_reference_friend.html.erb +1 -0
- data/app/views/fe/questions/_reference_parent.html.erb +1 -0
- data/app/views/fe/questions/_reference_peer.html.erb +1 -0
- data/app/views/fe/questions/_reference_question.html.erb +38 -0
- data/app/views/fe/questions/_reference_roommate.html.erb +1 -0
- data/app/views/fe/questions/_reference_spiritual.html.erb +1 -0
- data/app/views/fe/questions/_reference_staff.html.erb +1 -0
- data/app/views/fe/questions/_section.html.erb +1 -0
- data/app/views/fe/questions/_state_chooser.html.erb +7 -0
- data/app/views/fe/questions/_text_area_field.html.erb +6 -0
- data/app/views/fe/questions/_text_field.html.erb +8 -0
- data/app/views/fe/questions/_yes_no.html.erb +17 -0
- data/app/views/fe/questions/_yes_no_field.erb +17 -0
- data/app/views/fe/reference_sheets/not_found.html.erb +5 -0
- data/app/views/layouts/fe/application.html.erb +31 -0
- data/app/views/layouts/fe/qe.admin.html.erb +30 -0
- data/config/routes.rb +49 -0
- data/db/migrate/20131003041856_core.rb +91 -0
- data/db/migrate/20131003044250_create_reference_sheets.rb +23 -0
- data/db/migrate/20131003044436_add_element_and_answer_fields.rb +10 -0
- data/db/migrate/20131003044518_create_email_templates.rb +17 -0
- data/db/migrate/20131003044621_add_max_lengths.rb +8 -0
- data/db/migrate/20131003044714_create_join_table.rb +11 -0
- data/db/migrate/20131016162128_remove_question_id_from_element.rb +9 -0
- data/lib/fe.rb +22 -0
- data/lib/fe/engine.rb +19 -0
- data/lib/fe/version.rb +3 -0
- data/lib/generators/fe/install_generator.rb +132 -0
- data/lib/tasks/qe_tasks.rake +4 -0
- data/spec/controllers/fe/admin/elements_controller_spec.rb +4 -0
- data/spec/controllers/fe/admin/email_templates_controller_spec.rb +4 -0
- data/spec/controllers/fe/admin/question_pages_controller_spec.rb +4 -0
- data/spec/controllers/fe/admin/question_sheets_controller_spec.rb +4 -0
- data/spec/controllers/fe/answer_pages_controller_spec.rb +4 -0
- data/spec/controllers/fe/answer_sheets_controller_spec.rb +4 -0
- data/spec/controllers/fe/reference_sheets_controller_spec.rb +4 -0
- data/spec/factories/answer_sheets.rb +5 -0
- data/spec/factories/answers.rb +4 -0
- data/spec/factories/paragraphs.rb +4 -0
- data/spec/factories/question_sheet.rb +5 -0
- data/spec/factories/reference_questions.rb +4 -0
- data/spec/models/fe/answer_sheet_question_sheet_spec.rb +6 -0
- data/spec/models/fe/answer_sheet_spec.rb +8 -0
- data/spec/models/fe/answer_spec.rb +13 -0
- data/spec/models/fe/attachment_field_spec.rb +4 -0
- data/spec/models/fe/choice_field_spec.rb +5 -0
- data/spec/models/fe/condition_spec.rb +8 -0
- data/spec/models/fe/date_field_spec.rb +49 -0
- data/spec/models/fe/element_spec.rb +12 -0
- data/spec/models/fe/email_template_spec.rb +5 -0
- data/spec/models/fe/option_group_spec.rb +4 -0
- data/spec/models/fe/option_spec.rb +4 -0
- data/spec/models/fe/page_element_spec.rb +6 -0
- data/spec/models/fe/page_link_spec.rb +4 -0
- data/spec/models/fe/page_spec.rb +14 -0
- data/spec/models/fe/paragraph_spec.rb +17 -0
- data/spec/models/fe/question_grid_spec.rb +4 -0
- data/spec/models/fe/question_grid_with_total_spec.rb +4 -0
- data/spec/models/fe/question_set_spec.rb +4 -0
- data/spec/models/fe/question_sheet_spec.rb +8 -0
- data/spec/models/fe/question_spec.rb +20 -0
- data/spec/models/fe/reference_question_spec.rb +17 -0
- data/spec/models/fe/reference_sheet_spec.rb +11 -0
- data/spec/models/fe/section_spec.rb +4 -0
- data/spec/models/fe/state_chooser_spec.rb +4 -0
- data/spec/models/fe/text_field_spec.rb +17 -0
- data/spec/spec_helper.rb +66 -0
- data/spec/support/database.txt +28 -0
- metadata +508 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
module Fe
|
|
2
|
+
class AnswerSheetQuestionSheet < ActiveRecord::Base
|
|
3
|
+
self.table_name = self.table_name.sub('fe_', Fe.table_name_prefix)
|
|
4
|
+
belongs_to :answer_sheet, class_name: Fe.answer_sheet_class
|
|
5
|
+
belongs_to :question_sheet, class_name: 'Fe::QuestionSheet'
|
|
6
|
+
end
|
|
7
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Fe
|
|
2
|
+
module AnswerConcern
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
include ActionView::Helpers::TextHelper
|
|
5
|
+
|
|
6
|
+
included do
|
|
7
|
+
|
|
8
|
+
belongs_to :answer_sheet
|
|
9
|
+
belongs_to :question, :class_name => "Element", :foreign_key => "question_id"
|
|
10
|
+
|
|
11
|
+
# validates_presence_of :value
|
|
12
|
+
validates_length_of :short_value, :maximum => 255, :allow_nil => true
|
|
13
|
+
|
|
14
|
+
before_save :set_value_from_filename
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def set(value, short_value = value)
|
|
18
|
+
self.value = value
|
|
19
|
+
self.short_value = truncate(short_value, :length => 225) # adds ... if truncated (but not if not)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def to_s
|
|
23
|
+
self.value
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def set_value_from_filename
|
|
27
|
+
self.value = self.short_value = self.attachment_file_name if self[:attachment_file_name].present?
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
module ClassMethods
|
|
31
|
+
def table_name
|
|
32
|
+
"#{Fe.table_name_prefix}answers"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
module Fe
|
|
2
|
+
module AnswerPagesPresenterConcern
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
included do
|
|
6
|
+
attr_accessor :active_answer_sheet, :page_links, :active_page, :pages
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def initialize(controller, answer_sheets, a = nil, custom_pages = nil)
|
|
10
|
+
super(controller)
|
|
11
|
+
@answer_sheets = Array.wrap(answer_sheets)
|
|
12
|
+
@active_answer_sheet = @answer_sheets.first
|
|
13
|
+
initialize_pages(@active_answer_sheet)
|
|
14
|
+
|
|
15
|
+
@page_links = page_list(@answer_sheets, a, custom_pages)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def questions_for_page(page_id=:first)
|
|
19
|
+
@active_page = page_id == :first ? pages.first : pages.detect {|p| p.id == page_id.to_i}
|
|
20
|
+
@active_page ||= @active_answer_sheet.pages.visible.includes(:elements).find(page_id)
|
|
21
|
+
Fe::QuestionSet.new(@active_page ? @active_page.elements : [], @active_answer_sheet)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def all_questions_for_page(page_id=:first)
|
|
25
|
+
@active_page = page_id == :first ? pages.first : pages.detect {|p| p.id == page_id.to_i}
|
|
26
|
+
@active_page ||= @active_answer_sheet.pages.visible.find(page_id)
|
|
27
|
+
Fe::QuestionSet.new(@active_page ? @active_page.all_elements : [], @active_answer_sheet)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# title
|
|
31
|
+
def sheet_title
|
|
32
|
+
@active_answer_sheet.question_sheet.label
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def active_page_link
|
|
36
|
+
return unless @active_page
|
|
37
|
+
link = new_page_link(@active_answer_sheet, @active_page)
|
|
38
|
+
link.save_path = answer_sheet_page_path(@active_answer_sheet, @active_page)
|
|
39
|
+
link
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def next_page
|
|
43
|
+
active_page_dom_id = active_page_link.dom_id
|
|
44
|
+
|
|
45
|
+
this_page = @page_links.find {|p| p.dom_id == active_page_dom_id}
|
|
46
|
+
@page_links.at( @page_links.index(this_page) + 1 ) unless this_page.nil?
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def reference?
|
|
50
|
+
if @active_answer_sheet.respond_to?(:apply_sheet)
|
|
51
|
+
@active_answer_sheet.apply_sheet.sleeve_sheet.assign_to == 'reference'
|
|
52
|
+
else
|
|
53
|
+
false
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def initialize_pages(answer_sheet)
|
|
58
|
+
@pages = []
|
|
59
|
+
answer_sheet.question_sheets.each do |qs|
|
|
60
|
+
qs.pages.visible.each do |page|
|
|
61
|
+
@pages << page
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def started?
|
|
67
|
+
active_answer_sheet.question_sheets.each do |qs|
|
|
68
|
+
qs.pages.visible.each do |page|
|
|
69
|
+
return true if page.started?(active_answer_sheet)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def new_page_link(answer_sheet, page, a = nil)
|
|
75
|
+
Fe::PageLink.new(page.label, edit_answer_sheet_page_path(answer_sheet, page, :a => a), dom_page(answer_sheet, page), page) if page
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
protected
|
|
79
|
+
|
|
80
|
+
# for pages_list sidebar
|
|
81
|
+
def page_list(answer_sheets, a = nil, custom_pages = nil)
|
|
82
|
+
page_list = []
|
|
83
|
+
answer_sheets.each do |answer_sheet|
|
|
84
|
+
pages.each do |page|
|
|
85
|
+
page_list << new_page_link(answer_sheet, page, a)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
page_list = page_list + custom_pages unless custom_pages.nil?
|
|
89
|
+
page_list
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# page is identified by answer sheet, so can have multiple sheets loaded at once
|
|
93
|
+
def dom_page(answer_sheet, page)
|
|
94
|
+
dom = "#{dom_id(answer_sheet)}-#{dom_id(page)}"
|
|
95
|
+
dom += "-no_cache" if page.no_cache
|
|
96
|
+
dom
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
module Fe
|
|
2
|
+
module AnswerSheetConcern
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
included do
|
|
6
|
+
has_many :answer_sheet_question_sheets,
|
|
7
|
+
:class_name => "Fe::AnswerSheetQuestionSheet",
|
|
8
|
+
:foreign_key => 'answer_sheet_id'
|
|
9
|
+
|
|
10
|
+
has_many :question_sheets,
|
|
11
|
+
:through => :answer_sheet_question_sheets
|
|
12
|
+
|
|
13
|
+
has_many :answers,
|
|
14
|
+
:class_name => 'Fe::Answer',
|
|
15
|
+
:foreign_key => 'answer_sheet_id'
|
|
16
|
+
|
|
17
|
+
has_many :reference_sheets,
|
|
18
|
+
:class_name => "Fe::ReferenceSheet",
|
|
19
|
+
:foreign_key => "applicant_answer_sheet_id"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def complete?
|
|
23
|
+
!completed_at.nil?
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# answers for this sheet, grouped by question id
|
|
27
|
+
def answers_by_question
|
|
28
|
+
@answers_by_question ||= answers.group_by { |answer| answer.question_id }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Convenience method if there is only one question sheet in your system
|
|
32
|
+
def question_sheet
|
|
33
|
+
question_sheets.first
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def pages
|
|
37
|
+
Page.where(:question_sheet_id => question_sheets.collect(&:id))
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def completely_filled_out?
|
|
41
|
+
pages.all? {|p| p.complete?(self)}
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def has_answer_for?(question_id)
|
|
45
|
+
!answers_by_question[question_id].nil?
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def reference?
|
|
49
|
+
false
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def percent_complete
|
|
53
|
+
num_questions = question_sheets.inject(0.0) { |sum, qs| qs.nil? ? sum : qs.questions.length + sum }
|
|
54
|
+
return 0 if num_questions == 0
|
|
55
|
+
num_answers = answers.where("value IS NOT NULL && value != ''").select("DISTINCT question_id").count
|
|
56
|
+
[ [ (num_answers.to_f / num_questions.to_f * 100.0).to_i, 100 ].min, 0 ].max
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def collat_title() "" end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
require 'net/http'
|
|
2
|
+
begin
|
|
3
|
+
require 'xml/libxml'
|
|
4
|
+
rescue LoadError
|
|
5
|
+
require 'rexml/document'
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
module Fe
|
|
9
|
+
module ChoiceFieldConcern
|
|
10
|
+
extend ActiveSupport::Concern
|
|
11
|
+
|
|
12
|
+
included do
|
|
13
|
+
has_many :elements, :class_name => "Element", :foreign_key => "conditional_id", :dependent => :nullify#, :order => :position
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Returns choices stored one per line in content field
|
|
17
|
+
def choices
|
|
18
|
+
retVal = Array.new
|
|
19
|
+
if ['yes-no', 'acceptance'].include?(self.style)
|
|
20
|
+
return [["Yes",1],["No",0]]
|
|
21
|
+
elsif !source.blank?
|
|
22
|
+
begin
|
|
23
|
+
doc = XML::Document.file(source)
|
|
24
|
+
options = doc.find(text_xpath).collect { |n| n.content }
|
|
25
|
+
values = doc.find(value_xpath).collect { |n| n.content }
|
|
26
|
+
retVal = [options, values].transpose
|
|
27
|
+
rescue NameError
|
|
28
|
+
doc = REXML::Document.new Net::HTTP.get_response(URI.parse(source)).body
|
|
29
|
+
retVal = [ doc.elements.collect(text_xpath){|c|c.text}, doc.elements.collect(value_xpath){|c|c.text} ].transpose.sort
|
|
30
|
+
end
|
|
31
|
+
elsif !content.nil?
|
|
32
|
+
content.split("\n").each do |opt|
|
|
33
|
+
pair = opt.strip.split(";").reverse!
|
|
34
|
+
pair[1] ||= pair[0]
|
|
35
|
+
retVal << pair
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
return retVal
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def has_answer?(choice, app)
|
|
42
|
+
responses(app).each do |r| # loop through Answers
|
|
43
|
+
# legacy field type choices may be int or tinyint
|
|
44
|
+
# raise r.inspect + ' - ' + choice.inspect if id == 1137 && r != 1
|
|
45
|
+
# r = r.to_s
|
|
46
|
+
return true if case true
|
|
47
|
+
when is_true(r) then is_true(choice)
|
|
48
|
+
when is_false(r) then is_false(choice)
|
|
49
|
+
else
|
|
50
|
+
r.to_s == choice.to_s
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
false
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# which view to render this element?
|
|
57
|
+
def ptemplate
|
|
58
|
+
if self.style == 'checkbox'
|
|
59
|
+
'checkbox_field'
|
|
60
|
+
elsif self.style == 'drop-down'
|
|
61
|
+
'drop_down_field'
|
|
62
|
+
elsif self.style == 'radio'
|
|
63
|
+
'radio_button_field'
|
|
64
|
+
elsif self.style == 'yes-no'
|
|
65
|
+
'yes_no'
|
|
66
|
+
elsif self.style == 'rating'
|
|
67
|
+
'rating'
|
|
68
|
+
elsif self.style == 'acceptance'
|
|
69
|
+
'acceptance'
|
|
70
|
+
elsif self.style == 'country'
|
|
71
|
+
'country'
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# element view provides the element label?
|
|
76
|
+
def default_label?
|
|
77
|
+
if self.style == 'acceptance' || self.hide_option_labels?
|
|
78
|
+
false # template provides its own label
|
|
79
|
+
else
|
|
80
|
+
true
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# css class names for javascript-based validation
|
|
85
|
+
def validation_class(answer_sheet)
|
|
86
|
+
if self.required?(answer_sheet)
|
|
87
|
+
if self.style == 'drop-down'
|
|
88
|
+
'validate-selection required'
|
|
89
|
+
elsif self.style == 'rating'
|
|
90
|
+
'validate-rating required'
|
|
91
|
+
elsif self.style == 'acceptance'
|
|
92
|
+
'required'
|
|
93
|
+
else
|
|
94
|
+
'validate-one-required required'
|
|
95
|
+
end
|
|
96
|
+
else
|
|
97
|
+
''
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def display_response(app=nil)
|
|
102
|
+
r = responses(app)
|
|
103
|
+
r.reject! {|a| a.class == Answer && a.value.blank?}
|
|
104
|
+
if r.blank?
|
|
105
|
+
""
|
|
106
|
+
elsif self.style == 'yes-no'
|
|
107
|
+
ans = r.first
|
|
108
|
+
if ans.class == Answer
|
|
109
|
+
is_true(ans.value) ? "Yes" : "No"
|
|
110
|
+
else
|
|
111
|
+
is_true(ans) ? "Yes" : "No"
|
|
112
|
+
end
|
|
113
|
+
elsif self.style == 'acceptance'
|
|
114
|
+
"Accepted" # if not blank, it's accepted
|
|
115
|
+
else
|
|
116
|
+
r.compact.join(", ")
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
protected
|
|
121
|
+
def is_true(val)
|
|
122
|
+
[1,'1',true,'true','Yes','yes'].include?(val) # note: true = anything but false | nil
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def is_false(val)
|
|
126
|
+
# returns false if false (a bit odd)
|
|
127
|
+
[0,'0',false,'false','No','no'].include?(val)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
end
|
|
131
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# :trigger_id - question that controls the state of the dependent pages/questions
|
|
2
|
+
# :expresion - a single expression for eval() by both Javascript and Ruby
|
|
3
|
+
# i.e. "answer == 'yes'"
|
|
4
|
+
# a question can have more than one answer (choose many) in which case ANY answer will do (find)
|
|
5
|
+
module Fe
|
|
6
|
+
class Condition < ActiveRecord::Base
|
|
7
|
+
self.table_name = self.table_name.sub('fe_', Fe.table_name_prefix)
|
|
8
|
+
|
|
9
|
+
belongs_to :question_sheet
|
|
10
|
+
|
|
11
|
+
belongs_to :trigger,
|
|
12
|
+
:class_name => "Question",
|
|
13
|
+
:foreign_key => "trigger_id"
|
|
14
|
+
|
|
15
|
+
validates_presence_of :expression
|
|
16
|
+
validates_length_of :expression, :maximum => 255, :allow_nil => true
|
|
17
|
+
|
|
18
|
+
# evaluate triggering element against expression and return match|nil
|
|
19
|
+
def evaluate?
|
|
20
|
+
true
|
|
21
|
+
# answers = self.trigger.response # answers loaded?
|
|
22
|
+
# expression = self.expression.downcase
|
|
23
|
+
# answers.find {|answer| answer = answer.downcase; eval(expression)}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# javascript to toggle pages/elements based on the "response"
|
|
27
|
+
def trigger_js
|
|
28
|
+
# will find the first answer (if multiple/checkboxes) where the expression evaluates to true (downcase both to be case insensitive)
|
|
29
|
+
# if no match, disabled will be true, otherwise false
|
|
30
|
+
js = <<-JS
|
|
31
|
+
disabled = (response.find(function(answer) {
|
|
32
|
+
answer = toLowerCase(answer);
|
|
33
|
+
return eval("#{escape_javascript(self.expression.downcase)}");
|
|
34
|
+
}) == undefined);
|
|
35
|
+
JS
|
|
36
|
+
|
|
37
|
+
if toggle_id.nil?
|
|
38
|
+
# toggling a whole page (link), which will affect final page validation
|
|
39
|
+
else
|
|
40
|
+
# toggling an element (form element)... if page is loaded/cached (if not, the server-side will take care of it on load)
|
|
41
|
+
js = js + <<-JS
|
|
42
|
+
if(page_handler.isPageLoaded('page_#{self.toggle_page_id}'))
|
|
43
|
+
{
|
|
44
|
+
$('element_#{self.toggle_id}').disabled = disabled;
|
|
45
|
+
}
|
|
46
|
+
JS
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
js
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# DateField
|
|
2
|
+
# - a question that provides a calendar/date picker
|
|
3
|
+
module Fe
|
|
4
|
+
class DateField < Question
|
|
5
|
+
|
|
6
|
+
def validation_class(answer_sheet = nil)
|
|
7
|
+
if self.style == 'mmyy'
|
|
8
|
+
'validate-selection ' + super
|
|
9
|
+
else
|
|
10
|
+
'validate-date ' + super
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def response(answer_sheet = nil)
|
|
15
|
+
r = super
|
|
16
|
+
return nil if r.blank?
|
|
17
|
+
begin
|
|
18
|
+
if r.is_a?(String)
|
|
19
|
+
parts = r.split('/')
|
|
20
|
+
if parts.length == 3
|
|
21
|
+
r = Time.mktime(parts[2], parts[0], parts[1])
|
|
22
|
+
else
|
|
23
|
+
r = Time.parse(r)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
rescue ArgumentError
|
|
27
|
+
r = ''
|
|
28
|
+
end
|
|
29
|
+
r
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def display_response(answer_sheet = nil)
|
|
33
|
+
return format_date_response(answer_sheet)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def format_date_response(answer_sheet = nil)
|
|
37
|
+
r = response(answer_sheet)
|
|
38
|
+
r = r.strftime("%m/%d/%Y") unless r.blank?
|
|
39
|
+
r
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# which view to render this element?
|
|
43
|
+
def ptemplate
|
|
44
|
+
if self.style == 'mmyy'
|
|
45
|
+
'date_field_mmyy'
|
|
46
|
+
else
|
|
47
|
+
'date_field'
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
end
|
|
52
|
+
end
|