decidim-forms 0.21.0 → 0.22.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/config/admin/decidim_forms_manifest.js +1 -0
- data/app/assets/images/decidim/surveys/icon.svg +1 -19
- data/app/assets/javascripts/decidim/forms/admin/collapsible_questions.js.es6 +13 -0
- data/app/assets/javascripts/decidim/forms/admin/forms.js.es6 +95 -7
- data/app/assets/javascripts/decidim/forms/admin/live_text_update.component.js.es6 +52 -0
- data/app/assets/javascripts/decidim/forms/forms.js.es6 +42 -1
- data/app/assets/javascripts/decidim/forms/max_choices_alert.component.js.es6 +44 -0
- data/app/assets/stylesheets/decidim/forms/forms.scss +39 -0
- data/app/cells/decidim/forms/matrix_readonly/show.erb +5 -0
- data/app/cells/decidim/forms/matrix_readonly_cell.rb +12 -0
- data/app/cells/decidim/forms/question_readonly/show.erb +5 -1
- data/app/cells/decidim/forms/question_readonly_cell.rb +5 -0
- data/app/cells/decidim/forms/step_navigation/show.erb +35 -0
- data/app/cells/decidim/forms/step_navigation_cell.rb +46 -0
- data/app/commands/decidim/forms/admin/update_questionnaire.rb +8 -0
- data/app/commands/decidim/forms/answer_questionnaire.rb +2 -1
- data/app/controllers/decidim/forms/admin/concerns/has_questionnaire.rb +6 -2
- data/app/controllers/decidim/forms/concerns/has_questionnaire.rb +11 -2
- data/app/forms/decidim/forms/admin/question_form.rb +20 -1
- data/app/forms/decidim/forms/admin/question_matrix_row_form.rb +26 -0
- data/app/forms/decidim/forms/answer_choice_form.rb +1 -0
- data/app/forms/decidim/forms/answer_form.rb +16 -2
- data/app/forms/decidim/forms/questionnaire_form.rb +25 -3
- data/app/helpers/decidim/forms/admin/application_helper.rb +16 -0
- data/app/models/decidim/forms/answer_choice.rb +7 -0
- data/app/models/decidim/forms/question.rb +18 -2
- data/app/models/decidim/forms/question_matrix_row.rb +12 -0
- data/app/views/decidim/forms/admin/questionnaires/_answer_option_template.html.erb +1 -1
- data/app/views/decidim/forms/admin/questionnaires/_form.html.erb +37 -4
- data/app/views/decidim/forms/admin/questionnaires/_matrix_row.html.erb +34 -0
- data/app/views/decidim/forms/admin/questionnaires/_matrix_row_template.html.erb +7 -0
- data/app/views/decidim/forms/admin/questionnaires/_question.html.erb +29 -6
- data/app/views/decidim/forms/admin/questionnaires/_separator.html.erb +41 -0
- data/app/views/decidim/forms/questionnaires/_answer.html.erb +21 -92
- data/app/views/decidim/forms/questionnaires/answers/_long_answer.html.erb +1 -0
- data/app/views/decidim/forms/questionnaires/answers/_matrix_multiple.html.erb +43 -0
- data/app/views/decidim/forms/questionnaires/answers/_matrix_single.html.erb +43 -0
- data/app/views/decidim/forms/questionnaires/answers/_multiple_option.html.erb +23 -0
- data/app/views/decidim/forms/questionnaires/answers/_separator.html.erb +1 -0
- data/app/views/decidim/forms/questionnaires/answers/_short_answer.html.erb +1 -0
- data/app/views/decidim/forms/questionnaires/answers/_single_option.html.erb +30 -0
- data/app/views/decidim/forms/questionnaires/answers/_sorting.html.erb +23 -0
- data/app/views/decidim/forms/questionnaires/show.html.erb +57 -25
- data/config/locales/ar.yml +7 -3
- data/config/locales/bg-BG.yml +16 -0
- data/config/locales/ca.yml +35 -3
- data/config/locales/cs.yml +35 -3
- data/config/locales/da-DK.yml +1 -0
- data/config/locales/de.yml +41 -3
- data/config/locales/el.yml +119 -0
- data/config/locales/en.yml +35 -3
- data/config/locales/es-MX.yml +35 -3
- data/config/locales/es-PY.yml +35 -3
- data/config/locales/es.yml +35 -3
- data/config/locales/et-EE.yml +1 -0
- data/config/locales/eu.yml +7 -3
- data/config/locales/fi-plain.yml +35 -3
- data/config/locales/fi.yml +36 -4
- data/config/locales/fr-CA.yml +120 -0
- data/config/locales/fr.yml +36 -4
- data/config/locales/ga-IE.yml +1 -0
- data/config/locales/gl.yml +7 -3
- data/config/locales/hr-HR.yml +1 -0
- data/config/locales/hu.yml +11 -3
- data/config/locales/id-ID.yml +7 -3
- data/config/locales/it.yml +36 -4
- data/config/locales/ja-JP.yml +120 -0
- data/config/locales/lt-LT.yml +1 -0
- data/config/locales/lv-LV.yml +119 -0
- data/config/locales/mt-MT.yml +1 -0
- data/config/locales/nl.yml +35 -3
- data/config/locales/no.yml +7 -3
- data/config/locales/pl.yml +63 -25
- data/config/locales/pt-BR.yml +8 -4
- data/config/locales/pt.yml +62 -24
- data/config/locales/ro-RO.yml +118 -0
- data/config/locales/ru.yml +4 -1
- data/config/locales/sk-SK.yml +88 -0
- data/config/locales/sk.yml +92 -0
- data/config/locales/sl.yml +5 -0
- data/config/locales/sr-CS.yml +1 -0
- data/config/locales/sv.yml +38 -6
- data/config/locales/tr-TR.yml +7 -3
- data/db/migrate/20200225123810_create_decidim_forms_question_matrix_rows.rb +11 -0
- data/db/migrate/20200304152939_add_matrix_row_id_to_decidim_forms_answer_choices.rb +11 -0
- data/lib/decidim/forms/test/factories.rb +20 -0
- data/lib/decidim/forms/test/shared_examples/has_questionnaire.rb +313 -36
- data/lib/decidim/forms/test/shared_examples/manage_questionnaires.rb +346 -15
- data/lib/decidim/forms/user_answers_serializer.rb +21 -4
- data/lib/decidim/forms/version.rb +1 -1
- metadata +45 -8
@@ -9,7 +9,11 @@
|
|
9
9
|
|
10
10
|
<% if model.multiple_choice? %>
|
11
11
|
<ul class="questionnaire-question_readonly-answers <%= model.question_type %>">
|
12
|
-
|
12
|
+
<% if model.matrix? %>
|
13
|
+
<%= cell("decidim/forms/matrix_readonly", collection: model.matrix_rows) %>
|
14
|
+
<% else %>
|
15
|
+
<%= cell("decidim/forms/answer_readonly", collection: model.answer_options) %>
|
16
|
+
<% end %>
|
13
17
|
</ul>
|
14
18
|
<% end %>
|
15
19
|
</li>
|
@@ -0,0 +1,35 @@
|
|
1
|
+
<div class="button--double form-general-submit answer-questionnaire__submit">
|
2
|
+
<% if first_step? %>
|
3
|
+
<a></a>
|
4
|
+
<% else %>
|
5
|
+
<%= link_to(
|
6
|
+
icon("caret-left", class: "icon--small", role: "img") + " " + t("decidim.forms.step_navigation.show.back"),
|
7
|
+
"#",
|
8
|
+
class: "hollow secondary",
|
9
|
+
data: {
|
10
|
+
toggle: [previous_step_dom_id, current_step_dom_id].join(" ")
|
11
|
+
}
|
12
|
+
) %>
|
13
|
+
<% end %>
|
14
|
+
|
15
|
+
<% if last_step? %>
|
16
|
+
<%= form.submit(
|
17
|
+
t("decidim.forms.step_navigation.show.submit"),
|
18
|
+
class: "button button--sc",
|
19
|
+
disabled: button_disabled?,
|
20
|
+
data: {
|
21
|
+
confirm: t("decidim.forms.step_navigation.show.are_you_sure"),
|
22
|
+
disable: true
|
23
|
+
}
|
24
|
+
) %>
|
25
|
+
<% else %>
|
26
|
+
<%= link_to(
|
27
|
+
t("decidim.forms.step_navigation.show.continue"),
|
28
|
+
"#",
|
29
|
+
class: "button button--sc",
|
30
|
+
data: {
|
31
|
+
toggle: [next_step_dom_id, current_step_dom_id].join(" ")
|
32
|
+
}
|
33
|
+
) %>
|
34
|
+
<% end %>
|
35
|
+
</div>
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Forms
|
5
|
+
# This cell renders the navigation of a questionnaire step.
|
6
|
+
class StepNavigationCell < Decidim::ViewModel
|
7
|
+
include Decidim::LayoutHelper
|
8
|
+
|
9
|
+
def current_step_index
|
10
|
+
model
|
11
|
+
end
|
12
|
+
|
13
|
+
def first_step?
|
14
|
+
current_step_index.zero?
|
15
|
+
end
|
16
|
+
|
17
|
+
def last_step?
|
18
|
+
current_step_index + 1 == total_steps
|
19
|
+
end
|
20
|
+
|
21
|
+
def total_steps
|
22
|
+
options[:total_steps]
|
23
|
+
end
|
24
|
+
|
25
|
+
def form
|
26
|
+
options[:form]
|
27
|
+
end
|
28
|
+
|
29
|
+
def button_disabled?
|
30
|
+
options[:button_disabled]
|
31
|
+
end
|
32
|
+
|
33
|
+
def previous_step_dom_id
|
34
|
+
"step-#{current_step_index - 1}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def next_step_dom_id
|
38
|
+
"step-#{current_step_index + 1}"
|
39
|
+
end
|
40
|
+
|
41
|
+
def current_step_dom_id
|
42
|
+
"step-#{current_step_index}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -56,6 +56,14 @@ module Decidim
|
|
56
56
|
|
57
57
|
update_nested_model(form_answer_option, answer_option_attributes, question.answer_options)
|
58
58
|
end
|
59
|
+
|
60
|
+
form_question.matrix_rows.each do |form_matrix_row|
|
61
|
+
matrix_row_attributes = {
|
62
|
+
body: form_matrix_row.body
|
63
|
+
}
|
64
|
+
|
65
|
+
update_nested_model(form_matrix_row, matrix_row_attributes, question.matrix_rows)
|
66
|
+
end
|
59
67
|
end
|
60
68
|
end
|
61
69
|
|
@@ -30,7 +30,7 @@ module Decidim
|
|
30
30
|
|
31
31
|
def answer_questionnaire
|
32
32
|
Answer.transaction do
|
33
|
-
form.
|
33
|
+
form.responses_by_step.flatten.each do |form_answer|
|
34
34
|
answer = Answer.new(
|
35
35
|
user: @current_user,
|
36
36
|
questionnaire: @questionnaire,
|
@@ -45,6 +45,7 @@ module Decidim
|
|
45
45
|
body: choice.body,
|
46
46
|
custom_body: choice.custom_body,
|
47
47
|
decidim_answer_option_id: choice.answer_option_id,
|
48
|
+
decidim_question_matrix_row_id: choice.matrix_row_id,
|
48
49
|
position: choice.position
|
49
50
|
)
|
50
51
|
end
|
@@ -15,7 +15,7 @@ module Decidim
|
|
15
15
|
|
16
16
|
included do
|
17
17
|
helper Decidim::Forms::Admin::ApplicationHelper
|
18
|
-
helper_method :questionnaire_for, :questionnaire, :blank_question, :blank_answer_option, :question_types, :update_url
|
18
|
+
helper_method :questionnaire_for, :questionnaire, :blank_question, :blank_answer_option, :blank_matrix_row, :question_types, :update_url
|
19
19
|
|
20
20
|
def edit
|
21
21
|
enforce_permission_to :update, :questionnaire, questionnaire: questionnaire
|
@@ -82,8 +82,12 @@ module Decidim
|
|
82
82
|
@blank_answer_option ||= Admin::AnswerOptionForm.new
|
83
83
|
end
|
84
84
|
|
85
|
+
def blank_matrix_row
|
86
|
+
@blank_matrix_row ||= Admin::QuestionMatrixRowForm.new
|
87
|
+
end
|
88
|
+
|
85
89
|
def question_types
|
86
|
-
@question_types ||= Question::
|
90
|
+
@question_types ||= Question::QUESTION_TYPES.map do |question_type|
|
87
91
|
[question_type, I18n.t("decidim.forms.question_types.#{question_type}")]
|
88
92
|
end
|
89
93
|
end
|
@@ -16,7 +16,7 @@ module Decidim
|
|
16
16
|
helper Decidim::Forms::ApplicationHelper
|
17
17
|
include FormFactory
|
18
18
|
|
19
|
-
helper_method :questionnaire_for, :questionnaire, :allow_answers?, :visitor_can_answer?, :visitor_already_answered?, :update_url
|
19
|
+
helper_method :questionnaire_for, :questionnaire, :allow_answers?, :visitor_can_answer?, :visitor_already_answered?, :update_url, :form_path
|
20
20
|
|
21
21
|
invisible_captcha on_spam: :spam_detected
|
22
22
|
|
@@ -28,7 +28,7 @@ module Decidim
|
|
28
28
|
def answer
|
29
29
|
enforce_permission_to :answer, :questionnaire
|
30
30
|
|
31
|
-
@form = form(Decidim::Forms::QuestionnaireForm).from_params(params, session_token: session_token)
|
31
|
+
@form = form(Decidim::Forms::QuestionnaireForm).from_params(params, session_token: session_token, ip_hash: ip_hash)
|
32
32
|
|
33
33
|
Decidim::Forms::AnswerQuestionnaire.call(@form, current_user, questionnaire) do
|
34
34
|
on(:ok) do
|
@@ -81,6 +81,15 @@ module Decidim
|
|
81
81
|
url_for([questionnaire_for, action: :answer])
|
82
82
|
end
|
83
83
|
|
84
|
+
# Points to the shortest path accessing the current form. This will be
|
85
|
+
# used to detect whether a user is leaving the form with some partial
|
86
|
+
# answers, so that we can warn them.
|
87
|
+
#
|
88
|
+
# Overwrite this method at the controller.
|
89
|
+
def form_path
|
90
|
+
url_for([questionnaire_for, only_path: true])
|
91
|
+
end
|
92
|
+
|
84
93
|
# Public: Method to be implemented at the controller. You need to
|
85
94
|
# return the object that will hold the questionnaire.
|
86
95
|
def questionnaire_for
|
@@ -11,6 +11,7 @@ module Decidim
|
|
11
11
|
attribute :mandatory, Boolean, default: false
|
12
12
|
attribute :question_type, String
|
13
13
|
attribute :answer_options, Array[AnswerOptionForm]
|
14
|
+
attribute :matrix_rows, Array[QuestionMatrixRowForm]
|
14
15
|
attribute :max_choices, Integer
|
15
16
|
attribute :deleted, Boolean, default: false
|
16
17
|
|
@@ -20,7 +21,9 @@ module Decidim
|
|
20
21
|
validates :position, numericality: { greater_than_or_equal_to: 0 }
|
21
22
|
validates :question_type, inclusion: { in: Decidim::Forms::Question::TYPES }
|
22
23
|
validates :max_choices, numericality: { only_integer: true, greater_than: 1, less_than_or_equal_to: ->(form) { form.number_of_options } }, allow_blank: true
|
23
|
-
validates :body, translatable_presence: true,
|
24
|
+
validates :body, translatable_presence: true, if: :requires_body?
|
25
|
+
validates :matrix_rows, presence: true, if: :matrix?
|
26
|
+
validates :answer_options, presence: true, if: :matrix?
|
24
27
|
|
25
28
|
def to_param
|
26
29
|
return id if id.present?
|
@@ -31,6 +34,22 @@ module Decidim
|
|
31
34
|
def number_of_options
|
32
35
|
answer_options.size
|
33
36
|
end
|
37
|
+
|
38
|
+
def separator?
|
39
|
+
question_type == Decidim::Forms::Question::SEPARATOR_TYPE
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def matrix?
|
45
|
+
question_type == "matrix_single" || question_type == "matrix_multiple"
|
46
|
+
end
|
47
|
+
|
48
|
+
def requires_body?
|
49
|
+
return false if separator?
|
50
|
+
|
51
|
+
!deleted
|
52
|
+
end
|
34
53
|
end
|
35
54
|
end
|
36
55
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Forms
|
5
|
+
module Admin
|
6
|
+
# This class holds a Form to update questionnaire question matrixes from Decidim's admin panel.
|
7
|
+
class QuestionMatrixRowForm < Decidim::Form
|
8
|
+
include TranslatableAttributes
|
9
|
+
|
10
|
+
attribute :position, Integer, default: 0
|
11
|
+
attribute :deleted, Boolean, default: false
|
12
|
+
|
13
|
+
translatable_attribute :body, String
|
14
|
+
|
15
|
+
validates :position, numericality: { greater_than_or_equal_to: 0 }
|
16
|
+
validates :body, translatable_presence: true, unless: :deleted
|
17
|
+
|
18
|
+
def to_param
|
19
|
+
return id if id.present?
|
20
|
+
|
21
|
+
"questionnaire-question-matrix-row-id"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -9,14 +9,16 @@ module Decidim
|
|
9
9
|
attribute :question_id, String
|
10
10
|
attribute :body, String
|
11
11
|
attribute :choices, Array[AnswerChoiceForm]
|
12
|
+
attribute :matrix_choices, Array[AnswerChoiceForm]
|
12
13
|
|
13
14
|
validates :body, presence: true, if: :mandatory_body?
|
14
15
|
validates :selected_choices, presence: true, if: :mandatory_choices?
|
15
16
|
|
16
17
|
validate :max_choices, if: -> { question.max_choices }
|
17
18
|
validate :all_choices, if: -> { question.question_type == "sorting" }
|
19
|
+
validate :min_choices, if: -> { question.matrix? && question.mandatory? }
|
18
20
|
|
19
|
-
delegate :mandatory_body?, :mandatory_choices?, to: :question
|
21
|
+
delegate :mandatory_body?, :mandatory_choices?, :matrix?, to: :question
|
20
22
|
|
21
23
|
attr_writer :question
|
22
24
|
|
@@ -49,8 +51,20 @@ module Decidim
|
|
49
51
|
|
50
52
|
private
|
51
53
|
|
54
|
+
def grouped_choices
|
55
|
+
selected_choices.group_by(&:matrix_row_id).values
|
56
|
+
end
|
57
|
+
|
52
58
|
def max_choices
|
53
|
-
|
59
|
+
if matrix?
|
60
|
+
errors.add(:choices, :too_many) if grouped_choices.any? { |choices| choices.count > question.max_choices }
|
61
|
+
elsif selected_choices.size > question.max_choices
|
62
|
+
errors.add(:choices, :too_many)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def min_choices
|
67
|
+
errors.add(:choices, :missing) if grouped_choices.count != question.matrix_rows.count
|
54
68
|
end
|
55
69
|
|
56
70
|
def all_choices
|
@@ -4,7 +4,9 @@ module Decidim
|
|
4
4
|
module Forms
|
5
5
|
# This class holds a Form to answer a questionnaire from Decidim's public page.
|
6
6
|
class QuestionnaireForm < Decidim::Form
|
7
|
-
|
7
|
+
# as questionnaire uses "answers" for the database relationships is
|
8
|
+
# important not to use the same word here to avoid querying all the entries, resulting in a high performance penalty
|
9
|
+
attribute :responses, Array[AnswerForm]
|
8
10
|
attribute :user_group_id, Integer
|
9
11
|
|
10
12
|
attribute :tos_agreement, Boolean
|
@@ -12,15 +14,35 @@ module Decidim
|
|
12
14
|
validates :tos_agreement, allow_nil: false, acceptance: true
|
13
15
|
validate :session_token_in_context
|
14
16
|
|
15
|
-
# Private: Create the
|
17
|
+
# Private: Create the responses from the questionnaire questions
|
16
18
|
#
|
17
19
|
# Returns nothing.
|
18
20
|
def map_model(model)
|
19
|
-
self.
|
21
|
+
self.responses = model.questions.map do |question|
|
20
22
|
AnswerForm.from_model(Decidim::Forms::Answer.new(question: question))
|
21
23
|
end
|
22
24
|
end
|
23
25
|
|
26
|
+
# Public: Splits reponses by step, keeping the separator.
|
27
|
+
#
|
28
|
+
# Returns an array of steps. Each step is a list of the questions in that
|
29
|
+
# step, including the separator.
|
30
|
+
def responses_by_step
|
31
|
+
@responses_by_step ||=
|
32
|
+
begin
|
33
|
+
steps = responses.chunk_while do |a, b|
|
34
|
+
!a.question.separator? || b.question.separator?
|
35
|
+
end.to_a
|
36
|
+
|
37
|
+
steps = [[]] if steps == []
|
38
|
+
steps
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def total_steps
|
43
|
+
responses_by_step.count
|
44
|
+
end
|
45
|
+
|
24
46
|
def session_token_in_context
|
25
47
|
return if context&.session_token
|
26
48
|
|
@@ -13,6 +13,22 @@ module Decidim
|
|
13
13
|
def tabs_id_for_question_answer_option(question, answer_option)
|
14
14
|
"questionnaire_question_#{question.to_param}_answer_option_#{answer_option.to_param}"
|
15
15
|
end
|
16
|
+
|
17
|
+
def tabs_id_for_question_matrix_row(question, matrix_row)
|
18
|
+
"questionnaire_question_#{question.to_param}_matrix_row_#{matrix_row.to_param}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def dynamic_title(title, **options)
|
22
|
+
data = {
|
23
|
+
"max-length" => options[:max_length],
|
24
|
+
"omission" => options[:omission],
|
25
|
+
"placeholder" => options[:placeholder],
|
26
|
+
"locale" => I18n.locale
|
27
|
+
}
|
28
|
+
content_tag :span, class: options[:class], data: data do
|
29
|
+
truncate translated_attribute(title), length: options[:max_length], omission: options[:omission]
|
30
|
+
end
|
31
|
+
end
|
16
32
|
end
|
17
33
|
end
|
18
34
|
end
|
@@ -10,6 +10,13 @@ module Decidim
|
|
10
10
|
belongs_to :answer_option,
|
11
11
|
class_name: "AnswerOption",
|
12
12
|
foreign_key: "decidim_answer_option_id"
|
13
|
+
|
14
|
+
belongs_to :matrix_row,
|
15
|
+
class_name: "QuestionMatrixRow",
|
16
|
+
foreign_key: "decidim_question_matrix_row_id",
|
17
|
+
optional: true
|
18
|
+
|
19
|
+
validates :matrix_row, presence: true, if: -> { answer.question.matrix? }
|
13
20
|
end
|
14
21
|
end
|
15
22
|
end
|
@@ -4,10 +4,18 @@ module Decidim
|
|
4
4
|
module Forms
|
5
5
|
# The data store for a Question in the Decidim::Forms component.
|
6
6
|
class Question < Forms::ApplicationRecord
|
7
|
-
|
7
|
+
QUESTION_TYPES = %w(short_answer long_answer single_option multiple_option sorting matrix_single matrix_multiple).freeze
|
8
|
+
SEPARATOR_TYPE = "separator"
|
9
|
+
TYPES = (QUESTION_TYPES + [SEPARATOR_TYPE]).freeze
|
8
10
|
|
9
11
|
belongs_to :questionnaire, class_name: "Questionnaire", foreign_key: "decidim_questionnaire_id"
|
10
12
|
|
13
|
+
has_many :matrix_rows,
|
14
|
+
class_name: "QuestionMatrixRow",
|
15
|
+
foreign_key: "decidim_question_id",
|
16
|
+
dependent: :destroy,
|
17
|
+
inverse_of: :question
|
18
|
+
|
11
19
|
has_many :answer_options,
|
12
20
|
class_name: "AnswerOption",
|
13
21
|
foreign_key: "decidim_question_id",
|
@@ -16,8 +24,12 @@ module Decidim
|
|
16
24
|
|
17
25
|
validates :question_type, inclusion: { in: TYPES }
|
18
26
|
|
27
|
+
def matrix?
|
28
|
+
%w(matrix_single matrix_multiple).include?(question_type)
|
29
|
+
end
|
30
|
+
|
19
31
|
def multiple_choice?
|
20
|
-
%w(single_option multiple_option sorting).include?(question_type)
|
32
|
+
%w(single_option multiple_option sorting matrix_single matrix_multiple).include?(question_type)
|
21
33
|
end
|
22
34
|
|
23
35
|
def mandatory_body?
|
@@ -31,6 +43,10 @@ module Decidim
|
|
31
43
|
def number_of_options
|
32
44
|
answer_options.size
|
33
45
|
end
|
46
|
+
|
47
|
+
def separator?
|
48
|
+
question_type.to_s == SEPARATOR_TYPE
|
49
|
+
end
|
34
50
|
end
|
35
51
|
end
|
36
52
|
end
|