This repository has been archived on 2026-07-27. You can view files and clone it, but cannot push or open issues or pull requests.
fradrive-old/frontend/src/utils/form/navigate-away-prompt.js
2019-05-28 23:18:47 +02:00

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;
}
}