diff --git a/src/pretix/control/forms/subevents.py b/src/pretix/control/forms/subevents.py index 4e442c6d3..b0a78fd7f 100644 --- a/src/pretix/control/forms/subevents.py +++ b/src/pretix/control/forms/subevents.py @@ -390,7 +390,8 @@ class QuotaFormSet(I18nInlineFormSet): use_required_attribute=False, locales=self.locales, event=self.event, - items=self.items + items=self.items, + searchable_selection=self.searchable_selection, ) self.add_fields(form, None) return form diff --git a/src/pretix/control/templates/pretixcontrol/subevents/bulk.html b/src/pretix/control/templates/pretixcontrol/subevents/bulk.html index ba82ccdd7..3f7a041f7 100644 --- a/src/pretix/control/templates/pretixcontrol/subevents/bulk.html +++ b/src/pretix/control/templates/pretixcontrol/subevents/bulk.html @@ -487,30 +487,32 @@ {% trans "These settings are optional, if you leave them empty, the default values from the product settings will be used." %}

{% for f in itemvar_forms %} - {% bootstrap_form_errors f %} -
- -
-
- {% bootstrap_field f.price addon_after=request.event.currency form_group_class="" layout="inline" %} +
+ {% bootstrap_form_errors f %} +
+ +
+
+ {% bootstrap_field f.price addon_after=request.event.currency form_group_class="" layout="inline" %} +
+
+
+ {% bootstrap_field f.disabled layout="inline" form_group_class="" %} +
-
-
- {% bootstrap_field f.disabled layout="inline" form_group_class="" %} -
-
-
-
- - {% include "pretixcontrol/subevents/fragment_unavail_mode_indicator.html" with mode=f.available_from_mode %}
- {% bootstrap_field f.rel_available_from form_group_class="" layout="inline" %} -
-
- - {% include "pretixcontrol/subevents/fragment_unavail_mode_indicator.html" with mode=f.available_until_mode %}
- {% bootstrap_field f.rel_available_until form_group_class="" layout="inline" %} +
+
+ + {% include "pretixcontrol/subevents/fragment_unavail_mode_indicator.html" with mode=f.available_from_mode %}
+ {% bootstrap_field f.rel_available_from form_group_class="" layout="inline" %} +
+
+ + {% include "pretixcontrol/subevents/fragment_unavail_mode_indicator.html" with mode=f.available_until_mode %}
+ {% bootstrap_field f.rel_available_until form_group_class="" layout="inline" %} +
{% endfor %} @@ -625,7 +627,7 @@ {% endif %} {% endfor %} -
+
diff --git a/src/pretix/control/templates/pretixcontrol/subevents/bulk_edit.html b/src/pretix/control/templates/pretixcontrol/subevents/bulk_edit.html index 8770301c5..369bf3fa6 100644 --- a/src/pretix/control/templates/pretixcontrol/subevents/bulk_edit.html +++ b/src/pretix/control/templates/pretixcontrol/subevents/bulk_edit.html @@ -363,7 +363,7 @@
{% endif %} -
+
diff --git a/src/pretix/control/templates/pretixcontrol/subevents/detail.html b/src/pretix/control/templates/pretixcontrol/subevents/detail.html index 9a7466c85..5bce7afbb 100644 --- a/src/pretix/control/templates/pretixcontrol/subevents/detail.html +++ b/src/pretix/control/templates/pretixcontrol/subevents/detail.html @@ -130,30 +130,32 @@ {% trans "These settings are optional, if you leave them empty, the default values from the product settings will be used." %}

