diff --git a/src/pretix/base/reldate.py b/src/pretix/base/reldate.py index aeb9cd703f..79d49b82f5 100644 --- a/src/pretix/base/reldate.py +++ b/src/pretix/base/reldate.py @@ -28,6 +28,9 @@ from dateutil import parser from django import forms from django.core.exceptions import ValidationError from django.db import models +from django.utils.formats import get_format +from django.utils.functional import lazy +from django.utils.timezone import now from django.utils.translation import gettext_lazy as _ from rest_framework import serializers @@ -206,14 +209,27 @@ class RelativeDateTimeWidget(forms.MultiWidget): def __init__(self, *args, **kwargs): self.status_choices = kwargs.pop('status_choices') base_choices = kwargs.pop('base_choices') + + def placeholder_datetime_format(): + df = get_format('DATETIME_INPUT_FORMATS')[0] + return now().replace( + year=2000, month=12, day=31, hour=18, minute=0, second=0, microsecond=0 + ).strftime(df) + + def placeholder_time_format(): + tf = get_format('TIME_INPUT_FORMATS')[0] + return datetime.time(8, 30, 0).strftime(tf) + widgets = reldatetimeparts( status=forms.RadioSelect(choices=self.status_choices), absolute=forms.DateTimeInput( - attrs={'class': 'datetimepicker'} + attrs={'placeholder': lazy(placeholder_datetime_format, str), 'class': 'datetimepicker'} ), rel_days_number=forms.NumberInput(), rel_mins_relationto=forms.Select(choices=base_choices), - rel_days_timeofday=forms.TimeInput(attrs={'placeholder': _('Time'), 'class': 'timepickerfield'}), + rel_days_timeofday=forms.TimeInput( + attrs={'placeholder': lazy(placeholder_time_format, str), 'class': 'timepickerfield'} + ), rel_mins_number=forms.NumberInput(), rel_days_relationto=forms.Select(choices=base_choices), rel_mins_relation=forms.Select(choices=BEFORE_AFTER_CHOICE), diff --git a/src/pretix/control/forms/event.py b/src/pretix/control/forms/event.py index ffd1fbacdf..427447ab35 100644 --- a/src/pretix/control/forms/event.py +++ b/src/pretix/control/forms/event.py @@ -113,7 +113,6 @@ class EventWizardFoundationForm(forms.Form): attrs={ 'data-model-select2': 'generic', 'data-select2-url': reverse('control:organizers.select2') + '?can_create=1', - 'data-placeholder': _('Organizer') } ), empty_label=None, diff --git a/src/pretix/control/forms/filter.py b/src/pretix/control/forms/filter.py index 1c3a711958..abb66f03f1 100644 --- a/src/pretix/control/forms/filter.py +++ b/src/pretix/control/forms/filter.py @@ -1246,9 +1246,7 @@ class SubEventFilterForm(FilterForm): ) query = forms.CharField( label=_('Event name'), - widget=forms.TextInput(attrs={ - 'placeholder': _('Event name'), - }), + widget=forms.TextInput(), required=False ) @@ -1693,9 +1691,7 @@ class EventFilterForm(FilterForm): ) query = forms.CharField( label=_('Event name'), - widget=forms.TextInput(attrs={ - 'placeholder': _('Event name'), - }), + widget=forms.TextInput(), required=False ) date_from = forms.DateField( @@ -2448,7 +2444,7 @@ class CheckinFilterForm(FilterForm): 'event': self.event.slug, 'organizer': self.event.organizer.slug, }), - 'data-placeholder': _('Check-in list'), + 'data-placeholder': _('All check-in lists'), } ) self.fields['checkin_list'].widget.choices = self.fields['checkin_list'].choices diff --git a/src/pretix/control/forms/item.py b/src/pretix/control/forms/item.py index 029ff585c6..06aa2496bb 100644 --- a/src/pretix/control/forms/item.py +++ b/src/pretix/control/forms/item.py @@ -47,9 +47,7 @@ from django.urls import reverse from django.utils.functional import cached_property from django.utils.html import escape, format_html from django.utils.safestring import mark_safe -from django.utils.translation import ( - gettext as __, gettext_lazy as _, pgettext_lazy, -) +from django.utils.translation import gettext as __, gettext_lazy as _ from django_scopes.forms import ( SafeModelChoiceField, SafeModelMultipleChoiceField, ) @@ -330,7 +328,6 @@ class QuotaForm(I18nModelForm): 'event': self.event.slug, 'organizer': self.event.organizer.slug, }), - 'data-placeholder': pgettext_lazy('subevent', 'Date') } ) self.fields['subevent'].widget.choices = self.fields['subevent'].choices @@ -352,6 +349,9 @@ class QuotaForm(I18nModelForm): field_classes = { 'subevent': SafeModelChoiceField, } + widgets = { + 'size': forms.NumberInput(attrs={'placeholder': _('Unlimited')}) + } def save(self, *args, **kwargs): creating = not self.instance.pk diff --git a/src/pretix/control/forms/orders.py b/src/pretix/control/forms/orders.py index 737c6aca31..881920fca1 100644 --- a/src/pretix/control/forms/orders.py +++ b/src/pretix/control/forms/orders.py @@ -409,7 +409,6 @@ class OrderPositionAddForm(forms.Form): 'event': order.event.slug, 'organizer': order.event.organizer.slug, }), - 'data-placeholder': pgettext_lazy('subevent', 'Date') } ) self.fields['subevent'].widget.choices = self.fields['subevent'].choices @@ -705,7 +704,6 @@ class OrderContactForm(forms.ModelForm): 'data-select2-url': reverse('control:organizer.customers.select2', kwargs={ 'organizer': self.instance.event.organizer.slug, }), - 'data-placeholder': _('Customer') } ) self.fields['customer'].widget.choices = self.fields['customer'].choices diff --git a/src/pretix/control/forms/organizer.py b/src/pretix/control/forms/organizer.py index 14814ce269..4060c89b49 100644 --- a/src/pretix/control/forms/organizer.py +++ b/src/pretix/control/forms/organizer.py @@ -781,7 +781,6 @@ class GiftCardUpdateForm(forms.ModelForm): 'data-select2-url': reverse('control:organizer.ticket_select2', kwargs={ 'organizer': organizer.slug, }), - 'data-placeholder': _('Ticket') } ) self.fields['owner_ticket'].widget.choices = self.fields['owner_ticket'].choices @@ -817,7 +816,6 @@ class ReusableMediumUpdateForm(forms.ModelForm): 'data-select2-url': reverse('control:organizer.ticket_select2', kwargs={ 'organizer': organizer.slug, }), - 'data-placeholder': _('Ticket') } ) self.fields['linked_orderposition'].widget.choices = self.fields['linked_orderposition'].choices @@ -830,7 +828,6 @@ class ReusableMediumUpdateForm(forms.ModelForm): 'data-select2-url': reverse('control:organizer.giftcards.select2', kwargs={ 'organizer': organizer.slug, }), - 'data-placeholder': _('Gift card') } ) self.fields['linked_giftcard'].widget.choices = self.fields['linked_giftcard'].choices @@ -844,7 +841,6 @@ class ReusableMediumUpdateForm(forms.ModelForm): 'data-select2-url': reverse('control:organizer.customers.select2', kwargs={ 'organizer': organizer.slug, }), - 'data-placeholder': _('Customer') } ) self.fields['customer'].widget.choices = self.fields['customer'].choices diff --git a/src/pretix/control/forms/subevents.py b/src/pretix/control/forms/subevents.py index 1329a1bc8e..c0fcc6f29f 100644 --- a/src/pretix/control/forms/subevents.py +++ b/src/pretix/control/forms/subevents.py @@ -133,16 +133,12 @@ class SubEventBulkEditForm(I18nModelForm): # i18n fields if k in self.mixed_values: self.fields[k].widget.attrs['placeholder'] = '[{}]'.format(_('Selection contains various values')) - else: - self.fields[k].widget.attrs['placeholder'] = '' self.fields[k].one_required = False for k in ('geo_lat', 'geo_lon', 'comment'): # scalar fields if k in self.mixed_values: self.fields[k].widget.attrs['placeholder'] = '[{}]'.format(_('Selection contains various values')) - else: - self.fields[k].widget.attrs['placeholder'] = '' self.fields[k].widget.is_required = False self.fields[k].required = False diff --git a/src/pretix/control/forms/vouchers.py b/src/pretix/control/forms/vouchers.py index ff8abe336d..917dea87ab 100644 --- a/src/pretix/control/forms/vouchers.py +++ b/src/pretix/control/forms/vouchers.py @@ -41,7 +41,7 @@ from django.core.exceptions import ObjectDoesNotExist, ValidationError from django.core.validators import EmailValidator from django.db.models.functions import Upper from django.urls import reverse -from django.utils.translation import gettext_lazy as _, pgettext_lazy +from django.utils.translation import gettext_lazy as _ from django_scopes.forms import SafeModelChoiceField from pretix.base.email import get_available_placeholders @@ -115,7 +115,6 @@ class VoucherForm(I18nModelForm): 'event': instance.event.slug, 'organizer': instance.event.organizer.slug, }), - 'data-placeholder': pgettext_lazy('subevent', 'Date') } ) self.fields['subevent'].widget.choices = self.fields['subevent'].choices diff --git a/src/pretix/control/templates/pretixcontrol/event/fragment_geodata.html b/src/pretix/control/templates/pretixcontrol/event/fragment_geodata.html index c36a4de900..62664abe13 100644 --- a/src/pretix/control/templates/pretixcontrol/event/fragment_geodata.html +++ b/src/pretix/control/templates/pretixcontrol/event/fragment_geodata.html @@ -15,7 +15,7 @@ {% trans "Optional" %}
- {% bootstrap_field form.geo_lat layout="inline" %} + {% bootstrap_field form.geo_lat layout="inline" placeholder=_("Latitude") %} {% if global_settings.opencagedata_apikey %}

