Ask before leaving an unsaved CKEditor
Vanilla JavaScript way, but removes any other onbeforeunload
handlers:
$(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.
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);
Posted by Martin Straub to makandra dev (2014-02-18 08:29)