/*! * jQuery Plugin: Are-You-Sure (Dirty Form Detection) * https://github.com/codedance/jquery.AreYouSure/ * * Copyright (c) 2012-2014, Chris Dance and PaperCut Software http://www.papercut.com/ * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * Author: chris.dance@papercut.com * Version: 1.9.0 * Date: 13th August 2014 */ (function ($) { $.fn.areYouSure = function (options) { var settings = $.extend( { message: "You have unsaved changes!", dirtyClass: "dirty", change: null, silent: false, addRemoveFieldsMarksDirty: false, fieldEvents: "change keyup propertychange input", fieldSelector: ":input:not(input[type=submit]):not(input[type=button])", }, options ); var getValue = function ($field) { if ( $field.hasClass("ays-ignore") || $field.hasClass("aysIgnore") || $field.attr("data-ays-ignore") || $field.attr("name") === undefined ) { return null; } if ($field.is(":disabled")) { return "ays-disabled"; } var val; var type = $field.attr("type"); if ($field.is("select")) { type = "select"; } switch (type) { case "checkbox": case "radio": val = $field.is(":checked"); break; case "select": val = ""; $field.find("option").each(function (o) { var $option = $(this); if ($option.is(":selected")) { val += $option.val(); } }); break; default: val = $field.val(); } return val; }; var storeOrigValue = function ($field) { $field.data("ays-orig", getValue($field)); }; var checkForm = function (evt) { var isFieldDirty = function ($field) { var origValue = $field.data("ays-orig"); if (undefined === origValue) { return false; } return getValue($field) != origValue; }; 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))) { setDirtyStatus($form, true); return; } var $fields = $form.find(settings.fieldSelector); if (settings.addRemoveFieldsMarksDirty) { // Check if field count has changed var origCount = $form.data("ays-orig-field-count"); if (origCount != $fields.length) { setDirtyStatus($form, true); return; } } // Brute force - check each field var isDirty = false; $fields.each(function () { var $field = $(this); if (isFieldDirty($field)) { isDirty = true; return false; // break } }); //setDirtyStatus($form, isDirty); }; var initForm = function ($form) { var fields = $form.find(settings.fieldSelector); $(fields).each(function () { storeOrigValue($(this)); }); $(fields).unbind(settings.fieldEvents, checkForm); $(fields).bind(settings.fieldEvents, checkForm); $form.data("ays-orig-field-count", $(fields).length); setDirtyStatus($form, false); }; 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); if (isDirty) $form.trigger("dirty.areYouSure", [$form]); if (!isDirty) $form.trigger("clean.areYouSure", [$form]); $form.trigger("change.areYouSure", [$form]); } }; var rescan = function () { var $form = $(this); var fields = $form.find(settings.fieldSelector); $(fields).each(function () { var $field = $(this); if (!$field.data("ays-orig")) { storeOrigValue($field); $field.bind(settings.fieldEvents, checkForm); } }); // Check for changes while we're here $form.trigger("checkform.areYouSure"); }; var reinitialize = function () { initForm($(this)); }; if (!settings.silent && !window.aysUnloadSet) { window.aysUnloadSet = true; $(window).bind("beforeunload", function () { var $dirtyForms = $("form").filter("." + settings.dirtyClass); if ($dirtyForms.length == 0) { return; } // Prevent multiple prompts - seen on Chrome and IE if (navigator.userAgent.toLowerCase().match(/msie|chrome/)) { if (window.aysHasPrompted) { return; } window.aysHasPrompted = true; window.setTimeout(function () { window.aysHasPrompted = false; }, 900); } return settings.message; }); } return this.each(function (elem) { if (!$(this).is("form")) { return; } var $form = $(this); $form.submit(function () { $form.removeClass(settings.dirtyClass); }); $form.bind("reset", function () { setDirtyStatus($form, false); }); // Add a custom events $form.bind("rescan.areYouSure", rescan); $form.bind("reinitialize.areYouSure", reinitialize); $form.bind("checkform.areYouSure", checkForm); initForm($form); }); }; })(jQuery);