From bf5b92c4659a6e3c53417dd86c97dcb2d0c6307b Mon Sep 17 00:00:00 2001 From: Felix Rindt Date: Mon, 3 Aug 2020 18:15:23 +0200 Subject: [PATCH] Copy answers button for addon products (#1733) --- src/pretix/base/views/mixins.py | 3 +- .../pretixcontrol/item/include_addons.html | 3 +- .../event/checkout_questions.html | 17 +++++-- src/pretix/static/pretixpresale/js/ui/main.js | 48 ++++++++++++------- 4 files changed, 48 insertions(+), 23 deletions(-) diff --git a/src/pretix/base/views/mixins.py b/src/pretix/base/views/mixins.py index ec88d171e1..76bc376122 100644 --- a/src/pretix/base/views/mixins.py +++ b/src/pretix/base/views/mixins.py @@ -53,6 +53,7 @@ class BaseQuestionsViewMixin: data=(self.request.POST if self.request.method == 'POST' else None), files=(self.request.FILES if self.request.method == 'POST' else None)) form.pos = cartpos or orderpos + form.show_copy_answers_to_addon_button = form.pos.addon_to and set(form.pos.addon_to.item.questions.all()) & set(form.pos.item.questions.all()) if len(form.fields) > 0: formlist.append(form) return formlist @@ -61,7 +62,7 @@ class BaseQuestionsViewMixin: def formdict(self): storage = OrderedDict() for f in self.forms: - pos = f.cartpos or f.orderpos + pos = f.pos if pos.addon_to_id: if pos.addon_to not in storage: storage[pos.addon_to] = [] diff --git a/src/pretix/control/templates/pretixcontrol/item/include_addons.html b/src/pretix/control/templates/pretixcontrol/item/include_addons.html index 9cf9df0657..c60264cbef 100644 --- a/src/pretix/control/templates/pretixcontrol/item/include_addons.html +++ b/src/pretix/control/templates/pretixcontrol/item/include_addons.html @@ -8,8 +8,7 @@ workshops as add-ons to the conference ticket. With this configuration, the workshops cannot be bought on their own but only in combination with a conference ticket. You can here specify categories of products that can be used as add-ons to this product. You can also specify the minimum and maximum number of - add-ons of the given category that can or need to be chosen. The user can buy every add-on from the - category at most once. If an add-on product has multiple variations, only one of them can be bought. + add-ons of the given category that can or need to be chosen. {% endblocktrans %}

diff --git a/src/pretix/presale/templates/pretixpresale/event/checkout_questions.html b/src/pretix/presale/templates/pretixpresale/event/checkout_questions.html index 983ac92774..9715a82fa0 100644 --- a/src/pretix/presale/templates/pretixpresale/event/checkout_questions.html +++ b/src/pretix/presale/templates/pretixpresale/event/checkout_questions.html @@ -62,7 +62,7 @@ {% endif %} {% if forloop.counter > 1 %} - + {% else %} @@ -71,7 +71,7 @@
-
+
{% if pos.addons.all %}
diff --git a/src/pretix/static/pretixpresale/js/ui/main.js b/src/pretix/static/pretixpresale/js/ui/main.js index 42b945544a..3ea9f04df3 100644 --- a/src/pretix/static/pretixpresale/js/ui/main.js +++ b/src/pretix/static/pretixpresale/js/ui/main.js @@ -171,8 +171,28 @@ $(function () { $(".js-copy-answers").click(function (e) { e.preventDefault(); e.stopPropagation(); - var idx = $(this).data('id'); - copy_answers(idx); + let idx = $(this).data('id'); + const addonDivs = $('div[data-idx="' + idx +'"]') + addonDivs.each(function (index) { + const elements = $(this).find('input, select, textarea'); + + const addonIdx = $(this).attr("data-addonidx"); + const answersDiv = $('div[data-idx="0"][data-addonidx="' + addonIdx + '"]'); + const answers = answersDiv.find('input, select, textarea'); + + copy_answers(elements, answers); + }) + return false; + }); + $(".js-copy-answers-addon").click(function (e) { + e.preventDefault(); + e.stopPropagation(); + const id = $(this).data('id'); + const addonId = $(this).data('addonid'); + const addonDiv = $('div[data-idx="' + id +'"][data-addonidx="' + addonId + '"]'); + const elements = addonDiv.find('input, select, textarea'); + const answers = $('*[data-idx="' + id + '"] input, *[data-idx="' + id + '"] select, *[data-idx="' + id + '"] textarea'); + copy_answers(elements, answers); return false; }); var copy_to_first_ticket = true; @@ -424,45 +444,41 @@ $(function () { lightbox.init(); }); -function copy_answers(idx) { - var elements = $('*[data-idx="' + idx + '"] input, *[data-idx="' + idx + '"] select, *[data-idx="' + idx + '"] textarea'); - var firstAnswers = $('*[data-idx="0"] input, *[data-idx="0"] select, *[data-idx="0"] textarea'); - elements.each(function (index) { +function copy_answers(elements, answers) { + elements.each(function (index) { var input = $(this), tagName = input.prop('tagName').toLowerCase(), attributeType = input.attr('type'), suffix = input.attr('name').split('-')[1]; - switch (tagName) { case "textarea": - input.val(firstAnswers.filter("[name$=" + suffix + "]").val()); + input.val(answers.filter("[name$=" + suffix + "]").val()); break; case "select": - input.val(firstAnswers.filter("[name$=" + suffix + "]").find(":selected").val()).change(); + input.val(answers.filter("[name$=" + suffix + "]").find(":selected").val()).change(); break; case "input": switch (attributeType) { case "text": case "number": - input.val(firstAnswers.filter("[name$=" + suffix + "]").val()); + input.val(answers.filter("[name$=" + suffix + "]").val()); break; case "checkbox": case "radio": if (input.attr('value')) { - input.prop("checked", firstAnswers.filter("[name$=" + suffix + "][value=" + input.attr('value') + "]").prop("checked")); + input.prop("checked", answers.filter("[name$=" + suffix + "][value=" + input.attr('value') + "]").prop("checked")); } else { - input.prop("checked", firstAnswers.filter("[name$=" + suffix + "]").prop("checked")); + input.prop("checked", answers.filter("[name$=" + suffix + "]").prop("checked")); } break; default: - input.val(firstAnswers.filter("[name$=" + suffix + "]").val()); + input.val(answers.filter("[name$=" + suffix + "]").val()); } break; default: - input.val(firstAnswers.filter("[name$=" + suffix + "]").val()); + input.val(answers.filter("[name$=" + suffix + "]").val()); } }); questions_toggle_dependent(true); -} - +} \ No newline at end of file