612

In my experience, input type="text" onchange event usually occurs only after you leave (blur) the control.

Is there a way to force browser to trigger onchange every time textfield content changes? If not, what is the most elegant way to track this “manually”?

Using onkey* events is not reliable, since you can right-click the field and choose Paste, and this will change the field without any keyboard input.

Is setTimeout the only way?.. Ugly :-)

Jonatas Walker
  • 13,583
  • 5
  • 53
  • 82
Ilya Birman
  • 9,834
  • 4
  • 27
  • 31

16 Answers16

912

These days listen for oninput. It feels like onchange without the need to lose focus on the element. It is HTML5.

It’s supported by everyone (even mobile), except IE8 and below. For IE add onpropertychange. I use it like this:

const source = document.getElementById('source');
const result = document.getElementById('result');

const inputHandler = function(e) {
  result.innerText = e.target.value;
}

source.addEventListener('input', inputHandler);
source.addEventListener('propertychange', inputHandler); // for IE8
// Firefox/Edge18-/IE9+ don’t fire on <select><option>
// source.addEventListener('change', inputHandler); 
<input id="source">
<div id="result"></div>
Robert Siemer
  • 32,405
  • 11
  • 84
  • 94
304

Update:

See Another answer (2015).


Original 2009 Answer:

So, you want the onchange event to fire on keydown, blur, and paste? That's magic.

If you want to track changes as they type, use "onkeydown". If you need to trap paste operations with the mouse, use "onpaste" (IE, FF3) and "oninput" (FF, Opera, Chrome, Safari1).

1Broken for <textarea> on Safari. Use textInput instead

Community
  • 1
  • 1
