79

I have a pretty simple form. When the user types in an input field, I want to update what they've typed somewhere else on the page. This all works fine. I've bound the update to the keyup, change and click events.

The only problem is if you select an input from the browser's autocomplete box, it does not update. Is there any event that triggers when you select from autocomplete (it's apparently neither change nor click). Note that if you select from the autocomplete box and the blur the input field, the update will be triggered. I would like for it to be triggered as soon as the autocomplete .

See: http://jsfiddle.net/pYKKp/ (hopefully you have filled out a lot of forms in the past with an input named "email").

HTML:

<input name="email" /> 
<div id="whatever">&lt;whatever></div> 

CSS:

div { 
    float: right; 
} 

Script:

$("input").on('keyup change click', function () { 
   var v = $(this).val(); 
    if (v) { 
     $("#whatever").text(v);   
    }  
    else { 
        $("#whatever").text('<whatever>'); 
    } 
}); 
Community
  • 1
  • 1
Explosion Pills
  • 188,624
  • 52
  • 326
  • 405

8 Answers8

82

I recommending using monitorEvents. It's a function provide by the javascript console in both web inspector and firebug that prints out all events that are generated by an element. Here's an example of how you'd use it:

monitorEvents($("input")[0]);

In your case, both Firefox and Opera generate an input event when the user selects an item from the autocomplete drop down. In IE7-8 a change event is produced after the user changes focus. The latest Chrome does generate a similar event.

A detailed browser compatibility chart can be found here:
https://developer.mozilla.org/en-US/docs/Web/Events/input

