Posted about 7 years ago. Visible to the public.

Howto prompt before accidentally discarding unsaved changes with JavaScript

Ask before leaving an unsaved CKEditor

Vanilla JavaScript way, but removes any other onbeforeunload handlers:

Copy
$(function(){ document.body.onbeforeunload = function() { for(editorName in CKEDITOR.instances) { if (CKEDITOR.instances[editorName].checkDirty()) { return "Unsaved changes present!" } } } }

A robuster implementation example

Note: Don't forget to mark the 'search as you type' forms with the skip_pending_changes_warning class.

Copy
var WarnBeforeAccidentallyDiscardUnsavedChanges = (function () { var anyDirtyInputFields = false; var unloadTriggeredBySubmit = false; var warningMessage = "Ungespeicherte Änderungen vorhanden!"; var confirmationMessage = "Möchten Sie diese Seite wirklich verlassen?"; var skipWarningClass = "skip_pending_changes_warning"; function init() { skipFormsWithOverwrittenSubmit(); observeInputFieldsForChanges(); observeSubmitEvents(); bindAlertMethod(); } // API method for others which need to know for unsaved changes function isUnsavedChangeConfirmed() { if (isUnsavedChangePresent()) { return confirm(warningMessage + "\n\n" + confirmationMessage); } else { return true; } } // opens a confirmation dialog if unsaved changes are present function bindAlertMethod() { $(window).on('beforeunload', function() { if (isUnsavedChangePresent() && !unloadTriggeredBySubmit) { return warningMessage; } }); } function isUnsavedChangePresent() { var unsavedChanges = false; // objects providing an isDirty() method unsavedChanges = unsavedChanges || anyDirtyCkeditors(); // elements which have to be observed manually unsavedChanges = unsavedChanges || anyDirtyInputFields; return unsavedChanges; } // dirty check helper methods function anyDirtyCkeditors() { var anyDirty = false; if(typeof CKEDITOR != 'undefined') { _.each(CKEDITOR.instances, function(instance) { anyDirty = anyDirty || instance.checkDirty(); }); } return anyDirty; } // observer helpers // Using a css class as marker may make developers awere of the // special form behavior when inspecting the form classes function skipFormsWithOverwrittenSubmit() { _.each($('form input[type=submit]'), function(submitInput) { if (!!$(submitInput).attr('onclick')) { $(submitInput).closest('form').addClass(skipWarningClass); } }); } function observeInputFieldsForChanges() { var $forms = $('form:not(.' + skipWarningClass + ')'); var $inputs = $forms.find( 'input:not(.' + skipWarningClass + '), ' + 'textarea:not(.' + skipWarningClass + '), ' + 'select:not(.' + skipWarningClass + ')'); $inputs.on('change', function() { anyDirtyInputFields = true; }); } function observeSubmitEvents() { $('form').submit(function() { unloadTriggeredBySubmit = true; }); } return { init: init, isUnsavedChangeConfirmed: isUnsavedChangeConfirmed }; }()); $(WarnBeforeAccidentallyDiscardUnsavedChanges.init);

Does your version of Ruby on Rails still receive security updates?
Rails LTS provides security patches for old versions of Ruby on Rails (3.2 and 2.3).

Owner of this card:

Avatar
Martin Straub
Last edit:
almost 7 years ago
Attachments:
prompt_before_discarding_changes.js
Keywords:
browser
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Martin Straub to makandra dev
This website uses short-lived cookies to improve usability.
Accept or learn more