57

Is it possible to bind javascript (jQuery is best) event to "change" form input value somehow?

I know about .change() method, but it does not trigger until you (the cursor) leave(s) the input field. I have also considered using .keyup() method but it reacts also on arrow keys and so on.

I need just trigger an action every time the text in the input changes, even if it's only one letter change.

Pavel S.
  • 11,892
  • 18
  • 75
  • 113
  • what about using the keypress event? – jwatts1980 Sep 23 '11 at 21:13
  • 1
    There are other possibilities to change the input than using key. For example, choosing from the drop-down menu of previously inserted values. – Pavel S. Jan 25 '13 at 10:43
  • possible duplicate of [Catch only keypresses that change input?](http://stackoverflow.com/questions/6488171/catch-only-keypresses-that-change-input) – random Jun 08 '13 at 15:20

9 Answers9

94

There is a simple solution, which is the HTML5 input event. It's supported in current versions of all major browsers for <input type="text"> elements and there's a simple workaround for IE < 9. See the following answers for more details:

Example (except IE < 9: see links above for workaround):

$("#your_id").on("input", function() {
    alert("Change to " + this.value);
});
Community
  • 1
  • 1
Tim Down
  • 318,141
  • 75
  • 454
  • 536
  • @vsync: I'm not clear what you mean. There isn't a shortcut method for handling the `input` event but jQuery still adds a listener for the event using `on()`. Proof: http://jsfiddle.net/QA5hN/ – Tim Down Mar 01 '13 at 17:33
  • This event works not only for `` but also for ` – mtoloo Apr 13 '16 at 05:29
  • 1
    Bare in mind this doesn't detect input changes done in javacript – A Friend Jan 30 '19 at 23:07
15

Yes, compare it to the value it was before it changed.

var previousValue = $("#elm").val();
$("#elm").keyup(function(e) {
    var currentValue = $(this).val();
    if(currentValue != previousValue) {
         previousValue = currentValue;
         alert("Value changed!");
    }
});

Another option is to only trigger your changed function on certain keys. Use e.KeyCode to figure out what key was pressed.

alexn
  • 57,867
  • 14
  • 111
  • 145
  • @Jordão Certainly, i did not see that requirement though. – alexn Sep 23 '11 at 21:18
  • Jordão is right, user can select one of previously entered values. Keyup is not what I'm looking for. Also, my form is dynamicaly generated and it's hard to store all the values. Isn't there any "simple" approach? – Pavel S. Sep 23 '11 at 21:18
  • @Pavel you should clarify how you want it to work. When do you need to trigger an event? When it changed by pasting text? Cutting text? Editing using firebug? Just changes with keyboard? The solution entirely depends on how flexible you need it to be. – alexn Sep 23 '11 at 21:20
  • @alexn I just need the action to be triggered if (and only if) the text value in the input has changed. I'm looking for simple function, something like .onSimpleChange()... – Pavel S. Sep 23 '11 at 21:23
  • And .change() does not work because you want it to trigger exactly after it changed? Not on blur? – alexn Sep 23 '11 at 21:25
  • Appreciating that this was written a long time ago, I think it worth noting that this approach would become complex fairly quickly if you were to be assigning this event to multiple elements via iterations/jquery. Say you have multiple elements and you assign via `$('.mySharedClass')` for example. suddenly you have to manage an array of previous values in the parent scope and define a strategy for indexing/retrieving those values in the event handler. – Jay Edwards Aug 12 '21 at 08:28
10

You can also store the initial value in a data attribute and check it against the current value.

<input type="text" name="somename" id="id_someid" value="" data-initial="your initial value" /> 

$("#id_someid").keyup(function() {
    return $(this).val() == $(this).data().initial;
});

Would return true if the initial value has not changed.

Kwaw Annor
  • 1,448
  • 13
  • 13
7
function checkChange($this){
    var value = $this.val();      
    var sv=$this.data("stored");            
        if(value!=sv)
            $this.trigger("simpleChange");    
}

$(document).ready(function(){
    $(this).data("stored",$(this).val());   
        $("input").bind("keyup",function(e){  
        checkChange($(this));
    });        
    $("input").bind("simpleChange",function(e){
        alert("the value is chaneged");
    });        
});

here is the fiddle http://jsfiddle.net/Q9PqT/1/

Martijn Vissers
  • 712
  • 5
  • 29
Rafay
  • 30,950
  • 5
  • 68
  • 101
3

You can employ the use of data in jQuery and catch all of the events which then tests it against it's last value (untested):

$(document).ready(function() {  
    $("#fieldId").bind("keyup keydown keypress change blur", function() {
        if ($(this).val() != jQuery.data(this, "lastvalue") {
         alert("changed");
        }
        jQuery.data(this, "lastvalue", $(this).val());
    });
});

This would work pretty good against a long list of items too. Using jQuery.data means you don't have to create a javascript variable to track the value. You could do $("#fieldId1, #fieldId2, #fieldId3, #fieldId14, etc") to track many fields.

UPDATE: Added blur to the bind list.

jwatts1980
  • 7,254
  • 2
  • 28
  • 44
  • 1
    Thanks, this works pretty fine. However, there is still one problem: When user selects the value from already entered values (dropdown browser hints), the action is not performed. However, it should, even if you don't leave the input. – Pavel S. Sep 23 '11 at 21:41
  • 1
    Wow. I agree that it should most definitely register an event there. If the browser doesn't cooperate, then the only recourse I can see if to add a "blur" event to the list. This will catch the change when the user navigates off the field. – jwatts1980 Sep 28 '11 at 16:10
  • I would recommend for a scenario where you need to track precisely what's entered, disable auto-complete with autocomplete="off" attribute. – Kon Nov 08 '13 at 20:46
1

You can set events on a combination of key and mouse events, and onblur as well, to be sure. In that event, store the value of the input. In the next call, compare the current value with the lastly stored value. Only do your magic if it has actually changed.

To do this in a more or less clean way:

You can associate data with a DOM element (lookup api.jquery.com/jQuery.data ) So you can write a generic set of event handlers that are assigned to all elements in the form. Each event can pass the element it was triggered by to one generic function. That one function can add the old value to the data of the element. That way, you should be able to implement this as a generic piece of code that works on your whole form and every form you'll write from now on. :) And it will probably take no more than about 20 lines of code, I guess.

An example is in this fiddle: http://jsfiddle.net/zeEwX/

GolezTrol
  • 114,394
  • 18
  • 182
  • 210
  • Is it really the only way, store all the form values and compare them manually? – Pavel S. Sep 23 '11 at 21:20
  • Created a fiddle to show how to do this without global variables, but by storing the old values with the elements themselves. Modified my answer. – GolezTrol Sep 23 '11 at 21:52
1

I had to use this kind of code for a scanner that pasted stuff into the field

$(document).ready(function() {
  var tId,oldVal;
  $("#fieldId").focus(function() {
     oldVal = $("#fieldId").val();
     tId=setInterval(function() { 
      var newVal = $("#fieldId").val(); 
      if (oldVal!=newVal) oldVal=newVal;
      someaction() },100);
  });
  $("#fieldId").blur(function(){ clearInterval(tId)});
});

Not tested...

mplungjan
  • 169,008
  • 28
  • 173
  • 236
1

I don't think there's a 'simple' solution. You'll probably need to use both the events onKeyUp and onChange so that you also catch when changes are made with the mouse. Every time your code is called you can store the value you've 'seen' on this.seenValue attached right to the field. This should make a little easier.

Sarel Botha
  • 12,419
  • 7
  • 54
  • 59
  • Is there any version of "onChange" triggered before the user leaves the field? He can select value by mouse and stay in the field. And I need to trigger the event. How can I recognize such a situation? – Pavel S. Sep 23 '11 at 21:30
  • No, I don't believe there is. You can also call your code on the onmouseup event. That should cover all bases. – Sarel Botha Sep 23 '11 at 21:38
  • Yes, there is a simple way: the HTML5 `input` event. See my answer. – Tim Down Sep 24 '11 at 00:31
1

Since the user can go into the OS menu and select paste using their mouse, there is no safe event that will trigger this for you. The only way I found that always works is to have a setInterval that checks if the input value has changed:

var inp = $('#input'),
    val = saved = inp.val(),
    tid = setInterval(function() {
        val = inp.val();
        if ( saved != val ) {
            console.log('#input has changed');
            saved = val;
    },50);

You can also set this up using a jQuery special event.

David Hellsing
  • 106,495
  • 44
  • 176
  • 212