feat(datepicker): new approach stub for formatting dates in formdata
This commit is contained in:
parent
0998d11312
commit
9ea7b2e3f7
@ -72,10 +72,8 @@ export class AsyncForm {
|
|||||||
const url = this._element.getAttribute('action');
|
const url = this._element.getAttribute('action');
|
||||||
const headers = { };
|
const headers = { };
|
||||||
|
|
||||||
// format any date values before submission
|
// create new FormData and format any date values
|
||||||
Datepicker.formatAllFormInputDateValues(this._element);
|
const body = Datepicker.unformatAll(this._element, new FormData(this._element));
|
||||||
|
|
||||||
const body = new FormData(this._element);
|
|
||||||
|
|
||||||
const isModal = this._element.closest(MODAL_SELECTOR);
|
const isModal = this._element.closest(MODAL_SELECTOR);
|
||||||
if (isModal) {
|
if (isModal) {
|
||||||
|
|||||||
@ -241,7 +241,7 @@ export class AsyncTable {
|
|||||||
const url = new URL(getLocalStorageParameter('currentTableUrl') || window.location.href);
|
const url = new URL(getLocalStorageParameter('currentTableUrl') || window.location.href);
|
||||||
|
|
||||||
// format any date values before submission
|
// format any date values before submission
|
||||||
Datepicker.formatAllFormInputDateValues(tableFilterForm);
|
Datepicker.destroyAllFormInputDates(tableFilterForm);
|
||||||
|
|
||||||
const formData = new FormData(tableFilterForm);
|
const formData = new FormData(tableFilterForm);
|
||||||
|
|
||||||
@ -304,10 +304,8 @@ export class AsyncTable {
|
|||||||
_changePagesizeHandler = () => {
|
_changePagesizeHandler = () => {
|
||||||
const url = new URL(getLocalStorageParameter('currentTableUrl') || window.location.href);
|
const url = new URL(getLocalStorageParameter('currentTableUrl') || window.location.href);
|
||||||
|
|
||||||
// format any date values before submission
|
// create new FormData and format any date values
|
||||||
Datepicker.formatAllFormInputDateValues(this._pagesizeForm);
|
const formData = Datepicker.unformatAll(this._pagesizeForm, new FormData(this._pagesizeForm));
|
||||||
|
|
||||||
const formData = new FormData(this._pagesizeForm);
|
|
||||||
|
|
||||||
for (var k of url.searchParams.keys()) {
|
for (var k of url.searchParams.keys()) {
|
||||||
url.searchParams.delete(k);
|
url.searchParams.delete(k);
|
||||||
|
|||||||
@ -1,14 +1,32 @@
|
|||||||
import datetime from 'tail.datetime';
|
import datetime from 'tail.datetime';
|
||||||
import dateFormat from 'dateformat';
|
|
||||||
import { Utility } from '../../core/utility';
|
import { Utility } from '../../core/utility';
|
||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
// formats for displaying all dates and/or times
|
const KEYCODE_ESCAPE = 27;
|
||||||
const FORM_DATE_FORMAT_DATE = 'yyyy-mm-dd';
|
|
||||||
const FORM_DATE_FORMAT_TIME = 'HH:MM:ss';
|
// INTERNAL (Uni2work specific) formats for formatting dates and/or times
|
||||||
const FORM_DATE_FORMAT = {
|
const FORM_DATE_FORMAT = {
|
||||||
'date': FORM_DATE_FORMAT_DATE,
|
'date': moment.HTML5_FMT.DATE,
|
||||||
'time': FORM_DATE_FORMAT_TIME,
|
'time': moment.HTML5_FMT.TIME_SECONDS,
|
||||||
'datetime-local': `${FORM_DATE_FORMAT_DATE}"T"${FORM_DATE_FORMAT_TIME}`,
|
'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"]';
|
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
|
// TODO: hardcoded, get from current language / settings
|
||||||
locale: 'de',
|
locale: 'de',
|
||||||
weekStart: 1,
|
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
|
// prevent the instance from closing when selecting a date before selecting a time
|
||||||
stayOpen: true,
|
stayOpen: true,
|
||||||
@ -116,6 +135,15 @@ export class Datepicker {
|
|||||||
// mark the form input element as initialized
|
// mark the form input element as initialized
|
||||||
this._element.classList.add(DATEPICKER_INITIALIZED_CLASS);
|
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
|
// 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 => {
|
window.addEventListener('click', event => {
|
||||||
if (!this.datepickerInstance.dt.contains(event.target) && window.document.contains(event.target)) {
|
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
|
// close the datepicker on escape keydown events
|
||||||
this._element.addEventListener('keydown', event => {
|
this._element.addEventListener('keydown', event => {
|
||||||
if (event.keyCode === 27) {
|
if (event.keyCode === KEYCODE_ESCAPE) {
|
||||||
this.datepickerInstance.close();
|
this.datepickerInstance.close();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// format the date value of the form input element of this datepicker before form submission
|
// format the date value of the form input element of this datepicker before form submission
|
||||||
this._element.form.addEventListener('submit', () => this.formatElementValue());
|
this._element.form.addEventListener('submit', () => this.formatElementValue());
|
||||||
|
|
||||||
|
// format any existing dates to fancy display format on pageload
|
||||||
|
this.formatElementValue(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
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
|
* 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() {
|
formatElementValue(toFancy) {
|
||||||
if (!this.datepickerInstance.select || !this._element.value) return;
|
// console.log("Hello from formatElementValue with toFancy ", toFancy, " and element value ", this._element.value, " and datepicker instance ", this.datepickerInstance);
|
||||||
this._element.value = dateFormat(this.datepickerInstance.select, FORM_DATE_FORMAT[this.elementType]);
|
|
||||||
|
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.
|
* Returns a datestring in internal format from the current state of the input element value.
|
||||||
* @param {*} form form for which all datepicker date values should be formatted
|
|
||||||
*/
|
*/
|
||||||
static formatAllFormInputDateValues(form) {
|
unformat() {
|
||||||
if (!Datepicker.datepickerCollections) {
|
return moment(this._element.value, FORM_DATE_FORMAT_MOMENT[this.elementType]).format(FORM_DATE_FORMAT[this.elementType]);
|
||||||
// no datepicker collections yet (i.e. constructor was never called) => do nothing
|
}
|
||||||
return;
|
|
||||||
}
|
/**
|
||||||
|
* 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.
|
||||||
// if the form has no id, assign one randomly
|
* @param {*} form Form for which all dates will be formatted in the FormData
|
||||||
if (!form.id) {
|
* @param {*} formData Initial FormData
|
||||||
form.id = `f${Math.floor(Math.random() * 100000)}`;
|
*/
|
||||||
|
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;
|
// return the (possibly changed) FormData
|
||||||
|
return formData;
|
||||||
if (Datepicker.datepickerCollections.has(formID)) {
|
|
||||||
const datepickerInstances = Datepicker.datepickerCollections.get(formID);
|
|
||||||
datepickerInstances.forEach(instance => instance.formatElementValue());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -158,10 +158,8 @@ export class MassInput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_serializeForm(submitButton, enctype) {
|
_serializeForm(submitButton, enctype) {
|
||||||
// format any date values before submission
|
// create new FormData and format any date values
|
||||||
Datepicker.formatAllFormInputDateValues(this._massInputForm);
|
const formData = Datepicker.unformatAll(this._massInputForm, new FormData(this._massInputForm));
|
||||||
|
|
||||||
const formData = new FormData(this._massInputForm);
|
|
||||||
|
|
||||||
// manually add name and value of submit button to formData
|
// manually add name and value of submit button to formData
|
||||||
formData.append(submitButton.name, submitButton.value);
|
formData.append(submitButton.name, submitButton.value);
|
||||||
|
|||||||
2775
package-lock.json
generated
2775
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
33
package.json
33
package.json
@ -49,16 +49,16 @@
|
|||||||
"defaults"
|
"defaults"
|
||||||
],
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/cli": "^7.4.4",
|
"@babel/cli": "^7.5.5",
|
||||||
"@babel/core": "^7.4.5",
|
"@babel/core": "^7.5.5",
|
||||||
"@babel/plugin-proposal-class-properties": "^7.4.4",
|
"@babel/plugin-proposal-class-properties": "^7.5.5",
|
||||||
"@babel/plugin-proposal-decorators": "^7.4.4",
|
"@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/cli": "^8.1.0",
|
||||||
"@commitlint/config-conventional": "^8.0.0",
|
"@commitlint/config-conventional": "^8.1.0",
|
||||||
"autoprefixer": "^9.6.0",
|
"autoprefixer": "^9.6.1",
|
||||||
"babel-core": "^6.26.3",
|
"babel-core": "^6.26.3",
|
||||||
"babel-eslint": "^10.0.1",
|
"babel-eslint": "^10.0.3",
|
||||||
"babel-loader": "^8.0.6",
|
"babel-loader": "^8.0.6",
|
||||||
"babel-plugin-syntax-dynamic-import": "^6.18.0",
|
"babel-plugin-syntax-dynamic-import": "^6.18.0",
|
||||||
"babel-plugin-transform-decorators-legacy": "^1.3.5",
|
"babel-plugin-transform-decorators-legacy": "^1.3.5",
|
||||||
@ -66,9 +66,9 @@
|
|||||||
"css-loader": "^2.1.1",
|
"css-loader": "^2.1.1",
|
||||||
"eslint": "^5.16.0",
|
"eslint": "^5.16.0",
|
||||||
"extract-text-webpack-plugin": "^4.0.0-beta.0",
|
"extract-text-webpack-plugin": "^4.0.0-beta.0",
|
||||||
"husky": "^2.4.1",
|
"husky": "^2.7.0",
|
||||||
"jasmine-core": "^3.4.0",
|
"jasmine-core": "^3.4.0",
|
||||||
"karma": "^4.1.0",
|
"karma": "^4.2.0",
|
||||||
"karma-chrome-launcher": "^2.2.0",
|
"karma-chrome-launcher": "^2.2.0",
|
||||||
"karma-cli": "^2.0.0",
|
"karma-cli": "^2.0.0",
|
||||||
"karma-jasmine": "^2.0.1",
|
"karma-jasmine": "^2.0.1",
|
||||||
@ -81,17 +81,16 @@
|
|||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"null-loader": "^2.0.0",
|
"null-loader": "^2.0.0",
|
||||||
"postcss-loader": "^3.0.0",
|
"postcss-loader": "^3.0.0",
|
||||||
"sass-loader": "^7.1.0",
|
"sass-loader": "^7.3.1",
|
||||||
"standard-version": "^6.0.1",
|
"standard-version": "^6.0.1",
|
||||||
"style-loader": "^0.23.1",
|
"style-loader": "^0.23.1",
|
||||||
"uglifyjs-webpack-plugin": "^2.1.3",
|
"uglifyjs-webpack-plugin": "^2.2.0",
|
||||||
"webpack": "^4.34.0",
|
"webpack": "^4.39.3",
|
||||||
"webpack-cli": "^3.3.4"
|
"webpack-cli": "^3.3.7"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dateformat": "^3.0.3",
|
"moment": "^2.24.0",
|
||||||
"flatpickr": "^4.5.7",
|
"npm": "^6.11.2",
|
||||||
"npm": "^6.10.3",
|
"tail.datetime": "git+https://git@github.com/uni2work/tail.DateTime.git#update-view-on-select"
|
||||||
"tail.datetime": "git+https://git@github.com/uni2work/tail.DateTime.git#master"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user