Crescent Fresh
  • 115,249
  • 25
  • 154
  • 140
  • Haven’t you checked oninput in IE (Don’t have it on a Mac)? Because checking for paste itself is not enough: you can select and cut, for example. Thanks. – Ilya Birman Feb 22 '09 at 20:32
  • 27
    `onkeypress` should be used instead of `onkeydown`. `onkeydown` fires when a key is clicked down. If a user holds down a key, the event will only fire once for the first character. `onkeypress` fires whenever a char is added to the text field. – fent Mar 12 '12 at 17:22
  • 70
    It's not quite magic to make `onchange` fire on all those actions. `` will do well enough for most. – aroth Apr 25 '12 at 11:09
  • 1
    What about deleting some text in input box using mouse? I don't think this will work. – Jeevan Aug 27 '12 at 06:49
  • 1
    I agree with @DeaDEnD. In fact, I think the trio of events `input` + `onpropertychange` + `onkeypress` is better than `input` + `onpaste` + `onkeydown`. `onpropertychange` is IE's counterpart to `input`. – Vicky Chijwani Dec 25 '12 at 10:43
  • 47
    With jquery 1.8.3, looks like: `$().on('change keydown paste input', function() {})` – Narfanator Jun 01 '13 at 22:34
  • if using `onkeydown` it may be a good idea to check for `.isChar` and filter out `.key` values like `'Shift'`, `'Control'`, etc... – Sergey Ushakov Nov 25 '14 at 04:28
  • It might be worth noting that, according to the spec, onpaste is cancelable, whereas oninput is not. – craPkit Aug 06 '15 at 08:40
  • 1
    Refer to @Robert-Siemer's answer below. It should be the new accepted answer. – Max P Magee Feb 01 '16 at 23:19
  • @MaxPMagee: yaar it should. Stack is such a wasteland of outdated information these days. I've updated this answer to reference [@RobertSiemer's answer](http://stackoverflow.com/a/26202266/45433). I don't have time to police my 7 year old answers so thank you for bringing it to my attention! – Crescent Fresh Feb 02 '16 at 15:20
  • 1
    This answer is DEPRECATED... look the Robert Siemer answer is the modern one and far better – Ari Waisberg Apr 02 '17 at 21:36
  • 6
    @AriWais: YES, omg most of SO should be deprecated. Folks this answer is *8 years old*. I wish there was a "deprecate" button for old answers such as this one, and the community could choose the better one. – Crescent Fresh Apr 03 '17 at 14:48
  • Hm, what about cut and undo events? – Igor Shumichenko Jan 23 '21 at 15:00
68

Below code works fine for me with Jquery 1.8.3

HTML : <input type="text" id="myId" />

Javascript/JQuery:

$("#myId").on('change keydown paste input', function(){
      doSomething();
});
Arnaud
  • 17,268
  • 9
  • 65
  • 83
Amrit Pal Singh
  • 7,116
  • 7
  • 40
  • 50
  • 18
    The jQuery **library** isn't tagged in the question. – John Weisz Feb 16 '15 at 21:03
  • 29
    Jquery is a Javascript api, and I was brought here by a search with Jquery keyword, I don't think it's worth creating a new question for each javascript qustion for the Jquery answer... – GaelDev May 27 '15 at 12:12
  • 15
    If people weren't allowed to suggest the use of libraries in answers there would be A LOT more unanswered questions on SO – Fabio Dec 17 '15 at 03:01
  • 3
    Fires multiple times. Likely due to change and keydown. Likely input is only needed here. – mjs Sep 01 '17 at 11:09
  • 3
    you don't need the `keydown` because it will duplicate the value of the input, remove it. – Youssef Al Subaihi Jan 01 '19 at 10:11
49

Javascript is unpredictable and funny here.

  • onchange occurs only when you blur the textbox
  • onkeyup & onkeypress doesn't always occur on text change
  • onkeydown occurs on text change (but cannot track cut & paste with mouse click)
  • onpaste & oncut occurs with keypress and even with the mouse right click.

So, to track the change in textbox, we need onkeydown, oncut and onpaste. In the callback of these event, if you check the value of the textbox then you don't get the updated value as the value is changed after the callback. So a solution for this is to set a timeout function with a timeout of 50 mili-seconds (or may be less) to track the change.

This is a dirty hack but this is the only way, as I researched.

Here is an example. http://jsfiddle.net/2BfGC/12/

Sanket Sahu
  • 8,468
  • 10
  • 51
  • 65
  • 5
    `oninput` and `textInput` are the events which is the actual solution for this but, its not supported by all the browsers. – Sanket Sahu Jul 05 '12 at 06:59
  • For the second bullet point I assume you meant `onkeyup` and `onkeydown`, which are similar. Both can capture Ctrl, Alt, Shift, and Meta keys. For the third bullet point I assume you meant `onkeypress`. – Daniel Stevens Feb 22 '18 at 14:56
24

I think in 2018 it's better to use the input event.

-

As the WHATWG Spec describes (https://html.spec.whatwg.org/multipage/indices.html#event-input-input):

Fired at controls when the user changes the value (see also the change event)

-

Here's an example of how to use it:

<input type="text" oninput="handleValueChange()">
Patrick Hillert
  • 2,309
  • 4
  • 22
  • 37
  • 1
    This sounds right. Lots of developers seem to forget IMEs an voice dictation and swiping exist. Non game input, asking for a specific keycode is accessibility hostile and probe to breaking. Rule of thumb is, read text when focus is lost... Not before. If you want to be an IME, see what Octo.app did. – Ray Foss Jun 27 '21 at 03:31
16

onkeyup happens after you type for example I press t when I lift the finger the action happens but on keydown the action happens before I digit the character t

Hope this is helpful for someone.

So onkeyup is better for when you want to send what you just typed now.

Lucky
  • 16,787
  • 19
  • 117
  • 151
Fernando André
  • 1,213
  • 3
  • 19
  • 32
11

Use oninput instead of onchange.

index.html

<html>
  <head>
    <title>title here</title>
    <script src="index.js"></script>
  </head>
  <body>
    <input oninput="onclickhandler(this)"></input>
  </body>
</html>

script.js

function onclickhandler(e) {
  console.log(e.value);
}

10

I had a similar requirement (twitter style text field). Used onkeyup and onchange. onchange actually takes care of mouse paste operations during lost focus from the field.

[Update] In HTML5 or later, use oninput to get real time character modification updates, as explained in other answers above.

Mohnish
  • 1,905
  • 2
  • 17
  • 19
  • The oninput is useful if you want to detect when the contents of a textarea, input:text, input:password or input:search element have changed, because the onchange event on these elements fires when the element loses focus, not immediately after the modification. – hkasera May 04 '12 at 08:59
  • @hkasera Yes, with HTML5 `oninput` is the way to go. But, when I implemented, HTML5 didn't exist and we had IE 8 :( . I appreciate your update as it provides up-to-date information for users. – Mohnish May 08 '14 at 18:47
8

Please, judge next approach using JQuery:

HTML:

<input type="text" id="inputId" />

Javascript(JQuery):

$("#inputId").keyup(function() {
    $(this).blur();
    $(this).focus();
});

$("#inputId").change(function() {
    // Do whatever you need to do on actual change of the value of the input field
});
Harshal Patil
  • 17,838
  • 14
  • 60
  • 126
Alex Uke
  • 143
  • 1
  • 3
  • 1
    I use the same way : ) – khaled Dehia Jun 25 '15 at 18:26
  • I realize this isn't the newest answer, but wouldn't blurring and re-focusing the input on every keyup screw up the cursor placement if it was anywhere except the end of the input? – Michael Martin-Smucker May 02 '17 at 16:26
  • @MichaelMartin-Smucker You'd think so, but apparently not: https://jsfiddle.net/gsss8c6L/ – Clonkex Jul 04 '17 at 03:31
  • This brings an unexpected keyboard behavior in Android when used inside a webview. If the keyboard is opened for an input element and I either turned on all caps or switched to number view, as soon as I type a single character, all caps/number row is reset and a normal lowercase keyboard is shown - it is behaving like if I dismiss they keyboard and open it again for each character input. – muthuraj Mar 27 '23 at 13:42
6

Method 1: Add an event listener for input:

element.addEventListener("input", myFunction);

 

Method 2: Define the oninput property with JavaScript:

element.oninput = function()
{
    myFunction();
};

 

Method 3: Define the oninput property with HTML:

<input type="text" oninput="myFunction();">
Pikamander2
  • 7,332
  • 3
  • 48
  • 69
4

"input" worked for me.

var searchBar  = document.getElementById("searchBar");
searchBar.addEventListener("input", PredictSearch, false);
JTG
  • 8,587
  • 6
  • 31
  • 38
Sam
  • 51
  • 1
4

If you use ONLY Internet Explorer, you can use this:

<input type="text" id="myID" onpropertychange="TextChange(this)" />

<script type="text/javascript">
    function TextChange(tBox) {
        if(event.propertyName=='value') {
            //your code here
        }
    }
</script>

Hope that helps.

RolandDeschain
  • 227
  • 2
  • 3
4

To track each try this example and before that completely reduce cursor blink rate to zero.

<body>
//try onkeydown,onkeyup,onkeypress
<input type="text" onkeypress="myFunction(this.value)">
<span> </span>
<script>
function myFunction(val) {
//alert(val);
var mySpan = document.getElementsByTagName("span")[0].innerHTML;
mySpan += val+"<br>";
document.getElementsByTagName("span")[0].innerHTML = mySpan;
}
</script>

</body>

onblur : event generates on exit

onchange : event generates on exit if any changes made in inputtext

onkeydown: event generates on any key press (for key holding long times also)

onkeyup : event generates on any key release

onkeypress: same as onkeydown (or onkeyup) but won't react for ctrl,backsace,alt other

Venkat
  • 157
  • 3
4

2018 here, this is what I do:

$(inputs).on('change keydown paste input propertychange click keyup blur',handler);

If you can point out flaws in this approach, I would be grateful.

a20
  • 5,495
  • 2
  • 30
  • 27
  • 3
    2019 here, and this will fire multiple times for each keypress. For an example, see here: https://jsfiddle.net/sp00n82/3r4691tq/5/ – sp00n Apr 24 '19 at 14:55
4

there is a quite near solution (do not fix all Paste ways) but most of them:

It works for inputs as well as for textareas:

<input type="text" ... >
<textarea ... >...</textarea>

Do like this:

<input type="text" ... onkeyup="JavaScript: ControlChanges()" onmouseup="JavaScript: ControlChanges()" >
<textarea ... onkeyup="JavaScript: ControlChanges()" onmouseup="JavaScript: ControlChanges()" >...</textarea>

As i said, not all ways to Paste fire an event on all browsers... worst some do not fire any event at all, but Timers are horrible to be used for such.

But most of Paste ways are done with keyboard and/or mouse, so normally an onkeyup or onmouseup are fired after a paste, also onkeyup is fired when typing on keyboard.

Ensure yor check code does not take much time... otherwise user get a poor impresion.

Yes, the trick is to fire on key and on mouse... but beware both can be fired, so take in mind such!!!

z666zz666z
  • 1,235
  • 14
  • 7
3

You could use the keydown, keyup and keypress events as well.

Gumbo
  • 643,351
  • 109
  • 780
  • 844