Merge branch 'alert-on-form-leave' into 'master'
Show prompt if user has touched a form and tries to leave page Closes #377 See merge request !233
This commit is contained in:
commit
0cabee0826
@ -247,6 +247,88 @@
|
||||
setup: interactiveFieldsetUtil,
|
||||
});
|
||||
|
||||
/**
|
||||
*
|
||||
* Navigate Away Prompt Utility
|
||||
* This utility asks the user if (s)he really wants to navigate away
|
||||
* from a page containing a form if (s)he already touched an input.
|
||||
* Form-Submits will not trigger the prompt.
|
||||
* Utility will ignore forms that contain auto submit elements (buttons, inputs).
|
||||
*
|
||||
* Attribute: [none]
|
||||
* (automatically setup on all form tags that dont automatically submit, see AutoSubmitButtonUtil)
|
||||
*
|
||||
* Example usage:
|
||||
* (any page with a form)
|
||||
*/
|
||||
|
||||
var NAVIGATE_AWAY_PROMPT_UTIL_NAME = 'navigateAwayPrompt';
|
||||
var NAVIGATE_AWAY_PROMPT_UTIL_SELECTOR = 'form';
|
||||
|
||||
var NAVIGATE_AWAY_PROMPT_INITIALIZED_CLASS = 'navigate-away-prompt--initialized';
|
||||
|
||||
var navigateAwayPromptUtil = function(element) {
|
||||
var touched = false;
|
||||
var unloadDueToSubmit = false;
|
||||
|
||||
function init() {
|
||||
if (!element) {
|
||||
throw new Error('Navigate Away Prompt utility needs to be passed an element!');
|
||||
}
|
||||
|
||||
if (element.classList.contains(NAVIGATE_AWAY_PROMPT_INITIALIZED_CLASS)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// ignore forms that get submitted automatically
|
||||
if (element.querySelector(AUTO_SUBMIT_BUTTON_UTIL_SELECTOR) || element.querySelector(AUTO_SUBMIT_INPUT_UTIL_SELECTOR)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
window.addEventListener('beforeunload', beforeUnloadHandler);
|
||||
|
||||
element.addEventListener('submit', function() {
|
||||
unloadDueToSubmit = true;
|
||||
});
|
||||
element.addEventListener('change', function() {
|
||||
touched = true;
|
||||
unloadDueToSubmit = false;
|
||||
});
|
||||
|
||||
// mark initialized
|
||||
element.classList.add(NAVIGATE_AWAY_PROMPT_INITIALIZED_CLASS);
|
||||
|
||||
return {
|
||||
name: NAVIGATE_AWAY_PROMPT_UTIL_NAME,
|
||||
element: element,
|
||||
destroy: function() {
|
||||
window.removeEventListener('beforeunload', beforeUnloadHandler);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function 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 (!touched || unloadDueToSubmit) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// cancel the unload event. This is the standard to force the prompt to appear.
|
||||
event.preventDefault();
|
||||
// for all non standard compliant browsers we return a truthy value to activate the prompt.
|
||||
return true;
|
||||
}
|
||||
|
||||
return init();
|
||||
};
|
||||
|
||||
formUtilities.push({
|
||||
name: NAVIGATE_AWAY_PROMPT_UTIL_NAME,
|
||||
selector: NAVIGATE_AWAY_PROMPT_UTIL_SELECTOR,
|
||||
setup: navigateAwayPromptUtil,
|
||||
});
|
||||
|
||||
/**
|
||||
*
|
||||
* Auto Submit Button Utility
|
||||
@ -270,6 +352,10 @@
|
||||
throw new Error('Auto Submit Button utility needs to be passed an element!');
|
||||
}
|
||||
|
||||
if (element.classList.contains(AUTO_SUBMIT_BUTTON_INITIALIZED_CLASS)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// hide and mark initialized
|
||||
element.classList.add(AUTO_SUBMIT_BUTTON_HIDDEN_CLASS, AUTO_SUBMIT_BUTTON_INITIALIZED_CLASS);
|
||||
|
||||
@ -315,6 +401,10 @@
|
||||
throw new Error('Auto Submit Input utility needs to be passed an element!');
|
||||
}
|
||||
|
||||
if (element.classList.contains(AUTO_SUBMIT_INPUT_INITIALIZED_CLASS)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
form = element.form;
|
||||
if (!form) {
|
||||
throw new Error('Could not determine associated form for auto submit input');
|
||||
@ -374,6 +464,10 @@
|
||||
throw new Error('Form Error Remover utility needs to be passed an element!');
|
||||
}
|
||||
|
||||
if (element.classList.contains(FORM_ERROR_REMOVER_INITIALIZED_CLASS)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// find form groups
|
||||
formGroups = Array.from(element.querySelectorAll(FORM_GROUP_SELECTOR));
|
||||
|
||||
@ -428,6 +522,8 @@
|
||||
var DATEPICKER_UTIL_NAME = 'datepicker';
|
||||
var DATEPICKER_UTIL_SELECTOR = 'input[type="date"], input[type="time"], input[type="datetime-local"]';
|
||||
|
||||
var DATEPICKER_INITIALIZED_CLASS = 'datepicker--initialized';
|
||||
|
||||
var DATEPICKER_CONFIG = {
|
||||
"datetime-local": {
|
||||
enableTime: true,
|
||||
@ -459,6 +555,10 @@
|
||||
throw new Error('Datepicker utility needs to be passed an element!');
|
||||
}
|
||||
|
||||
if (element.classList.contains(DATEPICKER_INITIALIZED_CLASS)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var flatpickrConfig = DATEPICKER_CONFIG[element.getAttribute("type")];
|
||||
|
||||
if (!flatpickrConfig) {
|
||||
@ -467,6 +567,9 @@
|
||||
|
||||
flatpickrInstance = flatpickr(element, flatpickrConfig);
|
||||
|
||||
// mark initialized
|
||||
element.classList.add(DATEPICKER_INITIALIZED_CLASS);
|
||||
|
||||
return {
|
||||
name: DATEPICKER_UTIL_NAME,
|
||||
element: element,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user