How to stop users accidentally leaving a Wagtail edit page with JQuery

We had a request recently to implement a feature to stop users accidentally losing work while editing a page then forgetting to save. Especially now in Wagtail with features like StreamField, they can get pretty engrossed in their page layout design then forget to save, hit the ‘Back’ button my mistake etc.

Although I believe this functionality will be introduced into Wagtail itself soon, here is how to do it in a ‘quick and easy’ way before that time.

First off create a Javascript file in your app where ever you keep those, let’s call it leave_page.js (You can think of a better title name I’m sure)

Then add this code:


(function() {
(function($) {

window.onload = function() {

var submitted = false;

$(":submit").click(function(event){
submitted = true;
});

var del_button = $( "a:contains('Delete')" );
del_button.click(function(event){
submitted = true;
});

var unpublish_button = $( "a:contains('Unpublish')" );
unpublish_button.click(function(event){
submitted = true;
});

window.addEventListener("beforeunload", function (e) {

if (submitted == false){
var confirmationMessage = 'It looks like you have been editing something. ';
confirmationMessage += 'If you leave before saving, your changes will be lost.';

(e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
}
else {
return undefined;
}

});
};

})(jQuery);

}).call(this);


The first part of the code sets a flag so we can tell if any of the Wagtail main actions have been pressed like Save,Publish, Delete etc, we don’t want to bother the user if the page is being unloaded by those actions. If someone clicks Publish then we assume that’s what they want.

The code finds the Wagtail specific buttons and gives them a click handler which sets the flag to true.

The last part adds an event listener for the page exiting ‘beforeunload’, so just before we can remind them with an alert that they might lose their work, as long as submitted isn’t true.

You’ll need to get this JS picked up by Wagtail so use the Wagtail Hook ‘insert_editor_js’, create a file called ‘wagtail_hooks.py’ if you don’t already have one, then register the new JS Code from that. For more info on how to do that visit http://docs.wagtail.io/en/latest/reference/hooks.html

Hope this helps, let me know if there are any mistakes or if there is a cleaner, nicer way to do it.