Sadly, we are in a situation where we have to use a home-brew, spa-like engine, that hijacks all navigation and does it via ajax
.
I am looking for a way to be able to add a tag to a form
, maybe like this:
<form data-confirm-unsaved=""></form>
Which should cause a binding to the unloading of this form
, whether it is an actual whole page unload (like someone closed the tab or typed in a URL) or a click on any of the hijacked navigation elements... but I do not want it to be triggered when the form
is submitted/saved.
I have the beginning outline of what is NOT working code:
$('[data-confirm-unsaved]').on('beforeunload', function (e) {
let isUnload = true;
let message = $(this).attr('[data-confirm-unsaved]');
if (message == '')
message = "This data is unsaved. Are you certain that you want to cancel?";
if (isFormDirty($(this)))
isUnload = confirm(message);
if (isUnload)
e.preventDefault();
});
Of course I can't bind the beforeunload
event to a form
... only the window
, can I get some clues on how I would go about doing this?
The expected result is that when the form
gets unloaded by whatever means except submission, with dirty inputs that a confirmation appears if they really want to do so.
You can use MutationObserver
attached to <body>
with childList
option set to true
, at MutationEvent
, check if <form>
is removed node.
<body>
<form id="form">
<input>
</form>
<script>
const form = document.getElementById("form");
const observer = new MutationObserver(([{removedNodes}]) => {
if (removedNodes.length) {
// do stuff if `form` is removed from `document.body`
checkRemovedNodes: for (const node of removedNodes) {
if (node === form) {
console.log(`${node.tagName}#${node.id} removed from document`);
break checkRemovedNodes;
}
}
}
});
// remove `form` from `document` in `3000` milliseconds
observer.observe(document.body, {
childList: true
});
setTimeout(() => document.body.removeChild(form), 3000);
</script>
</body>