decidim-forms 0.22.0 → 0.23.3
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.css +3 -0
- data/app/assets/config/decidim_forms_manifest.css +1 -0
- data/app/assets/javascripts/decidim/forms/admin/auto_select_options_from_url.component.js.es6 +40 -0
- data/app/assets/javascripts/decidim/forms/admin/forms.js.es6 +181 -25
- data/app/assets/javascripts/decidim/forms/autosortable_checkboxes.component.js.es6 +54 -34
- data/app/assets/javascripts/decidim/forms/display_conditions.component.js.es6 +203 -0
- data/app/assets/javascripts/decidim/forms/forms.js.es6 +8 -1
- data/app/assets/stylesheets/decidim/forms/questionnaire-answers-pdf.scss +69 -0
- data/app/commands/decidim/forms/admin/update_questionnaire.rb +25 -1
- data/app/commands/decidim/forms/answer_questionnaire.rb +1 -1
- data/app/controllers/decidim/forms/admin/concerns/has_questionnaire.rb +47 -1
- data/app/controllers/decidim/forms/admin/concerns/has_questionnaire_answers.rb +97 -0
- data/app/controllers/decidim/forms/concerns/has_questionnaire.rb +3 -2
- data/app/forms/decidim/forms/admin/display_condition_form.rb +100 -0
- data/app/forms/decidim/forms/admin/question_form.rb +1 -0
- data/app/forms/decidim/forms/answer_form.rb +15 -0
- data/app/forms/decidim/forms/questionnaire_form.rb +5 -0
- data/app/helpers/decidim/forms/admin/application_helper.rb +21 -0
- data/app/helpers/decidim/forms/admin/concerns/has_questionnaire_answers_pagination_helper.rb +49 -0
- data/app/helpers/decidim/forms/admin/concerns/has_questionnaire_answers_url_helper.rb +40 -0
- data/app/helpers/decidim/forms/admin/questionnaire_answers_helper.rb +30 -0
- data/app/jobs/decidim/forms/export_questionnaire_answers_job.rb +19 -0
- data/app/models/decidim/forms/answer.rb +0 -3
- data/app/models/decidim/forms/answer_option.rb +14 -0
- data/app/models/decidim/forms/display_condition.rb +65 -0
- data/app/models/decidim/forms/question.rb +34 -0
- data/app/models/decidim/forms/question_matrix_row.rb +3 -0
- data/app/models/decidim/forms/questionnaire.rb +22 -1
- data/app/presenters/decidim/forms/admin/questionnaire_answer_presenter.rb +43 -0
- data/app/presenters/decidim/forms/admin/questionnaire_participant_presenter.rb +60 -0
- data/app/presenters/decidim/forms/answer_option_presenter.rb +20 -0
- data/app/presenters/decidim/forms/question_presenter.rb +16 -0
- data/app/queries/decidim/forms/questionnaire_participant.rb +35 -0
- data/app/queries/decidim/forms/questionnaire_participants.rb +43 -0
- data/app/views/decidim/forms/admin/questionnaires/_display_condition.html.erb +88 -0
- data/app/views/decidim/forms/admin/questionnaires/_display_condition_template.html.erb +7 -0
- data/app/views/decidim/forms/admin/questionnaires/_form.html.erb +30 -4
- data/app/views/decidim/forms/admin/questionnaires/_question.html.erb +19 -3
- data/app/views/decidim/forms/admin/questionnaires/answers/export/_answer.html.erb +31 -0
- data/app/views/decidim/forms/admin/questionnaires/answers/export/pdf.html.erb +13 -0
- data/app/views/decidim/forms/admin/questionnaires/answers/index.html.erb +53 -0
- data/app/views/decidim/forms/admin/questionnaires/answers/show.html.erb +48 -0
- data/app/views/decidim/forms/admin/questionnaires/edit.html.erb +9 -5
- data/app/views/decidim/forms/questionnaires/_answer.html.erb +1 -1
- data/app/views/decidim/forms/questionnaires/show.html.erb +22 -2
- data/app/views/layouts/decidim/forms/admin/questionnaires/questionnaire_answers.html.erb +12 -0
- data/config/initializers/wicked_pdf.rb +25 -0
- data/config/locales/am-ET.yml +1 -0
- data/config/locales/ar.yml +0 -1
- data/config/locales/bg-BG.yml +0 -2
- data/config/locales/bg.yml +14 -0
- data/config/locales/ca.yml +56 -4
- data/config/locales/cs.yml +56 -4
- data/config/locales/da.yml +1 -0
- data/config/locales/de.yml +53 -1
- data/config/locales/el.yml +0 -2
- data/config/locales/en.yml +54 -2
- data/config/locales/eo.yml +1 -0
- data/config/locales/es-MX.yml +53 -1
- data/config/locales/es-PY.yml +53 -1
- data/config/locales/es.yml +54 -2
- data/config/locales/et.yml +1 -0
- data/config/locales/eu.yml +0 -1
- data/config/locales/fi-plain.yml +53 -1
- data/config/locales/fi.yml +53 -1
- data/config/locales/fr-CA.yml +54 -2
- data/config/locales/fr.yml +55 -3
- data/config/locales/gl.yml +1 -1
- data/config/locales/hr.yml +1 -0
- data/config/locales/hu.yml +0 -2
- data/config/locales/id-ID.yml +0 -1
- data/config/locales/is.yml +1 -0
- data/config/locales/it.yml +53 -1
- data/config/locales/ja-JP.yml +51 -1
- data/config/locales/ja.yml +170 -0
- data/config/locales/ko-KR.yml +1 -0
- data/config/locales/ko.yml +1 -0
- data/config/locales/lt.yml +1 -0
- data/config/locales/{lv-LV.yml → lv.yml} +0 -1
- data/config/locales/mt.yml +1 -0
- data/config/locales/nl.yml +59 -7
- data/config/locales/no.yml +48 -2
- data/config/locales/om-ET.yml +1 -0
- data/config/locales/pl.yml +52 -3
- data/config/locales/pt-BR.yml +0 -1
- data/config/locales/pt.yml +51 -2
- data/config/locales/ro-RO.yml +51 -2
- data/config/locales/ru.yml +0 -1
- data/config/locales/si-LK.yml +1 -0
- data/config/locales/sk.yml +0 -2
- data/config/locales/sl.yml +7 -0
- data/config/locales/so-SO.yml +1 -0
- data/config/locales/sv.yml +51 -2
- data/config/locales/sw-KE.yml +1 -0
- data/config/locales/ti-ER.yml +1 -0
- data/config/locales/tr-TR.yml +88 -2
- data/config/locales/vi-VN.yml +1 -0
- data/config/locales/vi.yml +1 -0
- data/config/locales/zh-CN.yml +172 -0
- data/config/locales/zh-TW.yml +1 -0
- data/db/migrate/20200130194123_create_decidim_forms_display_conditions.rb +20 -0
- data/db/migrate/20201110152921_add_salt_to_decidim_forms_questionnaires.rb +16 -0
- data/lib/decidim/exporters/form_pdf.rb +33 -0
- data/lib/decidim/exporters/form_pdf_controller_helper.rb +11 -0
- data/lib/decidim/forms.rb +5 -0
- data/lib/decidim/forms/admin_engine.rb +1 -1
- data/lib/decidim/forms/test.rb +6 -0
- data/lib/decidim/forms/test/factories.rb +31 -0
- data/lib/decidim/forms/test/shared_examples/has_questionnaire.rb +619 -38
- data/lib/decidim/forms/test/shared_examples/manage_questionnaire_answers.rb +108 -0
- data/lib/decidim/forms/test/shared_examples/manage_questionnaires.rb +21 -894
- data/lib/decidim/forms/test/shared_examples/manage_questionnaires/add_display_conditions.rb +179 -0
- data/lib/decidim/forms/test/shared_examples/manage_questionnaires/add_questions.rb +463 -0
- data/lib/decidim/forms/test/shared_examples/manage_questionnaires/update_display_conditions.rb +93 -0
- data/lib/decidim/forms/test/shared_examples/manage_questionnaires/update_questions.rb +461 -0
- data/lib/decidim/forms/user_answers_serializer.rb +1 -1
- data/lib/decidim/forms/version.rb +1 -1
- metadata +97 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8c64f5c2dbb8ae561a2e8db75db766f978c2a445e7c38563a2fa7416c2566149
|
4
|
+
data.tar.gz: e0b9f7121d658512cf17d39878753365c0dde22355db67f266c84ba237de2361
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c622686680eba06c10eb5106938ea376ffcdfdc9196060975317f648c2119430ec8b5ec4b18016a6ca3268056ee4949958484ac1be9a4a4acea5055a858163a3
|
7
|
+
data.tar.gz: 4ea7be1f3ba73666074f04757de50d1fd95fca1aa01f4b91f04e5d0c6a01999fb2803243cc288bfdd3ac857a4ba619b68d7d0108aaa3c0f586a878e95ac80ac9
|
@@ -0,0 +1,40 @@
|
|
1
|
+
((exports) => {
|
2
|
+
class AutoSelectOptionsFromUrl {
|
3
|
+
constructor(options = {}) {
|
4
|
+
this.$source = options.source;
|
5
|
+
this.$select = options.select;
|
6
|
+
this.sourceToParams = options.sourceToParams;
|
7
|
+
this.run();
|
8
|
+
}
|
9
|
+
|
10
|
+
run() {
|
11
|
+
this.$source.on("change", this._onSourceChange.bind(this));
|
12
|
+
this._onSourceChange();
|
13
|
+
}
|
14
|
+
|
15
|
+
_onSourceChange() {
|
16
|
+
const select = this.$select;
|
17
|
+
const params = this.sourceToParams(this.$source);
|
18
|
+
const url = this.$source.data("url");
|
19
|
+
|
20
|
+
$.getJSON(url, params, function (data) {
|
21
|
+
select.find("option:not([value=''])").remove();
|
22
|
+
const selectedValue = select.data("selected");
|
23
|
+
|
24
|
+
data.forEach((option) => {
|
25
|
+
let optionElement = $(`<option value="${option.id}">${option.body}</option>`).appendTo(select);
|
26
|
+
if (option.id === selectedValue) {
|
27
|
+
optionElement.attr("selected", true);
|
28
|
+
}
|
29
|
+
});
|
30
|
+
|
31
|
+
if (selectedValue) {
|
32
|
+
select.val(selectedValue);
|
33
|
+
}
|
34
|
+
});
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
exports.DecidimAdmin = exports.DecidimAdmin || {};
|
39
|
+
exports.DecidimAdmin.AutoSelectOptionsFromUrl = AutoSelectOptionsFromUrl;
|
40
|
+
})(window);
|
@@ -1,9 +1,12 @@
|
|
1
|
+
/* eslint-disable max-lines */
|
2
|
+
|
1
3
|
// = require ./auto_buttons_by_min_items.component
|
2
4
|
// = require ./auto_select_options_by_total_items.component
|
5
|
+
// = require ./auto_select_options_from_url.component
|
3
6
|
// = require ./live_text_update.component
|
4
7
|
|
5
8
|
((exports) => {
|
6
|
-
const { AutoLabelByPositionComponent, AutoButtonsByPositionComponent, AutoButtonsByMinItemsComponent, AutoSelectOptionsByTotalItemsComponent, createLiveTextUpdateComponent, createFieldDependentInputs, createDynamicFields, createSortList } = exports.DecidimAdmin;
|
9
|
+
const { AutoLabelByPositionComponent, AutoButtonsByPositionComponent, AutoButtonsByMinItemsComponent, AutoSelectOptionsByTotalItemsComponent, AutoSelectOptionsFromUrl, createLiveTextUpdateComponent, createFieldDependentInputs, createDynamicFields, createSortList } = exports.DecidimAdmin;
|
7
10
|
const { createQuillEditor } = exports.Decidim;
|
8
11
|
|
9
12
|
const wrapperSelector = ".questionnaire-questions";
|
@@ -18,22 +21,54 @@
|
|
18
21
|
const addMatrixRowButtonSelector = ".add-matrix-row";
|
19
22
|
const maxChoicesWrapperSelector = ".questionnaire-question-max-choices";
|
20
23
|
|
21
|
-
const
|
22
|
-
const
|
24
|
+
const displayConditionFieldSelector = ".questionnaire-question-display-condition";
|
25
|
+
const displayConditionsWrapperSelector = ".questionnaire-question-display-conditions";
|
26
|
+
const displayConditionRemoveFieldButtonSelector = ".remove-display-condition";
|
27
|
+
|
28
|
+
const displayConditionQuestionSelector = "select[name$=\\[decidim_condition_question_id\\]]";
|
29
|
+
const displayConditionAnswerOptionSelector = "select[name$=\\[decidim_answer_option_id\\]]";
|
30
|
+
const displayConditionTypeSelector = "select[name$=\\[condition_type\\]]";
|
31
|
+
const deletedInputSelector = "input[name$=\\[deleted\\]]";
|
32
|
+
|
33
|
+
const displayConditionValueWrapperSelector = ".questionnaire-question-display-condition-value";
|
34
|
+
const displayconditionAnswerOptionWrapperSelector = ".questionnaire-question-display-condition-answer-option";
|
35
|
+
|
36
|
+
const addDisplayConditionButtonSelector = ".add-display-condition";
|
37
|
+
|
38
|
+
const removeDisplayConditionsForFirstQuestion = () => {
|
39
|
+
$(fieldSelector).each((idx, el) => {
|
40
|
+
const $question = $(el);
|
41
|
+
if (idx) {
|
42
|
+
$question.find(displayConditionsWrapperSelector).find(deletedInputSelector).val("false");
|
43
|
+
$question.find(displayConditionsWrapperSelector).show();
|
44
|
+
}
|
45
|
+
else {
|
46
|
+
$question.find(displayConditionsWrapperSelector).find(deletedInputSelector).val("true");
|
47
|
+
$question.find(displayConditionsWrapperSelector).hide();
|
48
|
+
}
|
49
|
+
});
|
50
|
+
};
|
51
|
+
|
52
|
+
const autoButtonsByPosition = new AutoButtonsByPositionComponent({
|
53
|
+
listSelector: ".questionnaire-question:not(.hidden)",
|
54
|
+
hideOnFirstSelector: ".move-up-question",
|
55
|
+
hideOnLastSelector: ".move-down-question"
|
56
|
+
});
|
23
57
|
|
24
58
|
const autoLabelByPosition = new AutoLabelByPositionComponent({
|
25
59
|
listSelector: ".questionnaire-question:not(.hidden)",
|
26
60
|
labelSelector: ".card-title span:first",
|
27
61
|
onPositionComputed: (el, idx) => {
|
28
62
|
$(el).find("input[name$=\\[position\\]]").val(idx);
|
63
|
+
|
64
|
+
autoButtonsByPosition.run();
|
65
|
+
|
66
|
+
removeDisplayConditionsForFirstQuestion();
|
29
67
|
}
|
30
68
|
});
|
31
69
|
|
32
|
-
const
|
33
|
-
|
34
|
-
hideOnFirstSelector: ".move-up-question",
|
35
|
-
hideOnLastSelector: ".move-down-question"
|
36
|
-
});
|
70
|
+
const MULTIPLE_CHOICE_VALUES = ["single_option", "multiple_option", "sorting", "matrix_single", "matrix_multiple"];
|
71
|
+
const MATRIX_VALUES = ["matrix_single", "matrix_multiple"];
|
37
72
|
|
38
73
|
const createAutoMaxChoicesByNumberOfAnswerOptions = (fieldId) => {
|
39
74
|
return new AutoSelectOptionsByTotalItemsComponent({
|
@@ -52,6 +87,14 @@
|
|
52
87
|
})
|
53
88
|
};
|
54
89
|
|
90
|
+
const createAutoSelectOptionsFromUrl = ($field) => {
|
91
|
+
return new AutoSelectOptionsFromUrl({
|
92
|
+
source: $field.find(displayConditionQuestionSelector),
|
93
|
+
select: $field.find(displayConditionAnswerOptionSelector),
|
94
|
+
sourceToParams: ($element) => { return { id: $element.val() } }
|
95
|
+
})
|
96
|
+
};
|
97
|
+
|
55
98
|
const createSortableList = () => {
|
56
99
|
createSortList(".questionnaire-questions-list:not(.published)", {
|
57
100
|
handle: ".question-divider",
|
@@ -80,6 +123,15 @@
|
|
80
123
|
});
|
81
124
|
}
|
82
125
|
|
126
|
+
const createCollapsibleQuestion = ($target) => {
|
127
|
+
const $collapsible = $target.find(".collapsible");
|
128
|
+
if ($collapsible.length > 0) {
|
129
|
+
const collapsibleId = $collapsible.attr("id").replace("-question-card", "");
|
130
|
+
const toggleAttr = `${collapsibleId}-question-card button--collapse-question-${collapsibleId} button--expand-question-${collapsibleId}`;
|
131
|
+
$target.find(".question--collapse").data("toggle", toggleAttr);
|
132
|
+
}
|
133
|
+
};
|
134
|
+
|
83
135
|
const createDynamicFieldsForAnswerOptions = (fieldId) => {
|
84
136
|
const autoButtons = createAutoButtonsByMinItemsForAnswerOptions(fieldId);
|
85
137
|
const autoSelectOptions = createAutoMaxChoicesByNumberOfAnswerOptions(fieldId);
|
@@ -123,22 +175,122 @@
|
|
123
175
|
|
124
176
|
const dynamicFieldsForMatrixRows = {};
|
125
177
|
|
126
|
-
const isMultipleChoiceOption = (
|
127
|
-
const value = $selectField.val();
|
128
|
-
|
178
|
+
const isMultipleChoiceOption = (value) => {
|
129
179
|
return MULTIPLE_CHOICE_VALUES.indexOf(value) >= 0;
|
130
180
|
}
|
131
181
|
|
132
|
-
const isMatrix = (
|
133
|
-
const value = $selectField.val();
|
134
|
-
|
182
|
+
const isMatrix = (value) => {
|
135
183
|
return MATRIX_VALUES.indexOf(value) >= 0;
|
136
184
|
}
|
137
185
|
|
186
|
+
const getSelectedQuestionType = (select) => {
|
187
|
+
const selectedOption = select.options[select.selectedIndex];
|
188
|
+
return $(selectedOption).data("type");
|
189
|
+
};
|
190
|
+
|
191
|
+
const onDisplayConditionQuestionChange = ($field) => {
|
192
|
+
const $questionSelector = $field.find(displayConditionQuestionSelector);
|
193
|
+
const selectedQuestionType = getSelectedQuestionType($questionSelector[0]);
|
194
|
+
|
195
|
+
const isMultiple = isMultipleChoiceOption(selectedQuestionType);
|
196
|
+
|
197
|
+
let conditionTypes = ["answered", "not_answered"];
|
198
|
+
|
199
|
+
if (isMultiple) {
|
200
|
+
conditionTypes.push("equal");
|
201
|
+
conditionTypes.push("not_equal");
|
202
|
+
}
|
203
|
+
|
204
|
+
conditionTypes.push("match");
|
205
|
+
|
206
|
+
const $conditionTypeSelect = $field.find(displayConditionTypeSelector);
|
207
|
+
|
208
|
+
$conditionTypeSelect.find("option").each((idx, option) => {
|
209
|
+
const $option = $(option);
|
210
|
+
const value = $option.val();
|
211
|
+
|
212
|
+
if (!value) {
|
213
|
+
return;
|
214
|
+
}
|
215
|
+
|
216
|
+
$option.show();
|
217
|
+
|
218
|
+
if (conditionTypes.indexOf(value) < 0) {
|
219
|
+
$option.hide();
|
220
|
+
}
|
221
|
+
});
|
222
|
+
|
223
|
+
if (conditionTypes.indexOf($conditionTypeSelect.val()) < 0) {
|
224
|
+
$conditionTypeSelect.val(conditionTypes[0]);
|
225
|
+
}
|
226
|
+
|
227
|
+
$conditionTypeSelect.trigger("change");
|
228
|
+
};
|
229
|
+
|
230
|
+
const onDisplayConditionTypeChange = ($field) => {
|
231
|
+
const value = $field.find(displayConditionTypeSelector).val();
|
232
|
+
const $valueWrapper = $field.find(displayConditionValueWrapperSelector);
|
233
|
+
const $answerOptionWrapper = $field.find(displayconditionAnswerOptionWrapperSelector);
|
234
|
+
|
235
|
+
const $questionSelector = $field.find(displayConditionQuestionSelector);
|
236
|
+
const selectedQuestionType = getSelectedQuestionType($questionSelector[0]);
|
237
|
+
|
238
|
+
const isMultiple = isMultipleChoiceOption(selectedQuestionType);
|
239
|
+
|
240
|
+
if (value === "match") {
|
241
|
+
$valueWrapper.show();
|
242
|
+
}
|
243
|
+
else {
|
244
|
+
$valueWrapper.hide();
|
245
|
+
}
|
246
|
+
|
247
|
+
if (isMultiple && (value === "not_equal" || value === "equal")) {
|
248
|
+
$answerOptionWrapper.show();
|
249
|
+
}
|
250
|
+
else {
|
251
|
+
$answerOptionWrapper.hide();
|
252
|
+
}
|
253
|
+
};
|
254
|
+
|
255
|
+
const initializeDisplayConditionField = ($field) => {
|
256
|
+
const autoSelectByUrl = createAutoSelectOptionsFromUrl($field);
|
257
|
+
autoSelectByUrl.run();
|
258
|
+
|
259
|
+
$field.find(displayConditionQuestionSelector).on("change", () => {
|
260
|
+
onDisplayConditionQuestionChange($field);
|
261
|
+
});
|
262
|
+
|
263
|
+
$field.find(displayConditionTypeSelector).on("change", () => {
|
264
|
+
onDisplayConditionTypeChange($field);
|
265
|
+
});
|
266
|
+
|
267
|
+
onDisplayConditionTypeChange($field);
|
268
|
+
onDisplayConditionQuestionChange($field);
|
269
|
+
}
|
270
|
+
|
271
|
+
const createDynamicFieldsForDisplayConditions = (fieldId) => {
|
272
|
+
return createDynamicFields({
|
273
|
+
placeholderId: "questionnaire-question-display-condition-id",
|
274
|
+
wrapperSelector: `#${fieldId} ${displayConditionsWrapperSelector}`,
|
275
|
+
containerSelector: ".questionnaire-question-display-conditions-list",
|
276
|
+
fieldSelector: displayConditionFieldSelector,
|
277
|
+
addFieldButtonSelector: addDisplayConditionButtonSelector,
|
278
|
+
removeFieldButtonSelector: displayConditionRemoveFieldButtonSelector,
|
279
|
+
onAddField: ($field) => {
|
280
|
+
initializeDisplayConditionField($field);
|
281
|
+
},
|
282
|
+
onRemoveField: () => {
|
283
|
+
}
|
284
|
+
});
|
285
|
+
};
|
286
|
+
|
287
|
+
const dynamicFieldsForDisplayConditions = {};
|
288
|
+
|
138
289
|
const setupInitialQuestionAttributes = ($target) => {
|
139
290
|
const fieldId = $target.attr("id");
|
140
291
|
const $fieldQuestionTypeSelect = $target.find(questionTypeSelector);
|
141
292
|
|
293
|
+
createCollapsibleQuestion($target);
|
142
294
|
createDynamicQuestionTitle(fieldId);
|
143
295
|
|
144
296
|
createFieldDependentInputs({
|
@@ -147,7 +299,7 @@
|
|
147
299
|
dependentFieldsSelector: answerOptionsWrapperSelector,
|
148
300
|
dependentInputSelector: `${answerOptionFieldSelector} input`,
|
149
301
|
enablingCondition: ($field) => {
|
150
|
-
return isMultipleChoiceOption($field);
|
302
|
+
return isMultipleChoiceOption($field.val());
|
151
303
|
}
|
152
304
|
});
|
153
305
|
|
@@ -167,18 +319,19 @@
|
|
167
319
|
dependentFieldsSelector: matrixRowsWrapperSelector,
|
168
320
|
dependentInputSelector: `${matrixRowFieldSelector} input`,
|
169
321
|
enablingCondition: ($field) => {
|
170
|
-
return isMatrix($field);
|
322
|
+
return isMatrix($field.val());
|
171
323
|
}
|
172
324
|
});
|
173
325
|
|
174
326
|
dynamicFieldsForAnswerOptions[fieldId] = createDynamicFieldsForAnswerOptions(fieldId);
|
175
327
|
dynamicFieldsForMatrixRows[fieldId] = createDynamicFieldsForMatrixRows(fieldId);
|
328
|
+
dynamicFieldsForDisplayConditions[fieldId] = createDynamicFieldsForDisplayConditions(fieldId);
|
176
329
|
|
177
330
|
const dynamicFieldsAnswerOptions = dynamicFieldsForAnswerOptions[fieldId];
|
178
331
|
const dynamicFieldsMatrixRows = dynamicFieldsForMatrixRows[fieldId];
|
179
332
|
|
180
333
|
const onQuestionTypeChange = () => {
|
181
|
-
if (isMultipleChoiceOption($fieldQuestionTypeSelect)) {
|
334
|
+
if (isMultipleChoiceOption($fieldQuestionTypeSelect.val())) {
|
182
335
|
const nOptions = $fieldQuestionTypeSelect.parents(fieldSelector).find(answerOptionFieldSelector).length;
|
183
336
|
|
184
337
|
if (nOptions === 0) {
|
@@ -187,7 +340,7 @@
|
|
187
340
|
}
|
188
341
|
}
|
189
342
|
|
190
|
-
if (isMatrix($fieldQuestionTypeSelect)) {
|
343
|
+
if (isMatrix($fieldQuestionTypeSelect.val())) {
|
191
344
|
const nRows = $fieldQuestionTypeSelect.parents(fieldSelector).find(matrixRowFieldSelector).length;
|
192
345
|
|
193
346
|
if (nRows === 0) {
|
@@ -224,13 +377,6 @@
|
|
224
377
|
moveUpFieldButtonSelector: ".move-up-question",
|
225
378
|
moveDownFieldButtonSelector: ".move-down-question",
|
226
379
|
onAddField: ($field) => {
|
227
|
-
const $collapsible = $field.find(".collapsible");
|
228
|
-
if ($collapsible.length > 0) {
|
229
|
-
const collapsibleId = $collapsible.attr("id").replace("-question-card", "");
|
230
|
-
const toggleAttr = `${collapsibleId}-question-card button--collapse-question-${collapsibleId} button--expand-question-${collapsibleId}`;
|
231
|
-
$field.find(".question--collapse").data("toggle", toggleAttr);
|
232
|
-
}
|
233
|
-
|
234
380
|
setupInitialQuestionAttributes($field);
|
235
381
|
createSortableList();
|
236
382
|
|
@@ -248,9 +394,14 @@
|
|
248
394
|
$field.find(answerOptionRemoveFieldButtonSelector).each((idx, el) => {
|
249
395
|
dynamicFieldsForAnswerOptions[$field.attr("id")]._removeField(el);
|
250
396
|
});
|
397
|
+
|
251
398
|
$field.find(matrixRowRemoveFieldButtonSelector).each((idx, el) => {
|
252
399
|
dynamicFieldsForMatrixRows[$field.attr("id")]._removeField(el);
|
253
400
|
});
|
401
|
+
|
402
|
+
$field.find(displayConditionRemoveFieldButtonSelector).each((idx, el) => {
|
403
|
+
dynamicFieldsForDisplayConditions[$field.attr("id")]._removeField(el);
|
404
|
+
});
|
254
405
|
},
|
255
406
|
onMoveUpField: () => {
|
256
407
|
autoLabelByPosition.run();
|
@@ -271,6 +422,11 @@
|
|
271
422
|
setupInitialQuestionAttributes($target);
|
272
423
|
});
|
273
424
|
|
425
|
+
$(displayConditionFieldSelector).each((idx, el) => {
|
426
|
+
const $field = $(el);
|
427
|
+
initializeDisplayConditionField($field)
|
428
|
+
});
|
429
|
+
|
274
430
|
autoLabelByPosition.run();
|
275
431
|
autoButtonsByPosition.run();
|
276
432
|
})(window);
|
@@ -1,59 +1,79 @@
|
|
1
|
+
/* eslint-disable no-ternary */
|
2
|
+
|
1
3
|
((exports) => {
|
2
4
|
class AutosortableCheckboxesComponent {
|
3
5
|
constructor(options = {}) {
|
4
6
|
this.wrapperField = options.wrapperField;
|
5
7
|
this._bindEvent();
|
6
|
-
this.
|
8
|
+
this._order();
|
9
|
+
this._normalize();
|
7
10
|
}
|
8
11
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
$lastSorted.removeClass("last-sorted");
|
18
|
-
$parentLabel.insertAfter($lastSorted);
|
19
|
-
} else {
|
20
|
-
$parentLabel.insertBefore(this.wrapperField.find("label:first-child"));
|
21
|
-
}
|
12
|
+
// Order by position
|
13
|
+
_order() {
|
14
|
+
const max = $(this.wrapperField).find(".collection-input").length;
|
15
|
+
$(this.wrapperField).find(".collection-input").each((idx, el) => {
|
16
|
+
const $positionField = $(el).find("input[name$=\\[position\\]]");
|
17
|
+
const position = $positionField.val()
|
18
|
+
? parseInt($positionField.val(), 10)
|
19
|
+
: max;
|
22
20
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
const
|
21
|
+
let $next = $(el).next();
|
22
|
+
while ($next.length > 0) {
|
23
|
+
const $nextPositionField = $next.find("input[name$=\\[position\\]]");
|
24
|
+
const nextPosition = $nextPositionField.val()
|
25
|
+
? parseInt($nextPositionField.val(), 10)
|
26
|
+
: max;
|
27
27
|
|
28
|
-
if (
|
29
|
-
$
|
30
|
-
} else {
|
31
|
-
$parentLabel.insertAfter(this.wrapperField.find("label:last-child"));
|
28
|
+
if (position > nextPosition) {
|
29
|
+
$next.insertBefore($(el));
|
32
30
|
}
|
33
|
-
|
34
|
-
$parentLabel.removeClass("sorted");
|
31
|
+
$next = $next.next();
|
35
32
|
}
|
36
33
|
});
|
34
|
+
}
|
37
35
|
|
38
|
-
|
39
|
-
|
36
|
+
_findLastPosition() {
|
37
|
+
let lastPosition = 0;
|
38
|
+
$(this.wrapperField).find(".collection-input").each((idx, el) => {
|
40
39
|
const $positionField = $(el).find("input[name$=\\[position\\]]");
|
40
|
+
const position = parseInt($positionField.val(), 10);
|
41
|
+
if (position > lastPosition) {
|
42
|
+
lastPosition = position;
|
43
|
+
}
|
44
|
+
});
|
45
|
+
return lastPosition;
|
46
|
+
}
|
41
47
|
|
42
|
-
|
48
|
+
_normalize() {
|
49
|
+
$(this.wrapperField).find(".collection-input .position").each((idx, el) => {
|
50
|
+
const $positionField = $(el).parent().find("input[name$=\\[position\\]]");
|
51
|
+
if ($positionField.val()) {
|
43
52
|
$positionField.val(idx);
|
44
53
|
$positionField.prop("disabled", false);
|
45
|
-
$
|
46
|
-
} else {
|
47
|
-
$positionField.val("");
|
48
|
-
$positionField.prop("disabled", true);
|
49
|
-
$positionSelector.html("");
|
54
|
+
$(el).html(`${idx + 1}. `);
|
50
55
|
}
|
51
56
|
});
|
52
57
|
}
|
53
58
|
|
54
59
|
_bindEvent() {
|
55
|
-
$(this.wrapperField).find("input[type=checkbox]").on("change", () => {
|
56
|
-
|
60
|
+
$(this.wrapperField).find("input[type=checkbox]").on("change", (el) => {
|
61
|
+
const $parentLabel = $(el.target).parents("label");
|
62
|
+
const $positionSelector = $parentLabel.find(".position");
|
63
|
+
const $positionField = $parentLabel.find("input[name$=\\[position\\]]");
|
64
|
+
const lastPosition = this._findLastPosition();
|
65
|
+
|
66
|
+
if (el.target.checked) {
|
67
|
+
$positionField.val(lastPosition + 1);
|
68
|
+
$positionField.prop("disabled", false);
|
69
|
+
$positionSelector.html(lastPosition + 1);
|
70
|
+
} else {
|
71
|
+
$positionField.val("");
|
72
|
+
$positionField.prop("disabled", true);
|
73
|
+
$positionSelector.html("");
|
74
|
+
}
|
75
|
+
this._order();
|
76
|
+
this._normalize();
|
57
77
|
});
|
58
78
|
}
|
59
79
|
}
|