@@ -25,7 +25,7 @@ {% endif %}

- {% bootstrap_field form.geo_lon layout="inline" %} + {% bootstrap_field form.geo_lon layout="inline" placeholder=_("Longitude") %}
diff --git a/src/pretix/control/templates/pretixcontrol/subevents/bulk.html b/src/pretix/control/templates/pretixcontrol/subevents/bulk.html index 1caaabcb22..ba82ccdd70 100644 --- a/src/pretix/control/templates/pretixcontrol/subevents/bulk.html +++ b/src/pretix/control/templates/pretixcontrol/subevents/bulk.html @@ -289,13 +289,13 @@ {% bootstrap_field f.DELETE form_group_class="" layout="inline" %}
- {% bootstrap_field f.time_from layout="inline" %} + {% bootstrap_field f.time_from layout="inline" placeholder=time_begin_sample %}
- {% bootstrap_field f.time_to layout="inline" %} + {% bootstrap_field f.time_to layout="inline" placeholder=time_end_sample %}
- {% bootstrap_field f.time_admission layout="inline" %} + {% bootstrap_field f.time_admission layout="inline" placeholder=time_admission_sample %}
- +
{% trans "Quotas" %} diff --git a/src/pretix/control/templates/pretixcontrol/subevents/bulk_edit.html b/src/pretix/control/templates/pretixcontrol/subevents/bulk_edit.html index e6c9898953..8770301c5c 100644 --- a/src/pretix/control/templates/pretixcontrol/subevents/bulk_edit.html +++ b/src/pretix/control/templates/pretixcontrol/subevents/bulk_edit.html @@ -51,7 +51,7 @@ diff --git a/src/pretix/control/views/subevents.py b/src/pretix/control/views/subevents.py index 6c6b043f6e..e047f5f308 100644 --- a/src/pretix/control/views/subevents.py +++ b/src/pretix/control/views/subevents.py @@ -49,7 +49,7 @@ from django.shortcuts import redirect, render from django.urls import reverse from django.utils.formats import get_format from django.utils.functional import cached_property -from django.utils.timezone import make_aware +from django.utils.timezone import make_aware, now from django.utils.translation import gettext_lazy as _, pgettext_lazy from django.views import View from django.views.generic import CreateView, FormView, ListView, UpdateView @@ -768,8 +768,15 @@ class SubEventBulkCreate(SubEventEditorMixin, EventPermissionRequiredMixin, Asyn ctx['time_formset'] = self.time_formset tf = get_format('TIME_INPUT_FORMATS')[0] + ctx['time_admission_sample'] = time(8, 30, 0).strftime(tf) ctx['time_begin_sample'] = time(9, 0, 0).strftime(tf) ctx['time_end_sample'] = time(18, 0, 0).strftime(tf) + + df = get_format('DATETIME_INPUT_FORMATS')[0] + ctx['datetime_sample'] = now().replace( + year=2000, month=12, day=31, hour=18, minute=0, second=0, microsecond=0 + ).strftime(df) + return ctx @cached_property diff --git a/src/pretix/plugins/autocheckin/forms.py b/src/pretix/plugins/autocheckin/forms.py index f7ddcb8071..3366243865 100644 --- a/src/pretix/plugins/autocheckin/forms.py +++ b/src/pretix/plugins/autocheckin/forms.py @@ -176,7 +176,6 @@ class AutoCheckinRuleForm(forms.ModelForm): "organizer": self.event.organizer.slug, }, ), - "data-placeholder": _("Check-in list"), } ) self.fields["list"].widget.choices = self.fields["list"].choices diff --git a/src/pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/new_refund_control_form.html b/src/pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/new_refund_control_form.html index 822a27854d..5442ee643d 100644 --- a/src/pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/new_refund_control_form.html +++ b/src/pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/new_refund_control_form.html @@ -2,7 +2,7 @@ {% load ibanformat %} {% load bootstrap3 %} -{% bootstrap_field form.payer layout="inline" %} -{% bootstrap_field form.iban layout="inline" %} -{% bootstrap_field form.bic layout="inline" %} +{% bootstrap_field form.payer layout="inline" placeholder=_("Account holder") %} +{% bootstrap_field form.iban layout="inline" placeholder=_("IBAN") %} +{% bootstrap_field form.bic layout="inline" placeholder=_("BIC (optional)") %} {% bootstrap_form_errors form error_types="all" %} diff --git a/src/pretix/plugins/sendmail/forms.py b/src/pretix/plugins/sendmail/forms.py index 5d46c7a76b..319f5a9519 100644 --- a/src/pretix/plugins/sendmail/forms.py +++ b/src/pretix/plugins/sendmail/forms.py @@ -279,7 +279,6 @@ class OrderMailForm(BaseMailForm): 'event': event.slug, 'organizer': event.organizer.slug, }), - 'data-placeholder': pgettext_lazy('subevent', 'Date') } ) self.fields['subevent'].widget.choices = self.fields['subevent'].choices @@ -360,7 +359,6 @@ class RuleForm(FormPlaceholderMixin, I18nModelForm): 'event': self.event.slug, 'organizer': self.event.organizer.slug, }), - 'data-placeholder': pgettext_lazy('subevent', 'Date') } ) self.fields['subevent'].widget.choices = self.fields['subevent'].choices diff --git a/src/pretix/settings.py b/src/pretix/settings.py index efc7c7daeb..e25555e47d 100644 --- a/src/pretix/settings.py +++ b/src/pretix/settings.py @@ -711,6 +711,7 @@ BOOTSTRAP3 = { 'bulkedit_inline': 'pretix.control.forms.renderers.InlineBulkEditFieldRenderer', 'checkout': 'pretix.presale.forms.renderers.CheckoutFieldRenderer', }, + 'set_placeholder': False, } PASSWORD_HASHERS = [ diff --git a/src/pretix/static/pretixcontrol/scss/auth.scss b/src/pretix/static/pretixcontrol/scss/auth.scss index f5a6513720..4760a79254 100644 --- a/src/pretix/static/pretixcontrol/scss/auth.scss +++ b/src/pretix/static/pretixcontrol/scss/auth.scss @@ -34,10 +34,6 @@ footer { margin: auto; padding-bottom: 0; - .control-label { - display: none; - } - .buttons { text-align: right; }