95

I have an input element and I want to keep checking the length of the contents and whenever the length becomes equal to a particular size, I want to enable the submit button, but I am facing a problem with the onchange event of Javascript as the event fires only when the input element goes out of scope and not when the contents change.

<input type="text" id="name" onchange="checkLength(this.value)" />

----onchange does not fire on changing contents of name, but only fires when name goes out of focus.

Is there something I can do to make this event work on content change? or some other event I can use for this? I found a workaround by using the onkeyup function, but that does not fire when we select some content from the auto completer of the browser.

I want something which can work when the content of the field change whether by keyboard or by mouse... any ideas?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Sachin Midha
  • 1,068
  • 2
  • 8
  • 11

7 Answers7

130
(function () {
    var oldVal;

    $('#name').on('change textInput input', function () {
        var val = this.value;
        if (val !== oldVal) {
            oldVal = val;
            checkLength(val);
        }
    });
}());

This will catch change, keystrokes, paste, textInput, input (when available). And not fire more than necessary.

http://jsfiddle.net/katspaugh/xqeDj/


References:

textInput — a W3C DOM Level 3 event type. http://www.w3.org/TR/DOM-Level-3-Events/#events-textevents

A user agent must dispatch this event when one or more characters have been entered. These characters may originate from a variety of sources, e.g., characters resulting from a key being pressed or released on a keyboard device, from the processing of an input method editor, or resulting from a voice command. Where a “paste” operation generates a simple sequence of characters, i.e., a text passage without any structure or style information, this event type should be generated as well.

input — an HTML5 event type.

Fired at controls when the user changes the value

Firefox, Chrome, IE9 and other modern browsers support it.

This event occurs immediately after modification, unlike the onchange event, which occurs when the element loses focus.

ChrisF
  • 134,786
  • 31
  • 255
  • 325
katspaugh
  • 17,449
  • 11
  • 66
  • 103
  • 1
    its no working...did you check your code at your end?? was it working on selection from an autocompleter...? – Sachin Midha Aug 18 '11 at 11:25
  • I checked `textInput` in Chrome 15 and it works. I checked `input` event in IE9 and it works too. Firefox should support `DOMAttrModified`, but I don't have it installed. These two events are the best you can hope for, since they fire on any kind of text input. – katspaugh Aug 18 '11 at 11:28
  • 1
    Awesome solution....input worked for me like a blessing...nothing else except input is needed, that itself works enough. it works on ff4, but does not on 3.x, & I had 3.6 on my desktop & it never worked... – Sachin Midha Aug 18 '11 at 11:43
  • Can you provide some more information about this input event with which you are binding the element here, I couldn't find it on api.jquery.com – Sachin Midha Aug 18 '11 at 12:02
  • @katspaugh nope, it only updates the other TBs when leaving the first one, I want the sync to happen immediately. – Shimmy Weitzhandler Nov 26 '12 at 23:05
  • 7
    For the sake of keeping things updated, currently this solution fired multiple times on a single input change in FF22, you don't need to use the keypress or textinput events, input and propertychange should suffice – cyber-guard Jan 28 '14 at 18:07
  • 1
    I found that `change`, `keyup`, and `input` was the best combination to cover IE9 and Firefox (36.0.4). The `keypress` event did not seem to work in IE9 because it didn't capture things like Delete and Backspace, and the `input` event covers pasting with the keyboard and with the context menu. – TLS Mar 26 '15 at 17:09
  • `input` dominates – thedanotto Jul 18 '17 at 05:56
  • This works not so well with characters that require input method. For example, to input Chinese character “長”, I'd press "c","h","a","n",“g” and then "space", all these keystrokes are recorded and fire the events unwantedly. Is there any workaround for this? https://stackoverflow.com/questions/70040718/how-to-prevent-input-textinput-event-from-firing-when-input-with-an-input-method – shenkwen Nov 19 '21 at 20:44
12

It took me 30 minutes to find it, but this is working in June 2019.

<input type="text" id="myInput" oninput="myFunction()">

and if you want to add an event listener programmatically in js

inputElement.addEventListener("input", event => {})
franmcod
  • 457
  • 4
  • 13
  • 1
    the "input" event is what also React is using for the onChange property :) – sekmo Nov 15 '22 at 10:43
  • @sekmo, then why they decided to call it `onChange`? It's confusing – Normal Dec 11 '22 at 21:16
  • can you share the link where react says that they use `onInput` when we call `onChange`? – Normal Dec 11 '22 at 21:27
  • "The onChange event behaves as you would expect it to: whenever a form field is changed, this event is fired. We intentionally do not use the existing browser behavior because onChange is a misnomer for its behavior and React relies on this event to handle user input in real time." https://reactjs.org/docs/dom-elements.html#onchange - "For and – sekmo Dec 13 '22 at 08:43
10

As an extention to katspaugh's answer, here's a way to do it for multiple elements using a css class.

   $('.myclass').each(function(){
        $(this).attr('oldval',$(this).val());
   });

   $('.myclass').on('change keypress paste focus textInput input',function(){
       var val = $(this).val();
       if(val != $(this).attr('oldval') ){
           $(this).attr('oldval',val); 
           checkLength($(this).val());
        }
    });
SSZero
  • 665
  • 6
  • 13
4

Do it the jQuery way:

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


$('#name').keyup(function() {
  alert('Content length has changed to: '+$(this).val().length);
});
powtac
  • 40,542
  • 28
  • 115
  • 170
1

You can use onkeyup

<input id="name" onkeyup="checkLength(this.value)" />
Dogbert
  • 212,659
  • 41
  • 396
  • 397
  • I have used onkeyup...but my problem is when the user selects from the autocompleter of the browser, then this event is not triggered...I have already written this in my question in the workaround i used... – Sachin Midha Aug 18 '11 at 10:57
0

Here is another solution I develop for the same problem. However I use many input boxes so I keep old value as an user-defined attribute of the elements itself: "data-value". Using jQuery it is so easy to manage.

        $(document).delegate('.filterBox', 'keyup', { self: this }, function (e) {
            var self = e.data.self;

            if (e.keyCode == 13) {
                e.preventDefault();
                $(this).attr('data-value', $(this).val());
                self.filterBy(this, true)
            }
            else if (e.keyCode == 27) {
                $(this).val('');
                $(this).attr('data-value', '');
                self.filterBy(this, true)
            }
            else {
                if ($(this).attr('data-value') != $(this).val()) {
                    $(this).attr('data-value', $(this).val());
                    self.filterBy(this);
                }
            }
        });

here is, I used 5-6 input boxes have class 'filterBox', I make filterBy method run only if data-value is different than its own value.

efirat
  • 3,679
  • 2
  • 39
  • 43
0

You would have to use a combination of onkeyup and onclick (or onmouseup) if you want to catch every possibility.

<input id="name" onkeyup="checkLength(this.value)" onmouseup="checkLength(this.value)" />
DaveRandom
  • 87,921
  • 11
  • 154
  • 174
  • nice try, but the issue here is that I am not pressing mouse on the input element but on the auto-completer, which will not trigger this event... – Sachin Midha Aug 18 '11 at 11:01
  • The only other thing I can think of, and it is nasty nasty, is to `setTimeout` and periodically check the value of the field... What exactly are you wanting to do? – DaveRandom Aug 18 '11 at 11:04
  • Thats very nasty...:D it is something similar to what a password strength indicator does, it tells you the strength of the password as you keep entering into it. I want to enable a button only when the entered string is of length 10 else keep it disabled. I hope you got it... – Sachin Midha Aug 18 '11 at 11:07