jquery.dirty
jquery.dirty copied to clipboard
Cando grid issue
/*
- Dirty 0.8.3
- jquery plugin to detect when a form is modified
- (c) 2016 Simon Taite - https://github.com/simon-reynolds/jquery.dirty
- originally based on jquery.dirrty by Ruben Torres - https://github.com/rubentd/dirrty
- Released under the MIT license */
(function ($) {
//Save dirty instances
var singleDs = [];
var dirty = "dirty";
var clean = "clean";
var dataInitialValue = "dirtyInitialValue";
var dataIsDirty = "isDirty";
var formIsDirty = false;
var $el;
var thisIsDirty;
var result;
var $this;
var $e;
var initialValue;
var currentValue;
var getSingleton = function (id) {
singleDs.forEach(function (e) {
if (e.id === id) {
result = e;
}
});
return result;
};
var setSubmitEvents = function (d) {
d.form.on("submit", function () {
d.submitting = true;
});
if (d.options.preventLeaving) {
$(window).on("beforeunload", function (event) {
if (d.isDirty && !d.submitting) {
event.preventDefault();
return d.options.leavingMessage;
}
});
}
};
var setNamespacedEvents = function (d) {
d.form.find("input, select, textarea").on("change.dirty click.dirty keyup.dirty keydown.dirty blur.dirty", function (e) {
d.checkValues(e);
});
d.form.on("dirty", function () {
d.options.onDirty();
});
d.form.on("clean", function () {
d.options.onClean();
});
};
var clearNamespacedEvents = function (d) {
d.form.find("input, select, textarea").off("change.dirty click.dirty keyup.dirty keydown.dirty blur.dirty");
d.form.off("dirty");
d.form.off("clean");
};
var Dirty = function (form, options) {
this.form = form;
this.isDirty = false;
this.options = options;
this.history = [clean, clean]; //Keep track of last statuses
this.id = $(form).attr("id");
singleDs.push(this);
};
Dirty.prototype = {
init: function () {
this.saveInitialValues();
this.setEvents();
},
isRadioOrCheckbox: function (el) {
return $(el).is(":radio, :checkbox");
},
isFileInput: function (el) {
return $(el).is(":file")
},
saveInitialValues: function () {
$this = this;
this.form.find("input, select, textarea").each(function (_, e) {
if ($this.isRadioOrCheckbox(e)) {
$(e).data(dataInitialValue, ($(e).is(":checked") ? "checked" : "unchecked"));
} else if ($this.isFileInput(e)) {
$(e).data(dataInitialValue, JSON.stringify(e.files))
} else {
$(e).data(dataInitialValue, $(e).val() || '');
}
});
},
refreshEvents: function () {
clearNamespacedEvents(this);
setNamespacedEvents(this);
},
showDirtyFields: function () {
return this.form.find("input, select, textarea").filter(function (_, e) {
return $(e).data("isDirty");
});
},
setEvents: function () {
setSubmitEvents(this);
setNamespacedEvents(this);
},
isFieldDirty: function ($field) {
initialValue = $field.data(dataInitialValue);
// Explicitly check for null/undefined here as value may be `false`, so ($field.data(dataInitialValue) || '') would not work
if (initialValue == null) { initialValue = ''; }
currentValue = $field.val();
if (currentValue == null) { currentValue = ''; }
// Boolean values can be encoded as "true/false" or "True/False" depending on underlying frameworks so we need a case insensitive comparison
if ((/^(true|false)$/i).test(initialValue) && (/^(true|false)$/i).test(currentValue)) {
return !(new RegExp("^" + initialValue + "$", "i")).test(currentValue);
}
return currentValue !== initialValue;
},
isFileInputDirty: function ($field) {
return JSON.stringify(($field[0]).files) !== $field.data(dataInitialValue);
},
isCheckboxDirty: function ($field) {
return $field.data(dataInitialValue) !== $field.is(":checked") ? "checked" : "unchecked";
},
checkValues: function (e) {
$this = this;
formIsDirty = false;
this.form.find("input, select, textarea").each(function (_, el) {
$el = $(el);
if ($this.isRadioOrCheckbox(el)) {
thisIsDirty = $this.isCheckboxDirty($el);
} else if ($this.isFileInput(el)) {
thisIsDirty = $this.isFileInputDirty($el);
} else {
thisIsDirty = $this.isFieldDirty($el);
}
$el.data(dataIsDirty, thisIsDirty);
formIsDirty |= thisIsDirty;
});
if (formIsDirty) {
$this.setDirty();
} else {
$this.setClean();
}
},
setDirty: function () {
this.isDirty = true;
this.history[0] = this.history[1];
this.history[1] = dirty;
if (this.options.fireEventsOnEachChange || this.wasJustClean()) {
this.form.trigger("dirty");
}
},
setClean: function () {
this.isDirty = false;
this.history[0] = this.history[1];
this.history[1] = clean;
if (this.options.fireEventsOnEachChange || this.wasJustDirty()) {
this.form.trigger("clean");
}
},
//Lets me know if the previous status of the form was dirty
wasJustDirty: function () {
return (this.history[0] === dirty);
},
//Lets me know if the previous status of the form was clean
wasJustClean: function () {
return (this.history[0] === clean);
},
setAsClean: function () {
this.saveInitialValues();
this.setClean();
},
setAsDirty: function () {
this.saveInitialValues();
this.setDirty();
},
resetForm: function () {
$this = this;
this.form.find("input, select, textarea").each(function (_, e) {
$e = $(e);
if ($this.isRadioOrCheckbox(e)) {
$e.prop("checked", ($e.data(dataInitialValue) === "checked"));
} if ($this.isFileInput(e)) {
e.value = "";
$(e).data(dataInitialValue, JSON.stringify(e.files))
} else {
$e.val($e.data(dataInitialValue));
}
});
this.checkValues();
}
};
$.fn.dirty = function (options) {
if (typeof options === "string" && /^(isDirty|isClean|refreshEvents|resetForm|setAsClean|setAsDirty|showDirtyFields)$/i.test(options)) {
//Check if we have an instance of dirty for this form
// TODO: check if this is DOM or jQuery object
$this = getSingleton($(this).attr("id"));
if (!$this) {
$this = new Dirty($(this), options);
$this.init();
}
switch (options.toLowerCase()) {
case "isclean":
return !$this.isDirty;
case "isdirty":
return $this.isDirty;
case "refreshevents":
$this.refreshEvents();
case "resetform":
$this.resetForm();
case "setasclean":
return $this.setAsClean();
case "setasdirty":
return $this.setAsDirty();
case "showdirtyfields":
return $this.showDirtyFields();
}
} else if (typeof options === "object" || !options) {
return this.each(function (_, e) {
options = $.extend({}, $.fn.dirty.defaults, options);
(new Dirty($(e), options)).init();
});
}
};
$.fn.dirty.defaults = {
preventLeaving: false,
leavingMessage: "There are unsaved changes on this page which will be discarded if you continue.",
onDirty: $.noop, //This function is fired when the form gets dirty
onClean: $.noop, //This funciton is fired when the form gets clean again
fireEventsOnEachChange: false, // Fire onDirty/onClean on each modification of the form
};
})(jQuery);