|
@@ -0,0 +1,192 @@
|
|
|
+/*!
|
|
|
+ * 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;
|
|
|
+ }
|
|
|
+
|
|
|
+ $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() {
|
|
|
+ $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() {
|
|
|
+ $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);
|