feat(datepicker): new approach stub for formatting dates in formdata

This commit is contained in:
Sarah Vaupel 2019-08-27 15:49:31 +02:00
parent 0998d11312
commit 9ea7b2e3f7
6 changed files with 1609 additions and 1335 deletions

View File

@ -72,10 +72,8 @@ export class AsyncForm {
const url = this._element.getAttribute('action');
const headers = { };
// format any date values before submission
Datepicker.formatAllFormInputDateValues(this._element);
const body = new FormData(this._element);
// create new FormData and format any date values
const body = Datepicker.unformatAll(this._element, new FormData(this._element));
const isModal = this._element.closest(MODAL_SELECTOR);
if (isModal) {

View File

@ -241,7 +241,7 @@ export class AsyncTable {
const url = new URL(getLocalStorageParameter('currentTableUrl') || window.location.href);
// format any date values before submission
Datepicker.formatAllFormInputDateValues(tableFilterForm);
Datepicker.destroyAllFormInputDates(tableFilterForm);
const formData = new FormData(tableFilterForm);
@ -304,10 +304,8 @@ export class AsyncTable {
_changePagesizeHandler = () => {
const url = new URL(getLocalStorageParameter('currentTableUrl') || window.location.href);
// format any date values before submission
Datepicker.formatAllFormInputDateValues(this._pagesizeForm);
const formData = new FormData(this._pagesizeForm);
// create new FormData and format any date values
const formData = Datepicker.unformatAll(this._pagesizeForm, new FormData(this._pagesizeForm));
for (var k of url.searchParams.keys()) {
url.searchParams.delete(k);

View File

@ -1,14 +1,32 @@
import datetime from 'tail.datetime';
import dateFormat from 'dateformat';
import { Utility } from '../../core/utility';
import moment from 'moment';
// formats for displaying all dates and/or times
const FORM_DATE_FORMAT_DATE = 'yyyy-mm-dd';
const FORM_DATE_FORMAT_TIME = 'HH:MM:ss';
const KEYCODE_ESCAPE = 27;
// INTERNAL (Uni2work specific) formats for formatting dates and/or times
const FORM_DATE_FORMAT = {
'date': FORM_DATE_FORMAT_DATE,
'time': FORM_DATE_FORMAT_TIME,
'datetime-local': `${FORM_DATE_FORMAT_DATE}"T"${FORM_DATE_FORMAT_TIME}`,
'date': moment.HTML5_FMT.DATE,
'time': moment.HTML5_FMT.TIME_SECONDS,
'datetime-local': moment.HTML5_FMT.DATETIME_LOCAL_SECONDS,
};
// FANCY (tail.datetime specific) formats for displaying dates and/or times
const FORM_DATE_FORMAT_DATE_DT = 'dd.mm.YYYY';
const FORM_DATE_FORMAT_TIME_DT = 'HH:ii:ss';
// const FORM_DATE_FORMAT_DT = {
// 'date': FORM_DATE_FORMAT_DATE_DT,
// 'time': FORM_DATE_FORMAT_TIME_DT,
// 'datetime-local': `${FORM_DATE_FORMAT_DATE_DT} ${FORM_DATE_FORMAT_TIME_DT}`,
// };
// FANCY (moment specific) formats for displaying dates and/or times
const FORM_DATE_FORMAT_DATE_MOMENT = 'DD.MM.YYYY';
const FORM_DATE_FORMAT_TIME_MOMENT = 'HH:mm:ss';
const FORM_DATE_FORMAT_MOMENT = {
'date': FORM_DATE_FORMAT_DATE_MOMENT,
'time': FORM_DATE_FORMAT_TIME_MOMENT,
'datetime-local': `${FORM_DATE_FORMAT_DATE_MOMENT} ${FORM_DATE_FORMAT_TIME_MOMENT}`,
};
const DATEPICKER_UTIL_SELECTOR = 'input[type="date"], input[type="time"], input[type="datetime-local"]';
@ -29,7 +47,8 @@ const DATEPICKER_CONFIG = {
// TODO: hardcoded, get from current language / settings
locale: 'de',
weekStart: 1,
dateFormat: 'dd.mm.YYYY',
dateFormat: FORM_DATE_FORMAT_DATE_DT,
timeFormat: FORM_DATE_FORMAT_TIME_DT,
// prevent the instance from closing when selecting a date before selecting a time
stayOpen: true,
@ -116,6 +135,15 @@ export class Datepicker {
// mark the form input element as initialized
this._element.classList.add(DATEPICKER_INITIALIZED_CLASS);
const changeEvent = () => {
const parsedDate = moment(this._element.value, FORM_DATE_FORMAT_MOMENT[this.elementType]).toDate();
this.datepickerInstance.selectDate(parsedDate);
// reregister change event to prevent event loop
this._element.addEventListener('change', changeEvent, { once: true });
};
// change the selected date in the tail.datetime instance if the value of the input element is changed
this._element.addEventListener('change', changeEvent, { once: true });
// close the instance if something other than the instance was clicked (i.e. if the target is not within the datepicker instance and if any previously clicked calendar view was replaced (is not in the window anymore) because it was clicked). YES, I KNOW
window.addEventListener('click', event => {
if (!this.datepickerInstance.dt.contains(event.target) && window.document.contains(event.target)) {
@ -125,47 +153,75 @@ export class Datepicker {
// close the datepicker on escape keydown events
this._element.addEventListener('keydown', event => {
if (event.keyCode === 27) {
if (event.keyCode === KEYCODE_ESCAPE) {
this.datepickerInstance.close();
}
});
// format the date value of the form input element of this datepicker before form submission
this._element.form.addEventListener('submit', () => this.formatElementValue());
// format any existing dates to fancy display format on pageload
this.formatElementValue(true);
}
destroy() {
this.datepickerInstance.destroy();
this.datepickerInstance.remove();
}
/**
* Formats the value of this input element from datepicker format (i.e. DATEPICKER_CONFIG.dateFormat + " " + datetime.defaults.timeFormat) to Uni2work internal date format (i.e. FORM_DATE_FORMAT) required for form submission
* @param {*} toFancy optional target format switch (boolean value; default is false). If set to a truthy value, formats the element value to fancy instead of internal date format.
*/
formatElementValue() {
if (!this.datepickerInstance.select || !this._element.value) return;
this._element.value = dateFormat(this.datepickerInstance.select, FORM_DATE_FORMAT[this.elementType]);
formatElementValue(toFancy) {
// console.log("Hello from formatElementValue with toFancy ", toFancy, " and element value ", this._element.value, " and datepicker instance ", this.datepickerInstance);
const dp = this.datepickerInstance;
if (this._element.value) {
if (toFancy) {
// console.log(" toFancy");
const d = new Date(this._element.value);
// console.log(" calling selectDate with ", d);
dp.selectDate(d);
} else {
// console.log(" not toFancy");
this._element.value = this.unformat();
// console.log(" new element value is ", this._element.value);
}
}
}
/**
* Calls formatElementValue on all datepicker objects registered for a form.
* @param {*} form form for which all datepicker date values should be formatted
* Returns a datestring in internal format from the current state of the input element value.
*/
static formatAllFormInputDateValues(form) {
if (!Datepicker.datepickerCollections) {
// no datepicker collections yet (i.e. constructor was never called) => do nothing
return;
}
// if the form has no id, assign one randomly
if (!form.id) {
form.id = `f${Math.floor(Math.random() * 100000)}`;
unformat() {
return moment(this._element.value, FORM_DATE_FORMAT_MOMENT[this.elementType]).format(FORM_DATE_FORMAT[this.elementType]);
}
/**
* Takes a Form and a FormData and returns a new FormData with all dates formatted to uni2work date format. This function will not change the value of the date input elements.
* @param {*} form Form for which all dates will be formatted in the FormData
* @param {*} formData Initial FormData
*/
static unformatAll(form, formData) {
// only proceed if there are any datepickers and if both form and formData are defined
if (Datepicker.datepickerCollections && form && formData) {
// if the form has no id, assign one randomly
if (!form.id) {
form.id = `f${Math.floor(Math.random() * 100000)}`;
}
const formId = form.id;
if (Datepicker.datepickerCollections.has(formId)) {
const datepickerInstances = Datepicker.datepickerCollections.get(formId);
datepickerInstances.forEach(instance => {
formData.set(instance._element.name, instance.unformat());
});
}
}
const formID = form.id;
if (Datepicker.datepickerCollections.has(formID)) {
const datepickerInstances = Datepicker.datepickerCollections.get(formID);
datepickerInstances.forEach(instance => instance.formatElementValue());
}
// return the (possibly changed) FormData
return formData;
}
}

View File

@ -158,10 +158,8 @@ export class MassInput {
}
_serializeForm(submitButton, enctype) {
// format any date values before submission
Datepicker.formatAllFormInputDateValues(this._massInputForm);
const formData = new FormData(this._massInputForm);
// create new FormData and format any date values
const formData = Datepicker.unformatAll(this._massInputForm, new FormData(this._massInputForm));
// manually add name and value of submit button to formData
formData.append(submitButton.name, submitButton.value);

2775
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -49,16 +49,16 @@
"defaults"
],
"devDependencies": {
"@babel/cli": "^7.4.4",
"@babel/core": "^7.4.5",
"@babel/plugin-proposal-class-properties": "^7.4.4",
"@babel/cli": "^7.5.5",
"@babel/core": "^7.5.5",
"@babel/plugin-proposal-class-properties": "^7.5.5",
"@babel/plugin-proposal-decorators": "^7.4.4",
"@babel/preset-env": "^7.4.5",
"@babel/preset-env": "^7.5.5",
"@commitlint/cli": "^8.1.0",
"@commitlint/config-conventional": "^8.0.0",
"autoprefixer": "^9.6.0",
"@commitlint/config-conventional": "^8.1.0",
"autoprefixer": "^9.6.1",
"babel-core": "^6.26.3",
"babel-eslint": "^10.0.1",
"babel-eslint": "^10.0.3",
"babel-loader": "^8.0.6",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"babel-plugin-transform-decorators-legacy": "^1.3.5",
@ -66,9 +66,9 @@
"css-loader": "^2.1.1",
"eslint": "^5.16.0",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"husky": "^2.4.1",
"husky": "^2.7.0",
"jasmine-core": "^3.4.0",
"karma": "^4.1.0",
"karma": "^4.2.0",
"karma-chrome-launcher": "^2.2.0",
"karma-cli": "^2.0.0",
"karma-jasmine": "^2.0.1",
@ -81,17 +81,16 @@
"npm-run-all": "^4.1.5",
"null-loader": "^2.0.0",
"postcss-loader": "^3.0.0",
"sass-loader": "^7.1.0",
"sass-loader": "^7.3.1",
"standard-version": "^6.0.1",
"style-loader": "^0.23.1",
"uglifyjs-webpack-plugin": "^2.1.3",
"webpack": "^4.34.0",
"webpack-cli": "^3.3.4"
"uglifyjs-webpack-plugin": "^2.2.0",
"webpack": "^4.39.3",
"webpack-cli": "^3.3.7"
},
"dependencies": {
"dateformat": "^3.0.3",
"flatpickr": "^4.5.7",
"npm": "^6.10.3",
"tail.datetime": "git+https://git@github.com/uni2work/tail.DateTime.git#master"
"moment": "^2.24.0",
"npm": "^6.11.2",
"tail.datetime": "git+https://git@github.com/uni2work/tail.DateTime.git#update-view-on-select"
}
}