67 lines
1.9 KiB
JavaScript
67 lines
1.9 KiB
JavaScript
import { Utility } from "../../core/utility";
|
|
import { AUTO_SUBMIT_BUTTON_UTIL_SELECTOR } from "./auto-submit-button";
|
|
import { AUTO_SUBMIT_INPUT_UTIL_SELECTOR } from "./auto-submit-input";
|
|
|
|
const NAVIGATE_AWAY_PROMPT_INITIALIZED_CLASS = 'navigate-away-prompt--initialized';
|
|
|
|
@Utility({
|
|
selector: 'form',
|
|
})
|
|
export class NavigateAwayPrompt {
|
|
|
|
_element;
|
|
|
|
_touched = false;
|
|
_unloadDueToSubmit = false;
|
|
|
|
constructor(element) {
|
|
if (!element) {
|
|
throw new Error('Navigate Away Prompt utility needs to be passed an element!');
|
|
}
|
|
|
|
this._element = element;
|
|
|
|
if (this._element.classList.contains(NAVIGATE_AWAY_PROMPT_INITIALIZED_CLASS)) {
|
|
return false;
|
|
}
|
|
|
|
// ignore forms that get submitted automatically
|
|
if (this._element.querySelector(AUTO_SUBMIT_BUTTON_UTIL_SELECTOR) || this._element.querySelector(AUTO_SUBMIT_INPUT_UTIL_SELECTOR)) {
|
|
return false;
|
|
}
|
|
|
|
window.addEventListener('beforeunload', this._beforeUnloadHandler);
|
|
|
|
this._element.addEventListener('submit', () => {
|
|
this._unloadDueToSubmit = true;
|
|
});
|
|
this._element.addEventListener('change', () => {
|
|
this._touched = true;
|
|
this._unloadDueToSubmit = false;
|
|
});
|
|
|
|
// mark initialized
|
|
this._element.classList.add(NAVIGATE_AWAY_PROMPT_INITIALIZED_CLASS);
|
|
|
|
}
|
|
|
|
destroy() {
|
|
window.removeEventListener('beforeunload', this._beforeUnloadHandler);
|
|
}
|
|
|
|
_beforeUnloadHandler = (event) => {
|
|
// allow the event to happen if the form was not touched by the
|
|
// user or the unload event was initiated by a form submit
|
|
if (!this._touched || this._unloadDueToSubmit) {
|
|
return false;
|
|
}
|
|
|
|
// cancel the unload event. This is the standard to force the prompt to appear.
|
|
event.preventDefault();
|
|
// chrome
|
|
event.returnValue = true;
|
|
// for all non standard compliant browsers we return a truthy value to activate the prompt.
|
|
return true;
|
|
}
|
|
}
|