decidim-forms 0.19.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/README.md +1 -1
- 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 +7 -2
- data/app/controllers/decidim/forms/admin/concerns/has_questionnaire.rb +6 -2
- data/app/controllers/decidim/forms/concerns/has_questionnaire.rb +58 -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 +33 -3
- data/app/helpers/decidim/forms/admin/application_helper.rb +16 -0
- data/app/models/decidim/forms/answer.rb +2 -2
- 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/models/decidim/forms/questionnaire.rb +2 -1
- data/app/queries/decidim/forms/questionnaire_user_answers.rb +1 -1
- data/app/types/decidim/forms/answer_option_type.rb +14 -0
- data/app/types/decidim/forms/question_type.rb +23 -0
- data/app/types/decidim/forms/questionnaire_type.rb +22 -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 +60 -27
- data/config/locales/ar.yml +12 -3
- data/config/locales/bg-BG.yml +16 -0
- data/config/locales/ca.yml +45 -7
- data/config/locales/cs.yml +41 -3
- data/config/locales/da-DK.yml +1 -0
- data/config/locales/de.yml +41 -3
- data/config/locales/el-GR.yml +1 -0
- data/config/locales/el.yml +120 -0
- data/config/locales/en.yml +41 -3
- data/config/locales/es-MX.yml +41 -3
- data/config/locales/es-PY.yml +41 -3
- data/config/locales/es.yml +41 -3
- data/config/locales/et-EE.yml +1 -0
- data/config/locales/eu.yml +7 -3
- data/config/locales/fi-plain.yml +41 -3
- data/config/locales/fi.yml +42 -4
- data/config/locales/fr-CA.yml +120 -0
- data/config/locales/fr.yml +41 -3
- 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 +18 -4
- data/config/locales/id-ID.yml +7 -3
- data/config/locales/is-IS.yml +1 -0
- data/config/locales/it.yml +42 -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 +41 -3
- data/config/locales/no.yml +86 -1
- 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 +47 -0
- 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 +41 -3
- data/config/locales/tr-TR.yml +7 -3
- data/db/migrate/20190315203056_add_session_token_to_decidim_forms_answers.rb +17 -0
- data/db/migrate/20190930094710_add_ip_hash_to_decidim_form_answers.rb +12 -0
- 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/api/questionnaire_entity_interface.rb +18 -0
- data/lib/decidim/forms.rb +1 -0
- data/lib/decidim/forms/api.rb +7 -0
- data/lib/decidim/forms/test/factories.rb +55 -11
- data/lib/decidim/forms/test/shared_examples/has_questionnaire.rb +320 -43
- data/lib/decidim/forms/test/shared_examples/manage_questionnaires.rb +347 -16
- data/lib/decidim/forms/user_answers_serializer.rb +23 -4
- data/lib/decidim/forms/version.rb +1 -1
- metadata +56 -9
@@ -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
|
@@ -7,7 +7,7 @@ module Decidim
|
|
7
7
|
include Decidim::DataPortability
|
8
8
|
include Decidim::NewsletterParticipant
|
9
9
|
|
10
|
-
belongs_to :user, class_name: "Decidim::User", foreign_key: "decidim_user_id"
|
10
|
+
belongs_to :user, class_name: "Decidim::User", foreign_key: "decidim_user_id", optional: true
|
11
11
|
belongs_to :questionnaire, class_name: "Questionnaire", foreign_key: "decidim_questionnaire_id"
|
12
12
|
belongs_to :question, class_name: "Question", foreign_key: "decidim_question_id"
|
13
13
|
|
@@ -45,7 +45,7 @@ module Decidim
|
|
45
45
|
private
|
46
46
|
|
47
47
|
def user_questionnaire_same_organization
|
48
|
-
return if user&.organization == questionnaire.questionnaire_for&.organization
|
48
|
+
return if user.nil? || user&.organization == questionnaire.questionnaire_for&.organization
|
49
49
|
|
50
50
|
errors.add(:user, :invalid)
|
51
51
|
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
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Forms
|
5
|
+
# The data store for a QuestionMatrix in the Decidim::Forms component.
|
6
|
+
class QuestionMatrixRow < Forms::ApplicationRecord
|
7
|
+
belongs_to :question, class_name: "Question", foreign_key: "decidim_question_id"
|
8
|
+
|
9
|
+
delegate :answer_options, :mandatory, :max_choices, to: :question
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -16,7 +16,8 @@ module Decidim
|
|
16
16
|
|
17
17
|
# Public: returns whether the questionnaire is answered by the user or not.
|
18
18
|
def answered_by?(user)
|
19
|
-
|
19
|
+
query = user.is_a?(String) ? { session_token: user } : { user: user }
|
20
|
+
answers.where(query).any? if questions.present?
|
20
21
|
end
|
21
22
|
end
|
22
23
|
end
|
@@ -21,7 +21,7 @@ module Decidim
|
|
21
21
|
# Finds and group answers by user for each questionnaire's question.
|
22
22
|
def query
|
23
23
|
answers = Answer.where(questionnaire: @questionnaire)
|
24
|
-
answers.sort_by { |answer| answer.question.position }.group_by
|
24
|
+
answers.sort_by { |answer| answer.question.position }.group_by { |a| a.user || a.session_token }.values
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Forms
|
5
|
+
AnswerOptionType = GraphQL::ObjectType.define do
|
6
|
+
name "AnswerOption"
|
7
|
+
description "An answer option for a multi-choice question in a questionnaire"
|
8
|
+
|
9
|
+
field :id, !types.ID, "ID of this answer option"
|
10
|
+
field :body, !Decidim::Core::TranslatedFieldType, "The text answer response option."
|
11
|
+
field :freeText, !types.Boolean, "Whether if this answer accepts any free text from the user.", property: :free_text
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Forms
|
5
|
+
QuestionType = GraphQL::ObjectType.define do
|
6
|
+
name "Question"
|
7
|
+
description "A question in a questionnaire"
|
8
|
+
|
9
|
+
interfaces [
|
10
|
+
-> { Decidim::Core::TimestampsInterface }
|
11
|
+
]
|
12
|
+
|
13
|
+
field :id, !types.ID, "ID of this question"
|
14
|
+
field :body, !Decidim::Core::TranslatedFieldType, "What is being asked in this question."
|
15
|
+
field :description, Decidim::Core::TranslatedFieldType, "The description of this question."
|
16
|
+
field :mandatory, !types.Boolean, "Whether if this question is mandatory."
|
17
|
+
field :position, types.Int, "Order position of the question in the questionnaire"
|
18
|
+
field :maxChoices, types.Int, "On questions with answer options, maximum number of choices the user has", property: :max_choices
|
19
|
+
field :questionType, types.String, "Type of question.", property: :question_type
|
20
|
+
field :answerOptions, !types[AnswerOptionType], "List of answer options in multi-choice questions.", property: :answer_options
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Forms
|
5
|
+
QuestionnaireType = GraphQL::ObjectType.define do
|
6
|
+
name "Questionnaire"
|
7
|
+
description "A questionnaire"
|
8
|
+
|
9
|
+
interfaces [
|
10
|
+
-> { Decidim::Core::TimestampsInterface }
|
11
|
+
]
|
12
|
+
|
13
|
+
field :id, !types.ID, "ID of this questionnaire"
|
14
|
+
field :title, !Decidim::Core::TranslatedFieldType, "The title of this questionnaire."
|
15
|
+
field :description, Decidim::Core::TranslatedFieldType, "The description of this questionnaire."
|
16
|
+
field :tos, Decidim::Core::TranslatedFieldType, "The Terms of Service for this questionnaire."
|
17
|
+
field :forType, types.String, "Type of entity using this questionnaire.", property: :questionnaire_for_type
|
18
|
+
field :forEntity, QuestionnaireEntityInterface, "Entity using this questionnaire.", property: :questionnaire_for
|
19
|
+
field :questions, !types[QuestionType], "Questions in this questionnaire."
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<% question = form.object %>
|
2
2
|
|
3
|
-
<script type="text/template" class="decidim-template" id="<%= template_id %>">
|
3
|
+
<script type="text/template" class="decidim-answer-option-template decidim-template" id="<%= template_id %>">
|
4
4
|
<%= fields_for "questionnaire[questions][#{question.to_param}][answer_options][]", blank_answer_option do |answer_option_form| %>
|
5
5
|
<%= render "decidim/forms/admin/questionnaires/answer_option", form: answer_option_form, question: question, editable: editable %>
|
6
6
|
<% end %>
|
@@ -21,12 +21,29 @@
|
|
21
21
|
</div>
|
22
22
|
|
23
23
|
<div class="questionnaire-questions">
|
24
|
+
<div class="row column text-center">
|
25
|
+
<button type="button" class="button collapse-all"><%= t(".collapse") %></button>
|
26
|
+
<button type="button" class="button expand-all"><%= t(".expand") %></button>
|
27
|
+
</div>
|
28
|
+
|
24
29
|
<% if questionnaire.questions_editable? %>
|
25
30
|
<%= fields_for "questionnaire[questions][#{blank_question.to_param}]", blank_question do |question_form| %>
|
26
|
-
<script type="text/template" class="decidim-template">
|
27
|
-
<%= render "decidim/forms/admin/questionnaires/question",
|
31
|
+
<script type="text/template" class="decidim-question-template decidim-template" id="question-template">
|
32
|
+
<%= render "decidim/forms/admin/questionnaires/question",
|
33
|
+
form: question_form,
|
34
|
+
id: tabs_id_for_question(blank_question),
|
35
|
+
editable: questionnaire.questions_editable?,
|
36
|
+
answer_option_template_selector: "#answer-option-template-dummy",
|
37
|
+
matrix_row_template_selector: "#matrix-row-template-dummy" %>
|
38
|
+
</script>
|
39
|
+
<script type="text/template" class="decidim-separator-template decidim-template" id="separator-template">
|
40
|
+
<%= render "decidim/forms/admin/questionnaires/separator",
|
41
|
+
form: question_form,
|
42
|
+
id: tabs_id_for_question(blank_question),
|
43
|
+
editable: questionnaire.questions_editable? %>
|
28
44
|
</script>
|
29
45
|
<%= render "decidim/forms/admin/questionnaires/answer_option_template", form: question_form, editable: questionnaire.questions_editable?, template_id: "answer-option-template-dummy" %>
|
46
|
+
<%= render "decidim/forms/admin/questionnaires/matrix_row_template", form: question_form, editable: questionnaire.questions_editable?, template_id: "matrix-row-template-dummy" %>
|
30
47
|
<% end %>
|
31
48
|
<% else %>
|
32
49
|
<div class="callout warning">
|
@@ -37,17 +54,33 @@
|
|
37
54
|
<div class="questionnaire-questions-list">
|
38
55
|
<% @form.questions.each_with_index do |question, index| %>
|
39
56
|
<%= fields_for "questionnaire[questions][]", question do |question_form| %>
|
40
|
-
|
41
|
-
|
57
|
+
<% if question.separator? %>
|
58
|
+
<%= render "decidim/forms/admin/questionnaires/separator",
|
59
|
+
form: question_form,
|
60
|
+
id: tabs_id_for_question(question),
|
61
|
+
editable: questionnaire.questions_editable? %>
|
62
|
+
<% else %>
|
63
|
+
<%= render "decidim/forms/admin/questionnaires/question",
|
64
|
+
form: question_form,
|
65
|
+
id: tabs_id_for_question(question),
|
66
|
+
editable: questionnaire.questions_editable?,
|
67
|
+
answer_option_template_selector: "#answer-option-template-#{index}",
|
68
|
+
matrix_row_template_selector: "#matrix-row-template-#{index}" %>
|
69
|
+
<%= render "decidim/forms/admin/questionnaires/answer_option_template", form: question_form, editable: questionnaire.questions_editable?, template_id: "answer-option-template-#{index}" %>
|
70
|
+
<%= render "decidim/forms/admin/questionnaires/matrix_row_template", form: question_form, editable: questionnaire.questions_editable?, template_id: "matrix-row-template-#{index}" %>
|
71
|
+
<% end %>
|
42
72
|
<% end %>
|
43
73
|
<% end %>
|
44
74
|
</div>
|
45
75
|
|
46
76
|
<% if questionnaire.questions_editable? %>
|
47
77
|
<button class="button add-question"><%= t(".add_question") %></button>
|
78
|
+
<button class="button add-separator"><%= t(".add_separator") %></button>
|
48
79
|
<% end %>
|
49
80
|
</div>
|
50
81
|
|
51
82
|
<% if questionnaire.questions_editable? %>
|
52
83
|
<%= javascript_include_tag "decidim/forms/admin/forms" %>
|
53
84
|
<% end %>
|
85
|
+
|
86
|
+
<%= javascript_include_tag "decidim/forms/admin/collapsible_questions" %>
|
@@ -0,0 +1,34 @@
|
|
1
|
+
<% matrix_row = form.object %>
|
2
|
+
|
3
|
+
<div class="card questionnaire-question-matrix-row">
|
4
|
+
<div class="card-divider">
|
5
|
+
<h2 class="card-title">
|
6
|
+
<span><%= t(".matrix_row") %></span>
|
7
|
+
<% if editable %>
|
8
|
+
<button class="button small alert hollow remove-matrix-row button--title">
|
9
|
+
<%= t(".remove") %>
|
10
|
+
</button>
|
11
|
+
<% end %>
|
12
|
+
</h2>
|
13
|
+
</div>
|
14
|
+
|
15
|
+
<div class="card-section">
|
16
|
+
<div class="row column">
|
17
|
+
<%=
|
18
|
+
form.translated(
|
19
|
+
:text_field,
|
20
|
+
:body,
|
21
|
+
tabs_id: tabs_id_for_question_matrix_row(question, matrix_row),
|
22
|
+
label: t(".statement"),
|
23
|
+
disabled: !editable
|
24
|
+
)
|
25
|
+
%>
|
26
|
+
</div>
|
27
|
+
</div>
|
28
|
+
|
29
|
+
<% if matrix_row.persisted? %>
|
30
|
+
<%= form.hidden_field :id, disabled: !editable %>
|
31
|
+
<% end %>
|
32
|
+
|
33
|
+
<%= form.hidden_field :deleted, disabled: !editable %>
|
34
|
+
</div>
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<% question = form.object %>
|
2
|
+
|
3
|
+
<script type="text/template" class="decidim-matrix-row-template decidim-template" id="<%= template_id %>">
|
4
|
+
<%= fields_for "questionnaire[questions][#{question.to_param}][matrix_rows][]", blank_matrix_row do |matrix_row_form| %>
|
5
|
+
<%= render "decidim/forms/admin/questionnaires/matrix_row", form: matrix_row_form, question: question, editable: editable %>
|
6
|
+
<% end %>
|
7
|
+
</script>
|
@@ -5,12 +5,21 @@
|
|
5
5
|
<h2 class="card-title">
|
6
6
|
<span>
|
7
7
|
<% if editable %>
|
8
|
-
<%==
|
9
|
-
<% else %>
|
10
|
-
<%= t(".question") %>
|
8
|
+
<%== icon("move") %>
|
11
9
|
<% end %>
|
10
|
+
<%= dynamic_title(translated_attribute(question.body), class: "question-title-statement", max_length: 50, omission: "...", placeholder: t(".question")) %>
|
12
11
|
</span>
|
13
12
|
|
13
|
+
<button type="button" class="button small secondary button--title question--collapse" data-toggle="<%= id %>-question-card button--collapse-question-<%= id %> button--expand-question-<%= id %>">
|
14
|
+
<span id="button--collapse-question-<%= id %>" data-toggler=".hide" class="icon-collapse hide">
|
15
|
+
<%== icon("caret-top", aria_label: t(".collapse"), role: "img") %>
|
16
|
+
</span>
|
17
|
+
|
18
|
+
<span id="button--expand-question-<%= id %>" data-toggler=".hide" class="icon-expand">
|
19
|
+
<%== icon("caret-bottom", aria_label: t(".expand"), role: "img") %>
|
20
|
+
</span>
|
21
|
+
</button>
|
22
|
+
|
14
23
|
<% if editable %>
|
15
24
|
<button class="button small alert hollow move-up-question button--title">
|
16
25
|
<%== "#{icon("arrow-top")} #{t(".up")}" %>
|
@@ -27,7 +36,7 @@
|
|
27
36
|
</h2>
|
28
37
|
</div>
|
29
38
|
|
30
|
-
<div class="card-section">
|
39
|
+
<div class="card-section collapsible hide" data-toggler=".hide" id="<%= id %>-question-card">
|
31
40
|
<div class="row column">
|
32
41
|
<%=
|
33
42
|
form.translated(
|
@@ -81,7 +90,21 @@
|
|
81
90
|
<%= form.hidden_field :position, value: question.position || 0, disabled: !editable %>
|
82
91
|
<%= form.hidden_field :deleted, disabled: !editable %>
|
83
92
|
|
84
|
-
<div class="questionnaire-question-
|
93
|
+
<div class="questionnaire-question-matrix-rows" data-template="<%= matrix_row_template_selector %>">
|
94
|
+
<div class="questionnaire-question-matrix-rows-list">
|
95
|
+
<% question.matrix_rows.each do |matrix_row| %>
|
96
|
+
<%= fields_for "questionnaire[questions][#{question.to_param}][matrix_rows][]", matrix_row do |matrix_row_form| %>
|
97
|
+
<%= render "decidim/forms/admin/questionnaires/matrix_row", form: matrix_row_form, question: question, editable: editable %>
|
98
|
+
<% end %>
|
99
|
+
<% end %>
|
100
|
+
</div>
|
101
|
+
|
102
|
+
<% if editable %>
|
103
|
+
<button class="button add-matrix-row"><%= t(".add_matrix_row") %></button>
|
104
|
+
<% end %>
|
105
|
+
</div>
|
106
|
+
|
107
|
+
<div class="questionnaire-question-answer-options" data-template="<%= answer_option_template_selector %>">
|
85
108
|
<div class="questionnaire-question-answer-options-list">
|
86
109
|
<% question.answer_options.each do |answer_option| %>
|
87
110
|
<%= fields_for "questionnaire[questions][#{question.to_param}][answer_options][]", answer_option do |answer_option_form| %>
|
@@ -100,7 +123,7 @@
|
|
100
123
|
form.select(
|
101
124
|
:max_choices,
|
102
125
|
(2..question.number_of_options),
|
103
|
-
{
|
126
|
+
{ include_blank: t(".any") },
|
104
127
|
disabled: !editable
|
105
128
|
)
|
106
129
|
%>
|
@@ -0,0 +1,41 @@
|
|
1
|
+
<% question = form.object %>
|
2
|
+
|
3
|
+
<div class="card questionnaire-question" id="<%= id %>-field">
|
4
|
+
<div class="card-divider question-divider">
|
5
|
+
<h2 class="card-title">
|
6
|
+
<span>
|
7
|
+
<% if editable %>
|
8
|
+
<%== icon("move") %>
|
9
|
+
<% end %>
|
10
|
+
<%= dynamic_title(t(".separator"), class: "question-title-statement", max_length: 50, omission: "...", placeholder: t(".separator")) %>
|
11
|
+
</span>
|
12
|
+
|
13
|
+
<% if editable %>
|
14
|
+
<button class="button small alert hollow move-up-question button--title">
|
15
|
+
<%== "#{icon("arrow-top")} #{t(".up")}" %>
|
16
|
+
</button>
|
17
|
+
|
18
|
+
<button class="button small alert hollow move-down-question button--title">
|
19
|
+
<%== "#{icon("arrow-bottom")} #{t(".down")}" %>
|
20
|
+
</button>
|
21
|
+
|
22
|
+
<button class="button small alert hollow remove-question button--title">
|
23
|
+
<%= t(".remove") %>
|
24
|
+
</button>
|
25
|
+
<% end %>
|
26
|
+
</h2>
|
27
|
+
|
28
|
+
<%=
|
29
|
+
form.hidden_field(
|
30
|
+
:question_type,
|
31
|
+
value: :separator
|
32
|
+
)
|
33
|
+
%>
|
34
|
+
<% if question.persisted? %>
|
35
|
+
<%= form.hidden_field :id, disabled: !editable %>
|
36
|
+
<% end %>
|
37
|
+
|
38
|
+
<%= form.hidden_field :position, value: question.position || 0, disabled: !editable %>
|
39
|
+
<%= form.hidden_field :deleted, disabled: !editable %>
|
40
|
+
</div>
|
41
|
+
</div>
|
@@ -1,100 +1,29 @@
|
|
1
1
|
<% field_id = "questionnaire_answers_#{answer_idx}" %>
|
2
|
-
<%= label_tag field_id, answer.label(answer_idx), class: "questionnaire-question" %>
|
3
2
|
|
4
|
-
<% if
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
<%
|
9
|
-
|
10
|
-
|
11
|
-
<%
|
12
|
-
|
13
|
-
<%
|
14
|
-
<%= answer_form.text_area :body, label: false, id: field_id, rows: 10, disabled: disabled %>
|
15
|
-
<% when "single_option" %>
|
16
|
-
<div class="radio-button-collection">
|
17
|
-
<% choice = answer.choices.first %>
|
18
|
-
|
19
|
-
<% answer.question.answer_options.each_with_index do |answer_option, idx| %>
|
20
|
-
<% choice_id = "#{field_id}_choices_#{idx}" %>
|
21
|
-
|
22
|
-
<div class="collection-input">
|
23
|
-
<%= label_tag "#{choice_id}_body" do %>
|
24
|
-
<%= radio_button_tag "questionnaire[answers][#{answer_idx}][choices][][body]",
|
25
|
-
translated_attribute(answer_option.body),
|
26
|
-
answer_option.id == choice.try(:answer_option_id),
|
27
|
-
id: "#{choice_id}_body", disabled: disabled %>
|
28
|
-
|
29
|
-
<%= translated_attribute(answer_option.body) %>
|
30
|
-
|
31
|
-
<%= hidden_field_tag "questionnaire[answers][#{answer_idx}][choices][][answer_option_id]",
|
32
|
-
answer_option.id,
|
33
|
-
id: "#{choice_id}_answer_option",
|
34
|
-
disabled: true %>
|
35
|
-
<% end %>
|
36
|
-
|
37
|
-
<% if answer_option.free_text %>
|
38
|
-
<%= text_field_tag "questionnaire[answers][#{answer_idx}][choices][][custom_body]",
|
39
|
-
choice.try(:custom_body),
|
40
|
-
id: "#{choice_id}_custom_body",
|
41
|
-
disabled: true %>
|
42
|
-
<% end %>
|
43
|
-
</div>
|
44
|
-
<% end %>
|
45
|
-
</div>
|
46
|
-
<% when "multiple_option" %>
|
47
|
-
<div class="check-box-collection">
|
48
|
-
<% answer.question.answer_options.each_with_index do |answer_option, idx| %>
|
49
|
-
<% choice = answer.selected_choices.find { |choice| choice.answer_option_id == answer_option.id } %>
|
3
|
+
<% if answer.question.separator? %>
|
4
|
+
<%= render partial: "decidim/forms/questionnaires/answers/#{answer.question.question_type}", locals: { answer: answer, answer_form: answer_form, answer_idx: answer_idx, field_id: field_id, disabled: disabled } %>
|
5
|
+
<%= answer_form.hidden_field :question_id %>
|
6
|
+
<% else %>
|
7
|
+
<% case answer.question.question_type %>
|
8
|
+
<% when "single_option", "multiple_option", "sorting" %>
|
9
|
+
<label class="questionnaire-question"><%= answer.label(cleaned_answer_idx) %></label>
|
10
|
+
<% else %>
|
11
|
+
<%= label_tag field_id, answer.label(cleaned_answer_idx), class: "questionnaire-question" %>
|
12
|
+
<% end %>
|
50
13
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
14
|
+
<% if translated_attribute(answer.question.description).present? %>
|
15
|
+
<div class="help-text">
|
16
|
+
<%= decidim_sanitize translated_attribute(answer.question.description) %>
|
17
|
+
</div>
|
18
|
+
<% end %>
|
56
19
|
|
57
|
-
|
20
|
+
<%= render partial: "decidim/forms/questionnaires/answers/#{answer.question.question_type}", locals: { answer: answer, answer_form: answer_form, answer_idx: answer_idx, field_id: field_id, disabled: disabled } %>
|
58
21
|
|
59
|
-
|
60
|
-
<% end %>
|
61
|
-
|
62
|
-
<% if answer_option.free_text %>
|
63
|
-
<%= text_field_tag "questionnaire[answers][#{answer_idx}][choices][#{idx}][custom_body]",
|
64
|
-
choice.try(:custom_body),
|
65
|
-
disabled: true %>
|
66
|
-
<% end %>
|
67
|
-
</div>
|
68
|
-
<% end %>
|
69
|
-
</div>
|
70
|
-
<% when "sorting" %>
|
71
|
-
<div class="sortable-check-box-collection">
|
72
|
-
<% answer.question.answer_options.each_with_index do |answer_option, idx| %>
|
73
|
-
<% choice = answer.selected_choices.find { |choice| choice.answer_option_id == answer_option.id } %>
|
74
|
-
|
75
|
-
<div class="collection-input">
|
76
|
-
<%= label_tag do %>
|
77
|
-
<%= check_box_tag "questionnaire[answers][#{answer_idx}][choices][#{idx}][body]",
|
78
|
-
translated_attribute(answer_option.body),
|
79
|
-
choice.present?, disabled: disabled %>
|
80
|
-
|
81
|
-
<span class="position"><%= choice.try(:position) %></span>
|
82
|
-
|
83
|
-
<%= translated_attribute(answer_option.body) %>
|
84
|
-
|
85
|
-
<%= hidden_field_tag "questionnaire[answers][#{answer_idx}][choices][#{idx}][position]",
|
86
|
-
choice.try(:position),
|
87
|
-
disabled: true %>
|
88
|
-
|
89
|
-
<%= hidden_field_tag "questionnaire[answers][#{answer_idx}][choices][#{idx}][answer_option_id]", answer_option.id %>
|
90
|
-
<% end %>
|
91
|
-
</div>
|
92
|
-
<% end %>
|
93
|
-
</div>
|
94
|
-
<% end %>
|
22
|
+
<%= answer_form.hidden_field :question_id %>
|
95
23
|
|
96
|
-
|
24
|
+
<small class="form-error max-choices-alert"><%= t(".max_choices_alert") %></small>
|
97
25
|
|
98
|
-
<% answer.errors.full_messages.each do |msg| %>
|
99
|
-
|
26
|
+
<% answer.errors.full_messages.each do |msg| %>
|
27
|
+
<small class="form-error is-visible"><%= msg %></small>
|
28
|
+
<% end %>
|
100
29
|
<% end %>
|