forked from CGM_Public/pretix_original
Copy answers button for addon products (#1733)
This commit is contained in:
@@ -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] = []
|
||||
|
||||
@@ -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 %}
|
||||
</p>
|
||||
<div class="formset" data-formset data-formset-prefix="{{ formset.prefix }}">
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
{% endif %}
|
||||
{% if forloop.counter > 1 %}
|
||||
<span class="text-right flip">
|
||||
<input type="button" data-id="{{ forloop.counter0 }}" name="copy" class="js-copy-answers btn btn-default btn-xs" value='{% trans "Copy answers from above" %}'>
|
||||
<button type="button" data-id="{{ forloop.counter0 }}" name="copy" class="js-copy-answers btn btn-default btn-xs">{% trans "Copy answers from above" %}</button>
|
||||
<i class="fa fa-angle-down collapse-indicator"></i>
|
||||
</span>
|
||||
{% else %}
|
||||
@@ -71,7 +71,7 @@
|
||||
</h4>
|
||||
</summary>
|
||||
<div>
|
||||
<div class="panel-body questions-form" data-idx="{{ forloop.counter0 }}">
|
||||
<div class="panel-body questions-form">
|
||||
{% if pos.addons.all %}
|
||||
<div class="form-group">
|
||||
<label class="col-md-3 control-label">
|
||||
@@ -105,9 +105,18 @@
|
||||
{% for form in forms %}
|
||||
{% if form.pos.item != pos.item %}
|
||||
{# Add-Ons #}
|
||||
<legend>+ {{ form.pos.item.name }}{% if form.pos.variation %} – {{ form.pos.variation.value }}{% endif %}</legend>
|
||||
<legend>
|
||||
{% if form.show_copy_answers_to_addon_button %}
|
||||
<span class="pull-right flip">
|
||||
<button type="button" data-id="{{ forloop.parentloop.counter0 }}" data-addonid="{{ forloop.counter0 }}" name="copy" class="js-copy-answers-addon btn btn-default btn-xs">{% trans "Copy answers" %}</button>
|
||||
</span>
|
||||
{% endif %}
|
||||
+ {{ form.pos.item.name }}{% if form.pos.variation %} – {{ form.pos.variation.value }}{% endif %}
|
||||
</legend>
|
||||
{% endif %}
|
||||
{% bootstrap_form form layout="checkout" %}
|
||||
<div data-idx="{{ forloop.parentloop.counter0 }}" data-addonidx="{{ forloop.counter0 }}">
|
||||
{% bootstrap_form form layout="checkout" %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user