diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 96580f3e1728884b31900234a92313ffe488b265..f1e79e5ab9054bccbd00a2414a424205e2e1e436 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -23,6 +23,7 @@ Fixed * Some combinations of allowed self-edit fields on persons could cause errors * Some preferences were required when they shouldn't, and vice versa. * IO errors on accessing backup directory in health check are now properly reported +* Date picker was not properly initialized if field was already filled. `2.6`_ - 2022-01-10 ------------------- diff --git a/aleksis/core/settings.py b/aleksis/core/settings.py index 05a460d13da4560a2aa8d07b18647e962800b925..4acb398f7762f40775864e50cbfd1d5bf4b62d58 100644 --- a/aleksis/core/settings.py +++ b/aleksis/core/settings.py @@ -550,6 +550,7 @@ YARN_INSTALLED_APPS = [ "jquery-sortablejs", "sortablejs", "@sentry/tracing", + "luxon", ] merge_app_settings("YARN_INSTALLED_APPS", YARN_INSTALLED_APPS, True) @@ -582,6 +583,7 @@ ANY_JS = { "Roboto900": {"css_url": JS_URL + "/@fontsource/roboto/900.css"}, "Sentry": {"js_url": JS_URL + "/@sentry/tracing/build/bundle.tracing.js"}, "cleavejs": {"js_url": "cleave.js/dist/cleave.min.js"}, + "luxon": {"js_url": JS_URL + "/luxon/build/global/luxon.min.js"}, } merge_app_settings("ANY_JS", ANY_JS, True) diff --git a/aleksis/core/static/js/main.js b/aleksis/core/static/js/main.js index 0610cbae2c6904572ae4b8b6714a12b67382c133..9b4c133e1ae7db5906645963cfd7182da313ca01 100644 --- a/aleksis/core/static/js/main.js +++ b/aleksis/core/static/js/main.js @@ -1,8 +1,59 @@ +// Define maps between Python's strftime and Luxon's and Materialize's proprietary formats +const pythonToMomentJs = { + "%a": "EEE", + "%A": "EEEE", + "%w": "E", + "%d": "dd", + "%b": "MMM", + "%B": "MMMM", + "%m": "MM", + "%y": "yy", + "%Y": "yyyy", + "%H": "HH", + "%I": "hh", + "%p": "a", + "%M": "mm", + "%s": "ss", + "%f": "SSSSSS", + "%z": "ZZZ", + "%Z": "z", + "%U": "WW", + "%j": "ooo", + "%W": "WW", + "%u": "E", + "%G": "kkkk", + "%V": "WW", +}; + +const pythonToMaterialize = { + "%d": "dd", + "%a": "ddd", + "%A": "dddd", + "%m": "mm", + "%b": "mmm", + "%B": "mmmm", + "%y": "yy", + "%Y": "yyyy", +} + +function buildDateFormat(formatString, map) { + // Convert a Python strftime format string to another format string + for (const key in map) { + formatString = formatString.replace(key, map[key]); + } + return formatString; +} + function initDatePicker(sel) { // Initialize datepicker [MAT] - const format = get_format('SHORT_DATE_FORMAT').toLowerCase().replace('d', 'dd').replace('m', 'mm').replace('y', 'yyyy'); + + // Get the date format from Django + const dateInputFormat = get_format('DATE_INPUT_FORMATS')[0] + const inputFormat = buildDateFormat(dateInputFormat, pythonToMomentJs); + const outputFormat = buildDateFormat(dateInputFormat, pythonToMaterialize); + const el = $(sel).datepicker({ - format: format, + format: outputFormat, // Pull translations from Django helpers i18n: { months: calendarweek_i18n.month_names, @@ -22,7 +73,16 @@ function initDatePicker(sel) { autoClose: true, yearRange: [new Date().getFullYear() - 100, new Date().getFullYear() + 100], }); - el.datepicker("setDate", $(sel).val()); + + // Set initial values of datepickers + $(sel).each(function () { + const currentValue = $(this).val(); + if (currentValue) { + const currentDate = luxon.DateTime.fromFormat(currentValue, inputFormat).toJSDate(); + $(this).datepicker('setDate', currentDate); + } + }); + return el; } diff --git a/aleksis/core/templates/core/base.html b/aleksis/core/templates/core/base.html index 7fd4e38f8449b0a649fcd01e08051a2332070a15..745a6668cdc42eb265536950a0acbecfb57ee537 100644 --- a/aleksis/core/templates/core/base.html +++ b/aleksis/core/templates/core/base.html @@ -201,6 +201,7 @@ </footer> +{% include_js "luxon" %} {% include_js "materialize" %} {% include_js "sortablejs" %} {% include_js "jquery-sortablejs" %}