feat(navigate-away-prompt): prompt on actual value change only
Store the initial FormData of a form and only prompt if any current value is actually different than the corresponding initial value (i.e. do not trigger prompt just by change events)
This commit is contained in:
parent
2512d69e67
commit
293ab6dc62
3
.babelrc
3
.babelrc
@ -4,6 +4,7 @@
|
|||||||
],
|
],
|
||||||
"plugins": [
|
"plugins": [
|
||||||
["@babel/plugin-proposal-decorators", { "legacy": true }],
|
["@babel/plugin-proposal-decorators", { "legacy": true }],
|
||||||
["@babel/plugin-proposal-class-properties", { "loose": true }]
|
["@babel/plugin-proposal-class-properties", { "loose": true }],
|
||||||
|
["@babel/transform-runtime"]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,16 @@ import { Utility } from '../../core/utility';
|
|||||||
import { AUTO_SUBMIT_BUTTON_UTIL_SELECTOR } from './auto-submit-button';
|
import { AUTO_SUBMIT_BUTTON_UTIL_SELECTOR } from './auto-submit-button';
|
||||||
import { AUTO_SUBMIT_INPUT_UTIL_SELECTOR } from './auto-submit-input';
|
import { AUTO_SUBMIT_INPUT_UTIL_SELECTOR } from './auto-submit-input';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key generator from an arbitrary number of FormData objects.
|
||||||
|
* @param {...any} formDatas FormData objects
|
||||||
|
*/
|
||||||
|
function* generatorFromFormDatas(...formDatas) {
|
||||||
|
for (let formData of formDatas) {
|
||||||
|
yield* formData.keys();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const NAVIGATE_AWAY_PROMPT_INITIALIZED_CLASS = 'navigate-away-prompt--initialized';
|
const NAVIGATE_AWAY_PROMPT_INITIALIZED_CLASS = 'navigate-away-prompt--initialized';
|
||||||
const NAVIGATE_AWAY_PROMPT_UTIL_OPTOUT = '[uw-no-navigate-away-prompt]';
|
const NAVIGATE_AWAY_PROMPT_UTIL_OPTOUT = '[uw-no-navigate-away-prompt]';
|
||||||
|
|
||||||
@ -12,7 +22,7 @@ export class NavigateAwayPrompt {
|
|||||||
|
|
||||||
_element;
|
_element;
|
||||||
|
|
||||||
_touched = false;
|
_initFormData;
|
||||||
_unloadDueToSubmit = false;
|
_unloadDueToSubmit = false;
|
||||||
|
|
||||||
constructor(element) {
|
constructor(element) {
|
||||||
@ -21,6 +31,7 @@ export class NavigateAwayPrompt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._element = element;
|
this._element = element;
|
||||||
|
this._initFormData = new FormData(this._element);
|
||||||
|
|
||||||
if (this._element.classList.contains(NAVIGATE_AWAY_PROMPT_INITIALIZED_CLASS)) {
|
if (this._element.classList.contains(NAVIGATE_AWAY_PROMPT_INITIALIZED_CLASS)) {
|
||||||
return false;
|
return false;
|
||||||
@ -40,10 +51,6 @@ export class NavigateAwayPrompt {
|
|||||||
this._element.addEventListener('submit', () => {
|
this._element.addEventListener('submit', () => {
|
||||||
this._unloadDueToSubmit = true;
|
this._unloadDueToSubmit = true;
|
||||||
});
|
});
|
||||||
this._element.addEventListener('change', () => {
|
|
||||||
this._touched = true;
|
|
||||||
this._unloadDueToSubmit = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
// mark initialized
|
// mark initialized
|
||||||
this._element.classList.add(NAVIGATE_AWAY_PROMPT_INITIALIZED_CLASS);
|
this._element.classList.add(NAVIGATE_AWAY_PROMPT_INITIALIZED_CLASS);
|
||||||
@ -55,9 +62,20 @@ export class NavigateAwayPrompt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_beforeUnloadHandler = (event) => {
|
_beforeUnloadHandler = (event) => {
|
||||||
|
// compare every value of the current FormData with every corresponding value of the initial FormData and set formDataHasChanged to true if there is at least one change
|
||||||
|
const currentFormData = new FormData(this._element);
|
||||||
|
var formDataHasChanged = false;
|
||||||
|
for (let key of generatorFromFormDatas(this._initFormData, currentFormData)) {
|
||||||
|
if (currentFormData.get(key) !== this._initFormData.get(key)) {
|
||||||
|
formDataHasChanged = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// allow the event to happen if the form was not touched by the
|
// allow the event to happen if the form was not touched by the
|
||||||
// user or the unload event was initiated by a form submit
|
// user (i.e. if the current FormData is equal to the initial FormData)
|
||||||
if (!this._touched || this._unloadDueToSubmit) {
|
// or the unload event was initiated by a form submit
|
||||||
|
if (!formDataHasChanged || this._unloadDueToSubmit) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
26
package-lock.json
generated
26
package-lock.json
generated
@ -1155,6 +1155,18 @@
|
|||||||
"@babel/helper-plugin-utils": "^7.0.0"
|
"@babel/helper-plugin-utils": "^7.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@babel/plugin-transform-runtime": {
|
||||||
|
"version": "7.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.5.5.tgz",
|
||||||
|
"integrity": "sha512-6Xmeidsun5rkwnGfMOp6/z9nSzWpHFNVr2Jx7kwoq4mVatQfQx5S56drBgEHF+XQbKOdIaOiMIINvp/kAwMN+w==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@babel/helper-module-imports": "^7.0.0",
|
||||||
|
"@babel/helper-plugin-utils": "^7.0.0",
|
||||||
|
"resolve": "^1.8.1",
|
||||||
|
"semver": "^5.5.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@babel/plugin-transform-shorthand-properties": {
|
"@babel/plugin-transform-shorthand-properties": {
|
||||||
"version": "7.2.0",
|
"version": "7.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz",
|
||||||
@ -1285,19 +1297,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/runtime": {
|
"@babel/runtime": {
|
||||||
"version": "7.4.5",
|
"version": "7.5.5",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.5.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.5.5.tgz",
|
||||||
"integrity": "sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==",
|
"integrity": "sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"regenerator-runtime": "^0.13.2"
|
"regenerator-runtime": "^0.13.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"regenerator-runtime": {
|
"regenerator-runtime": {
|
||||||
"version": "0.13.2",
|
"version": "0.13.3",
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz",
|
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz",
|
||||||
"integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==",
|
"integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw=="
|
||||||
"dev": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -53,6 +53,7 @@
|
|||||||
"@babel/core": "^7.5.5",
|
"@babel/core": "^7.5.5",
|
||||||
"@babel/plugin-proposal-class-properties": "^7.5.5",
|
"@babel/plugin-proposal-class-properties": "^7.5.5",
|
||||||
"@babel/plugin-proposal-decorators": "^7.4.4",
|
"@babel/plugin-proposal-decorators": "^7.4.4",
|
||||||
|
"@babel/plugin-transform-runtime": "^7.5.5",
|
||||||
"@babel/preset-env": "^7.5.5",
|
"@babel/preset-env": "^7.5.5",
|
||||||
"@commitlint/cli": "^8.1.0",
|
"@commitlint/cli": "^8.1.0",
|
||||||
"@commitlint/config-conventional": "^8.1.0",
|
"@commitlint/config-conventional": "^8.1.0",
|
||||||
@ -89,6 +90,7 @@
|
|||||||
"webpack-cli": "^3.3.7"
|
"webpack-cli": "^3.3.7"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.5.5",
|
||||||
"moment": "^2.24.0",
|
"moment": "^2.24.0",
|
||||||
"npm": "^6.11.2",
|
"npm": "^6.11.2",
|
||||||
"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#update-view-on-select"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user