mirror of
https://github.com/lucaspalomodevelop/eventcally.git
synced 2026-03-13 00:07:22 +00:00
Optimize time input #252
This commit is contained in:
parent
d71ecf5ff3
commit
5ae1c10205
@ -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 + '<option value="%d"%s>%02d</option>' % (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(
|
||||
'<div class="input-group-prepend mt-1"><input type="text" {}/></div><div class="mx-2"></div><div class="input-group-append mt-1"><select {}>{}</select><span class="input-group-text">:</span><select {}>{}</select></div>'.format(
|
||||
'<div class="input-group-prepend mt-1"><input type="text" {}/></div><div class="mx-2"></div><div class="input-group-append mt-1"><input {} /></div>'.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(
|
||||
|
||||
@ -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("");
|
||||
|
||||
@ -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',
|
||||
|
||||
@ -55,6 +55,9 @@ $( function() {
|
||||
}
|
||||
});
|
||||
|
||||
$("#start-time").rules("add", "time");
|
||||
$("#end-time").rules("add", "time");
|
||||
|
||||
function update_place_container(value) {
|
||||
switch (value) {
|
||||
case '1':
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -55,6 +55,7 @@
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.4.1/dist/MarkerCluster.Default.css" />
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.4.1/dist/MarkerCluster.css" />
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/leaflet.locatecontrol@0.68.0/dist/L.Control.Locate.min.css" />
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/timepicker@1.13.18/jquery.timepicker.min.css" />
|
||||
{%- block styles %}
|
||||
{%- endblock styles %}
|
||||
|
||||
@ -86,6 +87,7 @@
|
||||
<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js" integrity="sha512-GffPMF3RvMeYyc1LWMHtK8EbPv0iNZ8/oTtHPx9/cc2ILxQ+u905qIwdpULaqDkyBKgOaB57QTMg7ztg8Jm2Og==" crossorigin=""></script>
|
||||
<script src="https://unpkg.com/leaflet.markercluster@1.4.1/dist/leaflet.markercluster.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/leaflet.locatecontrol@0.68.0/dist/L.Control.Locate.min.js" charset="utf-8"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/timepicker@1.13.18/jquery.timepicker.min.js"></script>
|
||||
<script src="{{ url_for('static', filename='jquery.recurrenceinput.js')}}"></script>
|
||||
<script type="text/javascript">
|
||||
var csrf_token = "{{ csrf_token() }}";
|
||||
|
||||
@ -54,6 +54,9 @@
|
||||
}
|
||||
});
|
||||
|
||||
$("#start-time").rules("add", "time");
|
||||
$("#end-time").rules("add", "time");
|
||||
|
||||
wizard.steps({
|
||||
headerTag: "h4",
|
||||
bodyTag: "section",
|
||||
|
||||
@ -214,7 +214,7 @@ class Seeder(object):
|
||||
{
|
||||
"name": "Name",
|
||||
"description": "Beschreibung",
|
||||
"start": ["2030-12-31", "23", "59"],
|
||||
"start": ["2030-12-31", "23:59"],
|
||||
"event_place_id": place_id,
|
||||
"organizer_id": organizer_id,
|
||||
"photo-image_base64": self.get_default_image_upload_base64(),
|
||||
|
||||
@ -44,7 +44,7 @@ def test_create(client, app, utils, seeder, mocker, db_error):
|
||||
{
|
||||
"name": "Name",
|
||||
"description": "Beschreibung",
|
||||
"start": ["2030-12-31", "23", "59"],
|
||||
"start": ["2030-12-31", "23:59"],
|
||||
"event_place_id": place_id,
|
||||
"organizer_id": organizer_id,
|
||||
"photo-image_base64": seeder.get_default_image_upload_base64(),
|
||||
@ -80,7 +80,7 @@ def test_create_newPlaceAndOrganizer(client, app, utils, seeder, mocker):
|
||||
{
|
||||
"name": "Name",
|
||||
"description": "Beschreibung",
|
||||
"start": ["2030-12-31", "23", "59"],
|
||||
"start": ["2030-12-31", "23:59"],
|
||||
"organizer_choice": 2,
|
||||
"new_organizer-name": "Neuer Veranstalter",
|
||||
"event_place_choice": 2,
|
||||
@ -127,7 +127,7 @@ def test_create_missingPlace(client, app, utils, seeder, mocker):
|
||||
{
|
||||
"name": "Name",
|
||||
"description": "Beschreibung",
|
||||
"start": ["2030-12-31", "23", "59"],
|
||||
"start": ["2030-12-31", "23:59"],
|
||||
},
|
||||
)
|
||||
|
||||
@ -148,7 +148,7 @@ def test_create_missingOrganizer(client, app, utils, seeder, mocker):
|
||||
{
|
||||
"name": "Name",
|
||||
"description": "Beschreibung",
|
||||
"start": ["31.12.2030", "23", "59"],
|
||||
"start": ["31.12.2030", "23:59"],
|
||||
"event_place_id": place_id,
|
||||
"organizer_id": organizer_id,
|
||||
},
|
||||
@ -170,7 +170,7 @@ def test_create_invalidDateFormat(client, app, utils, seeder, mocker):
|
||||
{
|
||||
"name": "Name",
|
||||
"description": "Beschreibung",
|
||||
"start": ["2030-12-31", "23", "59"],
|
||||
"start": ["2030-12-31", "23:59"],
|
||||
"event_place_id": place_id,
|
||||
},
|
||||
)
|
||||
@ -190,8 +190,8 @@ def test_create_startAfterEnd(client, app, utils, seeder, mocker):
|
||||
response,
|
||||
{
|
||||
"name": "Name",
|
||||
"start": ["2030-12-31", "23", "59"],
|
||||
"end": ["2030-12-31", "23", "58"],
|
||||
"start": ["2030-12-31", "23:59"],
|
||||
"end": ["2030-12-31", "23:58"],
|
||||
"event_place_id": place_id,
|
||||
},
|
||||
)
|
||||
@ -214,8 +214,8 @@ def test_create_durationMoreThanMaxAllowedDuration(client, app, utils, seeder, m
|
||||
response,
|
||||
{
|
||||
"name": "Name",
|
||||
"start": ["2030-12-30", "12", "00"],
|
||||
"end": ["2031-01-13", "12", "01"],
|
||||
"start": ["2030-12-30", "12:00"],
|
||||
"end": ["2031-01-13", "12:01"],
|
||||
"event_place_id": place_id,
|
||||
},
|
||||
)
|
||||
|
||||
@ -76,7 +76,7 @@ def get_create_data():
|
||||
return {
|
||||
"accept_tos": "y",
|
||||
"name": "Vorschlag",
|
||||
"start": ["2030-12-31", "23", "59"],
|
||||
"start": ["2030-12-31", "23:59"],
|
||||
"contact_name": "Vorname Nachname",
|
||||
"contact_email": "vorname@nachname.de",
|
||||
"contact_email_notice": "y",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user