From 5ae1c10205c9856635900258145897e9d2888a09 Mon Sep 17 00:00:00 2001 From: Daniel Grams Date: Sun, 8 Aug 2021 22:57:46 +0200 Subject: [PATCH] Optimize time input #252 --- project/forms/widgets.py | 42 +++++++------------ project/static/site.js | 18 ++++---- project/templates/_macros.html | 4 ++ project/templates/event/create.html | 3 ++ project/templates/event/update.html | 3 ++ project/templates/layout.html | 2 + .../widget/event_suggestion/create.html | 3 ++ tests/seeder.py | 2 +- tests/views/test_event.py | 18 ++++---- tests/views/test_widget.py | 2 +- 10 files changed, 50 insertions(+), 47 deletions(-) diff --git a/project/forms/widgets.py b/project/forms/widgets.py index 8cf791d..729614c 100644 --- a/project/forms/widgets.py +++ b/project/forms/widgets.py @@ -15,24 +15,15 @@ class MultiCheckboxField(SelectMultipleField): option_widget = CheckboxInput() -def create_option_string(count, value): - result = "" - for i in range(count): - selected = " selected" if i == value else "" - result = result + '' % (i, selected, i) - return result - - class CustomDateTimeWidget: def __call__(self, field, **kwargs): id = kwargs.pop("id", field.id) date = "" - hour = minute = 0 + time = "" if field.data: date_value = to_user_timezone(field.data) date = date_value.strftime("%Y-%m-%d") - hour = date_value.hour - minute = date_value.minute + time = date_value.strftime("%H:%M") kwargs_class = kwargs.pop("class", "") @@ -45,20 +36,21 @@ class CustomDateTimeWidget: class_=date_class, **kwargs ) - time_hour_params = html_params( - name=field.name, id=id + "-hour", class_=kwargs_class, **kwargs - ) - time_minute_params = html_params( - name=field.name, id=id + "-minute", class_=kwargs_class, **kwargs + + time_class = kwargs_class + " timepicker" + time_params = html_params( + name=field.name, + id=id + "-time", + value=time, + required=field.flags.required, + class_=time_class, + **kwargs ) return Markup( - '
:
'.format( + '
'.format( date_params, - time_hour_params, - create_option_string(24, hour), - time_minute_params, - create_option_string(60, minute), + time_params, ) ) @@ -69,15 +61,13 @@ class CustomDateTimeField(DateTimeField): def process_formdata(self, valuelist): if valuelist: try: - date_str, hour_str, minute_str = valuelist + date_str, time_str = valuelist if not date_str: self.data = None return - date = datetime.strptime(date_str, "%Y-%m-%d") - date_time = datetime( - date.year, date.month, date.day, int(hour_str), int(minute_str) - ) + date_time_str = date_str + " " + time_str + date_time = datetime.strptime(date_time_str, "%Y-%m-%d %H:%M") self.data = berlin_tz.localize(date_time) except Exception: raise ValueError( diff --git a/project/static/site.js b/project/static/site.js index ef3d956..3a776bd 100644 --- a/project/static/site.js +++ b/project/static/site.js @@ -99,7 +99,8 @@ jQuery.tools.recurrenceinput.localize('de', { }); function get_moment_with_time(field_id) { - return moment($(field_id).val()).add($(field_id + "-hour").val(), "hour").add($(field_id + "-minute").val(), "minute"); + date_time_string = $(field_id).val() + ' ' + $(field_id + "-time").val(); + return moment(date_time_string); } function set_date_bounds(picker) { @@ -143,10 +144,7 @@ function set_picker_date(picker, date, timeout = -1) { picker.datepicker("setDate", date); var hidden_field_id = picker.attr('id').replace('-user', ''); - var hour = date == null ? 0 : date.getHours(); - var minute = date == null ? 0 : date.getMinutes(); - $("#" + hidden_field_id + "-hour").val(hour.toString()); - $("#" + hidden_field_id + "-minute").val(minute.toString()); + $("#" + hidden_field_id + "-time").timepicker('setTime', date); if (timeout < 0) { set_date_bounds(picker); @@ -214,11 +212,7 @@ function start_datepicker(input) { } }); - $("#" + hidden_field_id + "-hour").change(function() { - set_date_bounds(picker); - }); - - $("#" + hidden_field_id + "-minute").change(function() { + $("#" + hidden_field_id + "-time").change(function() { set_date_bounds(picker); }); @@ -314,6 +308,10 @@ $( function() { start_datepicker($(element)); }); + $('.timepicker').timepicker({ + timeFormat: 'H:i' + }); + $("#clear_location_btn").click(function () { $("#coordinate").val(""); $("#location").val(""); diff --git a/project/templates/_macros.html b/project/templates/_macros.html index f12265a..31083a2 100644 --- a/project/templates/_macros.html +++ b/project/templates/_macros.html @@ -1209,6 +1209,10 @@ if (URL) { return end <= max; }, jQuery.validator.format("{{ _('An event can last a maximum of 14 days.') }}")); + $.validator.addMethod( "time", function( value, element ) { + return this.optional( element ) || /^([01]\d|2[0-3]|[0-9])(:[0-5]\d){1,2}$/.test( value ); + }, jQuery.validator.format("{{ _('Please enter a valid time, between 00:00 and 23:59.') }}")); + jQuery.validator.setDefaults({ errorElement: 'div', errorClass: 'invalid-feedback', diff --git a/project/templates/event/create.html b/project/templates/event/create.html index 178d156..b5670ea 100644 --- a/project/templates/event/create.html +++ b/project/templates/event/create.html @@ -55,6 +55,9 @@ $( function() { } }); + $("#start-time").rules("add", "time"); + $("#end-time").rules("add", "time"); + function update_place_container(value) { switch (value) { case '1': diff --git a/project/templates/event/update.html b/project/templates/event/update.html index 790035f..5481752 100644 --- a/project/templates/event/update.html +++ b/project/templates/event/update.html @@ -26,6 +26,9 @@ } }); + $("#start-time").rules("add", "time"); + $("#end-time").rules("add", "time"); + // Organizer var organizer_select =$('#organizer_id'); var input_group = organizer_select.parent(); diff --git a/project/templates/layout.html b/project/templates/layout.html index 5b3d0ed..65ad30c 100644 --- a/project/templates/layout.html +++ b/project/templates/layout.html @@ -55,6 +55,7 @@ + {%- block styles %} {%- endblock styles %} @@ -86,6 +87,7 @@ +