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 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) {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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
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"
|
||||
],
|
||||
"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"
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user