From 7e7c91492026bc00ae8ac9aaf8ffb74136f953a7 Mon Sep 17 00:00:00 2001 From: Christophe Goffin Date: Thu, 3 Sep 2015 16:08:43 +0200 Subject: [PATCH] Let jquery.AreYouSure work after DOM manipulations. --- jquery.are-you-sure.js | 66 ++++++++++++++++++++++++++++++++---------- 1 file changed, 50 insertions(+), 16 deletions(-) diff --git a/jquery.are-you-sure.js b/jquery.are-you-sure.js index 3c41e2f..50d0523 100644 --- a/jquery.are-you-sure.js +++ b/jquery.are-you-sure.js @@ -11,9 +11,9 @@ * Date: 13th August 2014 */ (function($) { - + $.fn.areYouSure = function(options) { - + var settings = $.extend( { 'message' : 'You have unsaved changes!', @@ -64,33 +64,58 @@ return val; }; - var storeOrigValue = function($field) { - $field.data('ays-orig', getValue($field)); + var storeOrigValue = function($field, $form) { + // If possible, save the field data on the form to be able to check the + // field value when DOM manipulations occur within the form. + var field_value = getValue($field); + if ($field.attr('id')) { + $form.data('ays-orig-field-id-' + $field.attr('id'), field_value); + } + else if ($field.attr('type') !== 'radio' && $field.attr('name')) { + // Dont't do this for radio buttons because radio button group input + // elements have the same name. + $form.data('ays-orig-field-name-' + $field.attr('name'), field_value); + } + else { + $field.data('ays-orig', field_value); + } }; + var getOrigValue = function($field, $form) { + if ($field.attr('id')) { + return $form.data('ays-orig-field-id-' + $field.attr('id')); + } + else if ($field.attr('type') !== 'radio' && $field.attr('name')) { + return $form.data('ays-orig-field-name-' + $field.attr('name')); + } + else { + return $field.data('ays-orig'); + } + } + var checkForm = function(evt) { - var isFieldDirty = function($field) { - var origValue = $field.data('ays-orig'); + var isFieldDirty = function($field, $form) { + var origValue = getOrigValue($field, $form); if (undefined === origValue) { return false; } return (getValue($field) != origValue); }; - var $form = ($(this).is('form')) + var $form = ($(this).is('form')) ? $(this) : $(this).parents('form'); // Test on the target first as it's the most likely to be dirty - if (isFieldDirty($(evt.target))) { + if (isFieldDirty($(evt.target), $form)) { setDirtyStatus($form, true); return; } $fields = $form.find(settings.fieldSelector); - if (settings.addRemoveFieldsMarksDirty) { + if (settings.addRemoveFieldsMarksDirty) { // Check if field count has changed var origCount = $form.data("ays-orig-field-count"); if (origCount != $fields.length) { @@ -103,18 +128,18 @@ var isDirty = false; $fields.each(function() { $field = $(this); - if (isFieldDirty($field)) { + if (isFieldDirty($field, $form)) { isDirty = true; return false; // break } }); - + setDirtyStatus($form, isDirty); }; var initForm = function($form) { var fields = $form.find(settings.fieldSelector); - $(fields).each(function() { storeOrigValue($(this)); }); + $(fields).each(function() { storeOrigValue($(this), $form); }); $(fields).unbind(settings.fieldEvents, checkForm); $(fields).bind(settings.fieldEvents, checkForm); $form.data("ays-orig-field-count", $(fields).length); @@ -124,7 +149,7 @@ var setDirtyStatus = function($form, isDirty) { var changed = isDirty != $form.hasClass(settings.dirtyClass); $form.toggleClass(settings.dirtyClass, isDirty); - + // Fire change event if required if (changed) { if (settings.change) settings.change.call($form, $form); @@ -140,8 +165,8 @@ var fields = $form.find(settings.fieldSelector); $(fields).each(function() { var $field = $(this); - if (!$field.data('ays-orig')) { - storeOrigValue($field); + if (!getOrigValue($field, $form)) { + storeOrigValue($field, $form); $field.bind(settings.fieldEvents, checkForm); } }); @@ -153,6 +178,14 @@ initForm($(this)); } + // Only binding the events to the fields. Can be used after DOM manipulations. + var bindEvents = function() { + var $form = $(this); + var fields = $form.find(settings.fieldSelector); + $(fields).unbind(settings.fieldEvents, checkForm); + $(fields).bind(settings.fieldEvents, checkForm); + } + if (!settings.silent && !window.aysUnloadSet) { window.aysUnloadSet = true; $(window).bind('beforeunload', function() { @@ -177,7 +210,7 @@ return; } var $form = $(this); - + $form.submit(function() { $form.removeClass(settings.dirtyClass); }); @@ -186,6 +219,7 @@ $form.bind('rescan.areYouSure', rescan); $form.bind('reinitialize.areYouSure', reinitialize); $form.bind('checkform.areYouSure', checkForm); + $form.bind('bindEvents.areYouSure', bindEvents); initForm($form); }); };