Allow dependencies between questions (#1202)

- [x] data model
- [x] api
- [x] backend editor
- [x] backend validation logic
- [x] frontend display logic
- [x] frontend validation logic
- [x] test checkout step
- [x] test modify order in frontend
- [x] test modify order in backend
- [x] validation tests
- [x] correctly evaluate dependency tree in frontend?
- [x] copy events
This commit is contained in:
Raphael Michel
2019-03-13 16:49:20 +01:00
committed by GitHub
parent d10cbd07a7
commit f95e8f374d
22 changed files with 825 additions and 211 deletions

View File

@@ -0,0 +1,71 @@
/*global $ */
function questions_toggle_dependent(ev) {
function q_should_be_shown($el) {
if (!$el.attr('data-question-dependency')) {
return true;
}
var dependency_name = $el.attr("name").split("_")[0] + "_" + $el.attr("data-question-dependency");
var dependency_value = $el.attr("data-question-dependency-value");
var $dependency_el;
if ($("select[name=" + dependency_name + "]").length) {
// dependency is type C
$dependency_el = $("select[name=" + dependency_name + "]");
if (!$dependency_el.closest(".form-group").hasClass("dependency-hidden")) { // do not show things that depend on hidden things
return q_should_be_shown($dependency_el) && $dependency_el.val() === dependency_value;
}
} else if ($("input[type=checkbox][name=" + dependency_name + "]").length) {
// dependency type is B or M
if (dependency_value === "True" || dependency_value === "False") {
$dependency_el = $("input[name=" + dependency_name + "]");
if (!$dependency_el.closest(".form-group").hasClass("dependency-hidden")) { // do not show things that depend on hidden things
if (dependency_value === "True") {
return q_should_be_shown($dependency_el) && $dependency_el.prop('checked');
} else {
return q_should_be_shown($dependency_el) && !$dependency_el.prop('checked');
}
}
} else {
$dependency_el = $("input[value=" + dependency_value + "][name=" + dependency_name + "]");
if (!$dependency_el.closest(".form-group").hasClass("dependency-hidden")) { // do not show things that depend on hidden things
return q_should_be_shown($dependency_el) && $dependency_el.prop('checked');
}
}
}
}
$("[data-question-dependency]").each(function () {
var $dependent = $(this).closest(".form-group");
var is_shown = !$dependent.hasClass("dependency-hidden");
var should_be_shown = q_should_be_shown($(this));
if (should_be_shown && !is_shown) {
$dependent.stop().removeClass("dependency-hidden");
if (!ev) {
$dependent.show();
} else {
$dependent.slideDown();
}
$dependent.find("input.required-hidden, select.required-hidden, textarea.required-hidden").each(function () {
$(this).prop("required", true).removeClass("required-hidden");
});
} else if (!should_be_shown && is_shown) {
if ($dependent.hasClass("has-error") || $dependent.find(".has-error").length) {
// Do not hide things with invalid validation
return;
}
$dependent.stop().addClass("dependency-hidden");
if (!ev) {
$dependent.hide();
} else {
$dependent.slideUp();
}
$dependent.find("input[required], select[required], textarea[required]").each(function () {
$(this).prop("required", false).addClass("required-hidden");
});
}
});
}