jQuery Change event on an <input> element - any way to retain previous value?

JavascriptJqueryHtmlEventsForms

Javascript Problem Overview


I've been searching around this morning and I'm not finding any simple solutions... basically, I want to capture a change in an input element, but also know the previous value.

Here's a change event and an input element in its simplest form. Clearly, I can get the new value with $(elem).val(), but is there a sneaky method I'm missing for getting the previous value? I don't see anything in the jQuery API to do this, but maybe someone's already done this and has some tips?

<script>
    $(document).ready(function(){
        $('#myInputElement').bind('change', function(){
            //var oldvalue = ???
            var newvalue = $(this).val();
        });
    });
</script>
<input id="myInputElement" type="text">

I'm not against writing my own solution, I just want to make sure I'm not recreating the wheel here.

Javascript Solutions


Solution 1 - Javascript

A better approach is to store the old value using .data. This spares the creation of a global var which you should stay away from and keeps the information encapsulated within the element. A real world example as to why Global Vars are bad is documented here

e.g

<script>
    //look no global needed:)

    $(document).ready(function(){
        // Get the initial value
       var $el = $('#myInputElement');
       $el.data('oldVal',  $el.val() );
      

       $el.change(function(){
            //store new value
            var $this = $(this);
            var newValue = $this.data('newVal', $this.val());
       })
       .focus(function(){
            // Get the value when input gains focus
            var oldValue = $(this).data('oldVal');
       });
    });
</script>
<input id="myInputElement" type="text">

Solution 2 - Javascript

This might do the trick:

$(document).ready(function() {
    $("input[type=text]").change(function() {
        $(this).data("old", $(this).data("new") || "");
        $(this).data("new", $(this).val());
        console.log($(this).data("old"));
        console.log($(this).data("new"));
    });
});

#Demo here

Solution 3 - Javascript

$('#element').on('change', function() {
    $(this).val($(this).prop("defaultValue"));
});

Solution 4 - Javascript

You could have the value of the input field copied to a hidden field whenever focus leaves the input field (which should do what you want). See code below:

<script>
    $(document).ready(function(){
        $('#myInputElement').bind('change', function(){
            var newvalue = $(this).val();
        });
        $('#myInputElement').blur(function(){
            $('#myHiddenInput').val($(this).val());
        });
    });
</script>
<input id="myInputElement" type="text">

(untested, but it should work).

Solution 5 - Javascript

Every DOM element has an attribute called defaultValue. You can use that to get the default value if you just want to compare the first changing of data.

Solution 6 - Javascript

In Russ answer he binds the focus event. I don't think it is necessary.

You can store the old value in the change event.

<script>
    $(document).ready(function(){

        var newValue = $('#myInputElement').val();
        var oldValue;

        $('#myInputElement').change(function(){
            oldValue = newValue;
            newValue = $(this).val();
        });
    });
</script>
<input id="myInputElement" type="text">

Solution 7 - Javascript

Some points.

Use $.data Instead of $.fn.data

// regular
$(elem).data(key,value);
// 10x faster
$.data(elem,key,value);

Then, You can get the previous value through the event object, without complicating your life:

    $('#myInputElement').change(function(event){
        var defaultValue = event.target.defaultValue;
        var newValue = event.target.value;
    });

Be warned that defaultValue is NOT the last set value. It's the value the field was initialized with. But you can use $.data to keep track of the "oldValue"

I recomend you always declare the "event" object in your event handler functions and inspect them with firebug (console.log(event)) or something. You will find a lot of useful things there that will save you from creating/accessing jquery objects (which are great, but if you can be faster...)

Solution 8 - Javascript

I created these functions based on Joey Guerra's suggestion, thank you for that. I'm elaborating a little bit, perhaps someone can use it. The first function checkDefaults() is called when an input changes, the second is called when the form is submitted using jQuery.post. div.updatesubmit is my submit button, and class 'needsupdate' is an indicator that an update is made but not yet submitted.

function checkDefaults() {
	var changed = false;
    	jQuery('input').each(function(){
    		if(this.defaultValue != this.value) {
    			changed = true;
    		}
    	});
    	if(changed === true) {
    		jQuery('div.updatesubmit').addClass("needsupdate");
    	} else {
    		jQuery('div.updatesubmit').removeClass("needsupdate");
    	}
}
    	
function renewDefaults() {
    	jQuery('input').each(function(){
    		this.defaultValue = this.value;
    	});
    	jQuery('div.updatesubmit').removeClass("needsupdate");
}

Solution 9 - Javascript

I found a dirty trick but it works, you could use the hover function to get the value before change!

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSeanWView Question on Stackoverflow
Solution 1 - JavascriptredsquareView Answer on Stackoverflow
Solution 2 - JavascriptSalman AView Answer on Stackoverflow
Solution 3 - JavascriptHakadelView Answer on Stackoverflow
Solution 4 - JavascriptbrettkellyView Answer on Stackoverflow
Solution 5 - JavascriptJoey GuerraView Answer on Stackoverflow
Solution 6 - JavascriptDaniel MouraView Answer on Stackoverflow
Solution 7 - JavascriptmonzonjView Answer on Stackoverflow
Solution 8 - JavascriptMaarten van MiddelaarView Answer on Stackoverflow
Solution 9 - JavascriptAndrea CammoranesiView Answer on Stackoverflow