From dd9c0b3a01ad91d833fbfd4c0ba2c1bf7f2fa12c Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Mon, 17 Apr 2017 21:37:25 +0200 Subject: [PATCH] Add dependencies between form fields --- src/pretix/control/forms/event.py | 30 ++++++++----- src/pretix/static/pretixcontrol/js/ui/main.js | 43 +++++++++++++++++++ .../static/pretixcontrol/scss/_forms.scss | 4 ++ 3 files changed, 67 insertions(+), 10 deletions(-) diff --git a/src/pretix/control/forms/event.py b/src/pretix/control/forms/event.py index 9eb315bca..a13a8475e 100644 --- a/src/pretix/control/forms/event.py +++ b/src/pretix/control/forms/event.py @@ -151,9 +151,10 @@ class EventUpdateForm(I18nModelForm): ] widgets = { 'date_from': forms.DateTimeInput(attrs={'class': 'datetimepicker'}), - 'date_to': forms.DateTimeInput(attrs={'class': 'datetimepicker'}), + 'date_to': forms.DateTimeInput(attrs={'class': 'datetimepicker', 'data-date-after': '#id_date_from'}), 'presale_start': forms.DateTimeInput(attrs={'class': 'datetimepicker'}), - 'presale_end': forms.DateTimeInput(attrs={'class': 'datetimepicker'}), + 'presale_end': forms.DateTimeInput(attrs={'class': 'datetimepicker', + 'data-date-after': '#id_presale_start'}), } @@ -182,6 +183,7 @@ class EventSettingsForm(SettingsForm): presale_start_show_date = forms.BooleanField( label=_("Show start date"), help_text=_("Show the presale start date before presale has started."), + widget=forms.CheckboxInput(attrs={'data-display-dependency': '#id_presale_start'}), required=False ) last_order_modification_date = forms.DateTimeField( @@ -221,24 +223,27 @@ class EventSettingsForm(SettingsForm): min_value=6, help_text=_("If a ticket voucher is sent to a person on the waiting list, it has to be redeemed within this " "number of hours until it expires and can be re-assigned to the next person on the list."), - required=False + required=False, + widget=forms.NumberInput(attrs={'data-display-dependency': '#id_settings-waiting_list_enabled'}), ) waiting_list_auto = forms.BooleanField( label=_("Automatic waiting list assignments"), help_text=_("If ticket capacity becomes free, automatically create a voucher and send it to the first person " "on the waiting list for that product. If this is not active, mails will not be send automatically " "but you can send them manually via the control panel."), - required=False + required=False, + widget=forms.CheckboxInput(attrs={'data-display-dependency': '#id_settings-waiting_list_enabled'}), ) attendee_names_asked = forms.BooleanField( label=_("Ask for attendee names"), help_text=_("Ask for a name for all tickets which include admission to the event."), - required=False + required=False, ) attendee_names_required = forms.BooleanField( label=_("Require attendee names"), help_text=_("Require customers to fill in the names of all attendees."), - required=False + required=False, + widget=forms.CheckboxInput(attrs={'data-checkbox-dependency': '#id_settings-attendee_names_asked'}), ) attendee_emails_asked = forms.BooleanField( label=_("Ask for email addresses per ticket"), @@ -253,7 +258,8 @@ class EventSettingsForm(SettingsForm): help_text=_("Require customers to fill in individual e-mail addresses for all admission tickets. See the " "above option for more details. One email address for the order confirmation will always be " "required regardless of this setting."), - required=False + required=False, + widget=forms.CheckboxInput(attrs={'data-checkbox-dependency': '#id_settings-attendee_emails_asked'}), ) max_items_per_order = forms.IntegerField( min_value=1, @@ -386,11 +392,13 @@ class InvoiceSettingsForm(SettingsForm): ) invoice_address_required = forms.BooleanField( label=_("Require invoice address"), - required=False + required=False, + widget=forms.CheckboxInput(attrs={'data-checkbox-dependency': '#id_invoice_address_asked'}), ) invoice_address_vatid = forms.BooleanField( label=_("Ask for VAT ID"), help_text=_("Does only work if an invoice address is asked for. VAT ID is not required."), + widget=forms.CheckboxInput(attrs={'data-checkbox-dependency': '#id_invoice_address_asked'}), required=False ) invoice_numbers_consecutive = forms.BooleanField( @@ -606,11 +614,13 @@ class TicketSettingsForm(SettingsForm): label=_("Download date"), help_text=_("Ticket download will be offered after this date."), required=True, - widget=forms.DateTimeInput(attrs={'class': 'datetimepicker'}) + widget=forms.DateTimeInput(attrs={'class': 'datetimepicker', + 'data-display-dependency': '#id_ticket_download'}), ) ticket_download_addons = forms.BooleanField( label=_("Offer to download tickets separately for add-on products"), - required=False + required=False, + widget=forms.CheckboxInput(attrs={'data-display-dependency': '#id_ticket_download'}), ) def prepare_fields(self): diff --git a/src/pretix/static/pretixcontrol/js/ui/main.js b/src/pretix/static/pretixcontrol/js/ui/main.js index eff18e0d5..997e507ef 100644 --- a/src/pretix/static/pretixcontrol/js/ui/main.js +++ b/src/pretix/static/pretixcontrol/js/ui/main.js @@ -170,6 +170,49 @@ $(function () { $(this).datetimepicker(opts); }); + $(".datetimepicker[data-date-after], .datepickerfield[data-date-after]").each(function() { + var later_field = $(this), + earlier_field = $($(this).attr("data-date-after")), + update = function () { + var earlier = earlier_field.data('DateTimePicker').date(), + later = later_field.data('DateTimePicker').date(); + if (earlier === null) { + earlier = false; + } else if (later !== null && later.isBefore(earlier) && !later.isSame(earlier)) { + later_field.data('DateTimePicker').date(earlier.add(1, 'h')); + } + later_field.data('DateTimePicker').minDate(earlier); + }; + update(); + earlier_field.on("dp.change", update); + }); + + $("input[data-checkbox-dependency]").each(function () { + var dependent = $(this), + dependency = $($(this).attr("data-checkbox-dependency")), + update = function () { + var enabled = dependency.prop('checked'); + dependent.prop('disabled', !enabled).parents('.form-group').toggleClass('disabled', !enabled); + if (!enabled) { + dependent.prop('checked', false); + } + }; + update(); + dependency.on("change", update); + }); + + $("input[data-display-dependency]").each(function () { + var dependent = $(this), + dependency = $($(this).attr("data-display-dependency")), + update = function () { + var enabled = (dependency.attr("type") === 'checkbox') ? dependency.prop('checked') : !!dependency.val(); + dependent.prop('disabled', !enabled).parents('.form-group').toggleClass('disabled', !enabled); + }; + update(); + dependency.on("change", update); + dependency.on("dp.change", update); + }); + $(".qrcode-canvas").each(function() { $(this).qrcode( { diff --git a/src/pretix/static/pretixcontrol/scss/_forms.scss b/src/pretix/static/pretixcontrol/scss/_forms.scss index 87199030f..7d2968810 100644 --- a/src/pretix/static/pretixcontrol/scss/_forms.scss +++ b/src/pretix/static/pretixcontrol/scss/_forms.scss @@ -26,6 +26,10 @@ td > .form-group > .checkbox { margin-bottom: 0; } +.form-group.disabled { + opacity: 0.5; +} + .form-horizontal [data-formset] .form-group { width: 100%; }