1

In the following example I have an input field and accompanying datalist element. I am trying to write javascript that listens for when a user selects an item from the list. I have seen it suggested to use the "input" event for this, and in Chrome, Firefox, etc it all works. The problem is internet explorer.

In IE10 I get the following behavior:

  • Typing in the field fires the event.
  • Selecting an item from the datalist does not fire the event the first time.
  • Reselecting the same option does fire the event.

See test:

enter image description here

$('input').on('input', function(){
    console.log($('input').val());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input list="ice-cream-flavors" id="ice-cream-choice" name="ice-cream-choice" />

<datalist id="ice-cream-flavors">
    <option value="Chocolate">
    <option value="Coconut">
    <option value="Mint">
    <option value="Strawberry">
    <option value="Vanilla">
</datalist>

Does anyone have any suggestions on how I can force internet explorer to fire that (or any) event so I can run a function when a user makes a selection?

Smokey Dawson
  • 8,827
  • 19
  • 77
  • 152
WillD
  • 5,170
  • 6
  • 27
  • 56
  • I don't have access to IE10 to verify this, but try listening to `change` event or listen to both like `$('input').on('input change', function(){` – Brahma Dev Oct 25 '18 at 21:15
  • So I added 'change'. It still doesn't fire immediately, it does however execute my function if I click somewhere else on the page... presumably when the input elem loses focus. It didn't used to do that... so that's progress I guess. – WillD Oct 25 '18 at 21:24
  • doesn't seem that this issue is fixable for IE10, as it was reported to microsoft, and first corrected in the next version. Since IE10 is no longer supported by microsoft, it probably won't be fixed either. And since its not an evergreen browser, I wouldn't do too much to support people who are still using it. Giving them a "too good" experience on a website will just confuse them from what they are used to anyway. See here for more insight: https://github.com/jquery/jquery/issues/1698 – Ole Haugset Oct 25 '18 at 22:08
  • alas on this project I don't have the power to unilaterally unsupport IE10 users. If I did I would throw up a "use a modern browser, damnit" message and call it a day. I think I am going to use a JS library for autosuggest instead of native HTML datalist. – WillD Oct 25 '18 at 22:40

1 Answers1

2

I ran into the same issue on IE11 with a custom autocomplete list made based on this: https://www.w3schools.com/howto/howto_js_autocomplete.asp

Some testing showed that IE11 fired the input event when clicking away from the input box (i.e. when losing focus). The intended behaviour, as in other browsers, was to only fire this event on text entry (including backspace) into the input field.

The solution was to check whether the input value had changed in IE, like this:

function inputEventGeneral(input, fn) { //input event for any browser
    if (checkBrowserIE()) {
        inputEventIE(input, fn);
    } else {
        input.addEventListener('input', function (e) { //normal input event for Chrome, FF, etc.
            fn(this); //run this function on input
        });
    };
};

function inputEventIE(input, fn) { //input event for IE
    let curr = '';
    let prev = '';

    input.addEventListener('input', function (e) {
        curr = this.value;

        if (prev === curr) { //check if value changed
            return;
        };

        prev = curr; //update value of prev

        fn(this); //run this function only if the value has been changed
    });
};


function checkBrowserIE() {
    return (/Trident/.test(navigator.userAgent)); //https://stackoverflow.com/questions/22004381/ie-input-event-for-contenteditable
};

In IE, there is also the issue of the 'x' clear button on the text input field, which would not fire an input event when using the above code. For this, you could either a) simply hide that clear button with CSS, as below:

input[type=text]::-ms-clear { display: none; }

or b) you could modify the above code to store the value of prev in a data-prev attribute or a global variable, and then update it with any changes of the input form value (e.g. when selecting from the autocomplete list/datalist). This would then cause the event to fire on clicking the clear button, because the prev value (val) would be different from the curr value ('') when clearing.

Hope that helps!

sbgib
  • 5,580
  • 3
  • 19
  • 26