Last active
December 24, 2015 22:59
-
-
Save lukesutton/6876158 to your computer and use it in GitHub Desktop.
The start of a 'dirty' input tracking plugin. It's been done a bajillion times, but this one is simple.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* -------------------------------------------------------------------------- */ | |
| /* DIRTY FORM | |
| /* Checks to see if the user has made any changes to a form. Toggles the save | |
| /* control on or off appropriately. Also prompts user to save it they attempt | |
| /* to navigate away with unsaved changes. | |
| /* -------------------------------------------------------------------------- */ | |
| (function($) { | |
| var DirtyForm = function(form) { | |
| this.$form = form; | |
| this.$save = form.find('button.save'); | |
| var inputs = form.find(':input:not([type=hidden], button)'); | |
| this.originalValues = _.reduce(inputs, function(memo, el) { | |
| var $el = $(el); | |
| if (!$el.is(':radio, :checkbox') || $el.is(':checked')) { | |
| memo[$el.attr('name')] = { | |
| value: $.trim($el.val()), | |
| dirty: false | |
| }; | |
| } | |
| return memo; | |
| }, {}); | |
| this.setPristine(); | |
| inputs.on('change', $.proxy(this, 'change')); | |
| $(window).on('beforeunload', $.proxy(this, 'navigate')); | |
| }; | |
| DirtyForm.prototype = { | |
| change: function(e) { | |
| var $input = $(e.target) | |
| original = this.originalValues[$input.attr('name')], | |
| val = $.trim($input.val()); | |
| original.dirty = (original.value !== val); | |
| var dirty = _.some(_.pluck(this.originalValues, 'dirty')); | |
| if (dirty) { | |
| this.setDirty(); | |
| } | |
| else { | |
| this.setPristine(); | |
| } | |
| }, | |
| setDirty: function() { | |
| this.dirty = true; | |
| this.$save.prop('disabled', false).css('opacity', 1); | |
| }, | |
| setPristine: function() { | |
| this.dirty = false; | |
| this.$save.prop('disabled', true).css('opacity', 0.5); | |
| }, | |
| navigate: function() { | |
| if (this.dirty) { | |
| if (window.confirm("DERP")) { | |
| } | |
| else { | |
| // supress event | |
| } | |
| } | |
| } | |
| }; | |
| $.fn.islayDirtyForm = function() { | |
| this.each(function() { | |
| var $this = $(this); | |
| if (!$this.data('islayDirtyForm')) { | |
| $this.data('islayDirtyForm', new DirtyForm($this)); | |
| } | |
| }); | |
| return this; | |
| }; | |
| })(jQuery); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (function($) { | |
| function DirtyForm($el, opts) { | |
| this.$el = $el; | |
| this._dirty = false; | |
| this._originalValues = {}; | |
| this.settings = $.extend({ | |
| // Add default settings here. | |
| }, opts); | |
| // Subscribe to any event on the form | |
| var inputs = form.find(':input:not([type=hidden], button)'); | |
| for (var i = 0; i < inputs.length; i++) { | |
| var $el = $(inputs[i]); | |
| if (!$el.is(':radio, :checkbox') || $el.is(':checked')) { | |
| this._originalValues[$el.attr('name')] = {value: $.trim($el.val()), dirty: false}; | |
| } | |
| }; | |
| inputs.on('change', $.proxy(this, '_change')); | |
| if (this.settings.preventNavigation) { | |
| $(window).on('beforeunload', $.proxy(this, '_navigate')); | |
| } | |
| } | |
| DirtyForm.prototype = { | |
| isDirty: function() { | |
| return this._dirty; | |
| }, | |
| _change: function() { | |
| var $input = $(e.target) | |
| original = this._originalValues[$input.attr('name')], | |
| val = $.trim($input.val()); | |
| original.dirty = (original.value !== val); | |
| var dirty = _.some(_.pluck(this.originalValues, 'dirty')); | |
| if (dirty) { | |
| this._dirty = true; | |
| this.$el.trigger('dirty', true); | |
| } | |
| else { | |
| this._dirty = false; | |
| this.$el.trigger('dirty', false); | |
| } | |
| }, | |
| _navigate: function() { | |
| }, | |
| _run: function(name, args) { | |
| if (typeof this[name] === "function") { | |
| return this[name].apply(this, args); | |
| } | |
| else { | |
| throw "$.fn.dirtyForm does not have a function called " + name; | |
| } | |
| } | |
| }; | |
| $.fn.dirtyForm = function() { | |
| var args = Array.prototype.slice.call(arguments); | |
| for (var i = 0; i < this.length; i++) { | |
| var $this = $(this[i]); | |
| if (!$this.is('form')) { | |
| throw "$.fn.dirtyForm can only be called on form elements"; | |
| } | |
| if ($this.data('dirtyForm')) { | |
| return $this.data('dirtyForm')._run(args.shift(), args); | |
| } | |
| else { | |
| $this.data('dirtyForm', new DirtyForm($this, args[0])); | |
| } | |
| }); | |
| return this; | |
| }; | |
| })(jQuery); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment