misc: warn user if closing tab on an unsaved form (#6116) #1250

Merged
fpeters merged 1 commits from wip/6116-beforeunload into main 2024-03-15 15:04:45 +01:00
2 changed files with 13 additions and 0 deletions

View File

@ -107,6 +107,7 @@ class FormDefForm(Form):
def __init__(self):
super().__init__(enctype='multipart/form-data', use_tokens=False)
self.attrs['data-warn-on-unsaved-content'] = 'true'
def _render_error_notice_content(self, errors):
t = TemplateIO(html=True)

View File

@ -149,6 +149,18 @@ $(function() {
var autosave_button_to_click_on_complete = null;
var last_auto_save = $('form[data-has-draft]').serialize();
if ($('form[data-warn-on-unsaved-content]').length) {
window.addEventListener('beforeunload', function (e) {

Côté MDN https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event il est noté

In Firefox, beforeunload is not compatible with the back/forward cache (bfcache): that is, Firefox will not place pages in the bfcache if they have beforeunload listeners, and this is bad for performance.

It is therefore recommended that developers listen for beforeunload only when users have unsaved changes so that the dialog mentioned above can be used to warn them about impending data loss, and remove the listener again when it is not needed. Listening for beforeunload sparingly can minimize the effect on performance.

Mais comme on est déjà sur des pages avec du POST, il n'y a pas de "bfcache" et c'est quand même bien plus simple de poser une seule fois l'évènement, plutôt qu'avoir à détecter tout le temps les changements, donc je préfère nettement ainsi.

Côté MDN https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event il est noté > In Firefox, beforeunload is not compatible with the back/forward cache (bfcache): that is, Firefox will not place pages in the bfcache if they have beforeunload listeners, and this is bad for performance. > > It is therefore recommended that developers listen for beforeunload only when users have unsaved changes so that the dialog mentioned above can be used to warn them about impending data loss, and remove the listener again when it is not needed. Listening for beforeunload sparingly can minimize the effect on performance. Mais comme on est déjà sur des pages avec du POST, il n'y a pas de "bfcache" et c'est quand même bien plus simple de poser une seule fois l'évènement, plutôt qu'avoir à détecter tout le temps les changements, donc je préfère nettement ainsi.
var $form = $('form[data-warn-on-unsaved-content]');
var current_data = $form.serialize();
if (last_auto_save == current_data) return;
// preventDefault() and returnValue will trigger the browser alert
Outdated
Review

J'ai du aller sur le site de MDN pour comprendre que ces deux lignes preventDefault/returnValue était ce qui provoquait la popup d'alerte. J'ajouterais donc bien au dessus de ces deux lignes ce commentaire :

# trigger the warning dialog when the user closes or navigates the tab.

Et zou.

J'ai du aller sur le site de MDN pour comprendre que ces deux lignes preventDefault/returnValue était ce qui provoquait la popup d'alerte. J'ajouterais donc bien au dessus de ces deux lignes ce commentaire : `# trigger the warning dialog when the user closes or navigates the tab.` Et zou.

J'ai ajouté un commentaire (un peu différent).

J'ai ajouté un commentaire (un peu différent).
// warning user about closing tag/window and losing data.
e.preventDefault();
e.returnValue = true;
});
}
if ($('form[data-has-draft]:not([data-autosave=false])').length == 1) {
var error_counter = 0;