{% for f in itemvar_forms %} - {% bootstrap_form_errors f %} -
- -
-
- {% bootstrap_field f.price addon_after=request.event.currency form_group_class="" layout="inline" %} +
+ {% bootstrap_form_errors f %} +
+ +
+
+ {% bootstrap_field f.price addon_after=request.event.currency form_group_class="" layout="inline" %} +
+
+
+ {% bootstrap_field f.disabled layout="inline" form_group_class="" %} +
-
-
- {% bootstrap_field f.disabled layout="inline" form_group_class="" %} -
-
-
-
- - {% include "pretixcontrol/subevents/fragment_unavail_mode_indicator.html" with mode=f.available_from_mode %}
- {% bootstrap_field f.available_from form_group_class="foo" layout="inline" %} -
-
- - {% include "pretixcontrol/subevents/fragment_unavail_mode_indicator.html" with mode=f.available_until_mode %}
- {% bootstrap_field f.available_until form_group_class="" layout="inline" %} +
+
+ + {% include "pretixcontrol/subevents/fragment_unavail_mode_indicator.html" with mode=f.available_from_mode %}
+ {% bootstrap_field f.available_from form_group_class="foo" layout="inline" %} +
+
+ + {% include "pretixcontrol/subevents/fragment_unavail_mode_indicator.html" with mode=f.available_until_mode %}
+ {% bootstrap_field f.available_until form_group_class="" layout="inline" %} +
{% endfor %} @@ -282,7 +284,7 @@
{% endif %}
-
+
diff --git a/src/pretix/static/pretixcontrol/js/ui/subevent.js b/src/pretix/static/pretixcontrol/js/ui/subevent.js index d38773c1b..81872d7db 100644 --- a/src/pretix/static/pretixcontrol/js/ui/subevent.js +++ b/src/pretix/static/pretixcontrol/js/ui/subevent.js @@ -26,6 +26,7 @@ $(document).on("pretix:bind-forms", function () { } } + // RRule editor function rrule_preview() { var ruleset = new rrule.RRuleSet(); @@ -121,7 +122,14 @@ $(document).on("pretix:bind-forms", function () { }); } } + $("#rrule-formset").on("change keydown keyup keypress dp.change", "input, select", function () { + rrule_preview(); + }); + rrule_preview(); + $("#rrule-formset").on("formAdded", "div", function (event) {rrule_bind_form($(event.target)); }); + + // Timeslot editor $("#subevent_add_many_slots_go").on("click", function () { $("#time-formset [data-formset-form]").each(function () { var tf = $(this).find("[name$=time_from]").val() @@ -167,13 +175,45 @@ $(document).on("pretix:bind-forms", function () { $(this).addClass("hidden"); }); - $("#rrule-formset").on("change keydown keyup keypress dp.change", "input, select", function () { - rrule_preview(); - }); - rrule_preview(); + // Hide config for products that are not for sale + function quota_form_handlers(el) { + // searchable_selection = True + el.find('[id^="id_quotas-"]').on("select2:select select2:unselect", () => { + update_item_visibility(); + }); + // searchable_selection = False + el.find('input[id^="id_quotas-"][id*=itemvars_]').on("change", () => { + update_item_visibility(); + }); + } + function update_item_visibility() { + const itemvars = []; - $("#rrule-formset").on("formAdded", "div", function (event) { rrule_bind_form($(event.target)); }); + // searchable_selection = True + $("select[id^=id_quotas-][id$=-itemvars]").filter((idx, el) => { + return !$(el).closest('[data-formset-form]').is('[data-formset-form-deleted]'); + }).each((_, e) => itemvars.push(...$(e).val())); + // searchable_selection = False + $("input[id^=id_quotas-][id*=itemvars_]:checked").filter((idx, el) => { + return !$(el).closest('[data-formset-form]').is('[data-formset-form-deleted]'); + }).each((_, e) => itemvars.push($(e).val())); + $("div[data-itemvar]").each(function (idx, e) { + const el = $(e); + el.prop("hidden", !itemvars.includes(el.attr("data-itemvar")) && !el.find(".has-error, .alert-danger").length); + }); + } + + $('[data-formset-prefix="quotas"]').on("formDeleted", "div", () => { + update_item_visibility(); + }).on("formAdded", "div", (event) => { + quota_form_handlers($(event.target)); + update_item_visibility(); + }) + quota_form_handlers($("body")); + update_item_visibility(); + + // Auto-set name of check-in list var $namef = $("input[id^=id_name]").first(); var lastValue = $namef.val(); $namef.change(function () { diff --git a/src/pretix/static/pretixcontrol/scss/_forms.scss b/src/pretix/static/pretixcontrol/scss/_forms.scss index d096df830..f6f2d55f9 100644 --- a/src/pretix/static/pretixcontrol/scss/_forms.scss +++ b/src/pretix/static/pretixcontrol/scss/_forms.scss @@ -91,6 +91,12 @@ td > .form-group > .checkbox { } } +.submit-group-sticky { + position: sticky; + bottom: 0; + z-index: 100; +} + .panel .form-group:last-child { margin-bottom: 0; }