Xavi
  • 20,111
  • 14
  • 72
  • 63
  • 2
    Thanks, that helps with Firefox at least. The `change` event still appears to be triggered on blur, so I don't need to watch blur. – Explosion Pills Dec 17 '11 at 23:36
  • 1
    BTW, it turns out listening to `input` also helps with Opera. – Xavi Dec 18 '11 at 10:49
  • 3
    I just tested listening to the `input` event, and it works for all browsers I have installed. Versions: Firefox 21.0, Opera 12.15, Chrome 27, Safari 5.1.7 and IE 9. – awe Jun 18 '13 at 12:51
  • [Here](https://developer.mozilla.org/en-US/docs/Web/Events/input) you have a list of compatible browsers for the `input` event. I tested it in Chromium 55 and it works well for me. – MarthyM Feb 24 '17 at 15:49
  • It may also be useful to use monitorEvents($0) for the current selected dom elements. Saves the trouble of find the correct selector. – Guy Jun 01 '17 at 16:07
18

Here is an awesome solution.

$('html').bind('input', function() {
    alert('test');
});

I tested with Chrome and Firefox and it will also work for other browsers.

I have tried a lot of events with many elements but only this is triggered when you select from autocomplete.

Hope it will save some one's time.

Rafa Viotti
  • 9,998
  • 4
  • 42
  • 62
Anand Singh
  • 2,343
  • 1
  • 22
  • 34
  • This does not work in all browsers, it does, however, work in most of the browsers where the `change` event is not fired, so all you should need is add a listener to `change` AND `input` events. `$field.on('change input', changeFunction)` – MarthyM Feb 24 '17 at 15:25
  • 2
    I use `$input.on('keyup input change paste', callback)` . Works very well. – Sorin C Aug 30 '17 at 13:11
3

As Xavi explained, there's no a solution 100% cross-browser for that, so I created a trick on my own for that (5 steps to go on):
1. I need a couple of new arrays:

window.timeouts     = new Array();
window.memo_values  = new Array();


2. on focus on the input text I want to trigger (in your case "email", in my example "name") I set an Interval, for example using jQuery (not needed thought):

jQuery('#name').focus(function ()
{
    var id = jQuery(this).attr('id');
    window.timeouts[id] = setInterval('onChangeValue.call(document.getElementById("'+ id +'"), doSomething)', 500);
});


3. on blur I remove the interval: (always using jQuery not needed thought), and I verify if the value changed

jQuery('#name').blur(function ()
{
    var id = jQuery(this).attr('id');
    onChangeValue.call(document.getElementById(id), doSomething);
    clearInterval(window.timeouts[id]);
    delete window.timeouts[id];
});


4. Now, the main function which check changes is the following

function onChangeValue(callback)
{
    if (window.memo_values[this.id] != this.value)
    {
        window.memo_values[this.id] = this.value;

        if (callback instanceof Function)
        {
            callback.call(this);
        }
        else
        {
            eval( callback );
        }
    }
}

Important note: you can use "this" inside the above function, referring to your triggered input HTML element. An id must be specified in order to that function to work, and you can pass a function, or a function name or a string of command as a callback.


5. Finally you can do something when the input value is changed, even when a value is selected from a autocomplete dropdown list

function doSomething()
{
    alert('got you! '+this.value);
}

Important note: again you use "this" inside the above function referring to the your triggered input HTML element.

WORKING FIDDLE!!!
I know it sounds complicated, but it isn't.
I prepared a working fiddle for you, the input to change is named "name" so if you ever entered your name in an online form you might have an autocomplete dropdown list of your browser to test.

Community
  • 1
  • 1
Luca Borrione
  • 16,324
  • 8
  • 52
  • 66
3

Add "blur". works in all browsers!

$("input").on('blur keyup change click', function () {
Kareem
  • 5,068
  • 44
  • 38
  • 7
    Neither of those events are triggered when you autocomplete the input. Read OP. – machineaddict Mar 04 '16 at 07:43
  • @machineaddict autocomplete is not a javascript event. What you can do is to edit your autocomplete function to run another function when autocompletes. If you wanna share your autocomplete function, I can have a look and help you with it. – Kareem Mar 10 '16 at 07:53
  • Autocomplete has an event, [read this](http://stackoverflow.com/a/8548572/1057527). And the answer is on [this page](http://stackoverflow.com/a/33412873/1057527) and is working perfectly. You should edit your answer. – machineaddict Mar 10 '16 at 08:13
  • Th first answer clearly says it doesn't work across all browsers. the second answer does what I exactly suggested in my previous comment. There is no such an event listener like onAutocomplete. I am glad you found a solution for your problem. Thanks for sharing the links. They might help someone. – Kareem Mar 10 '16 at 11:20
2

Detecting autocomplete on form input with jQuery OR JAVASCRIPT

Using: Event input. To select (input or textarea) value suggestions

FOR EXAMPLE FOR JQUERY:

$(input).on('input', function() { 
alert("Number selected ");

});

FOR EXAMPLE FOR JAVASCRIPT:

<input type="text"  onInput="affiche(document.getElementById('something').text)" name="Somthing" />

This start ajax query ...

Franklin CI
  • 159
  • 1
  • 9
1

The only sure way is to use an interval.

Luca's answer is too complicated for me, so I created my own short version which hopefully will help someone (maybe even me from the future):

    $input.on( 'focus', function(){
        var intervalDuration = 1000, // ms
            interval = setInterval( function(){

                // do your tests here
                // ..................

                // when element loses focus, we stop checking:
                if( ! $input.is( ':focus' ) ) clearInterval( interval );  

            }, intervalDuration );
    } );

Tested on Chrome, Mozilla and even IE.

Sorin C
  • 984
  • 10
  • 8
1

I've realised via monitorEvents that at least in Chrome the keyup event is fired before the autocomplete input event. On a normal keyboard input the sequence is keydown input keyup, so after the input.

What i did is then:

let myFun = ()=>{ ..do Something };

input.addEventListener('change', myFun );

//fallback in case change is not fired on autocomplete
let _k = null;
input.addEventListener( 'keydown', (e)=>_k=e.type );
input.addEventListener( 'keyup', (e)=>_k=e.type );
input.addEventListener( 'input', (e)=>{ if(_k === 'keyup') myFun();})

Needs to be checked with other browser, but that might be a way without intervals.

Björn Grambow
  • 368
  • 1
  • 14
0

I don't think you need an event for this: this happens only once, and there is no good browser-wide support for this, as shown by @xavi 's answer.

Just add a function after loading the body that checks the fields once for any changes in the default value, or if it's just a matter of copying a certain value to another place, just copy it to make sure it is initialized properly.

Nanne
  • 64,065
  • 16
  • 119
  • 163