none
Trouble with Datalist autopopulate in IE11 RRS feed

  • Question

  • Hello,

    I have an input tag associated with a datalist which has few options. I am working on filtering the datalist which should populate with the text user enters into the input field. However i get the list only if the user types the starting letters of the texts in the datalist options. I would like the datalist to be filtered depending on any text he enters and not only the starting letters. The code works in Chrome and Firefox, but i require it to be working on IE. 

    My code:

    <html>
    <head>
        <title>My test widget</title>
        <meta charset="utf-8" />
        <script type='text/javascript'>
            function onFruitClick() {
                var input, filter, datalistFruit, i;
                input = document.getElementById("Search");
                filter = input.value.toUpperCase();
                datalistFruit = document.getElementById("Fruit");
                for (i = 0; i < datalistFruit.options.length; i++) {
                    if (datalistFruit.options[i].contains(filter)) {
                        datalistFruit.options[i].style.display = "";
                    } else {
                        datalistFruit.options[i].style.display = "none";
                    }
                }
            }

        </script> 
    </head>

    <body>
        <div id="myFirstWidget">
            <input list="Fruit" name="Search" id="Search" title="Search" onkeyup="onFruitClick()" >
            <datalist name="Fruit" id="Fruit">
                <option>apple</option>
                <option>pineapple</option>
                <option>mango</option>
                <option>grape</option>
    </datalist>
    </div>
    </body>
    </html>

    So to be more precise i want the datalist to be populated with 'apple', 'pineapple' and 'grape' when user types 'ap' in the input as of now i get only 'apple' when i type 'ap'.Any help is appreciated.

    Thanks.

    Thursday, June 20, 2019 7:20 AM

Answers

  • It seems like it is a browser behavior, in IE/Edge, it will filter the datalist based the start value (if you remove the JavaScript code, it will show the same issue). 

    I suggest you could try to use the following code:

        <div id="myFirstWidget">
            <input list="Fruit" name="Search" id="Search" title="Search" onkeyup="updateList();" oninput="updateInput();" autocomplete="on">
            <datalist name="Fruit" id="Fruit">
                <option>apple</option>
                <option>pineapple</option>
                <option>mango</option>
                <option>grape</option>
            </datalist>
        </div>
        <script type='text/javascript'>
            function updateList(that) {
                if (!that) {
                    return;
                }
                var lastValue = that.lastValue,
                    value = that.value,
                    array = [],
                    pos = value.indexOf('|'),
                    start = that.selectionStart,
                    end = that.selectionEnd,
                    options;
    
                if (that.options) {
                    options = that.options;
                } else {
                    options = Object.keys(that.list.options).map(function (option) {
                        return that.list.options[option].value;
                    });
                    that.options = options;
                }
    
                if (lastValue !== value) {
                    that.list.innerHTML = options.filter(function (a) {
                        return ~a.toLowerCase().indexOf(value.toLowerCase());
                    }).map(function (a) {
                        return '<option value="' + value + '|' + a + '">' + a + '</option>';
                    }).join();
                    updateInput(that);
                    that.lastValue = value;
                }
            }
    
            function updateInput(that) {
                if (!that) {
                    return;
                }
                var value = that.value,
                    pos = value.indexOf('|'),
                    start = that.selectionStart,
                    end = that.selectionEnd;
    
                if (~pos) {
                    value = value.slice(pos + 1);
                }
                that.value = value;
                that.setSelectionRange(start, end);
            }
    
            document.getElementById('Search').addEventListener('keyup', function (e) {
                updateList(this);
            });
            document.getElementById('Search').addEventListener('input', function (e) {
                updateInput(this);
            });
        </script>

    The screenshot in IE/Microsoft Edge browser as below:

    Besides, you could also use the JQuery UI Autocomplete widget to achieve the same behavior. code as below:

    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
        <link rel="stylesheet" href="/resources/demos/style.css">
        <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
        <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
        <script>
            $(function () {
                var availableFruits = [
                    "apple",
                    "pineapple",
                    "mango",
                    "grape",
                ];
                $("#Fruit").autocomplete({
                    source: availableFruits
                });
            });
        </script>
    </head>
    <body>
        <div id="myFirstWidget">
            <div class="ui-widget">
                <label for="Fruit">Fruit: </label>
                <input id="Fruit">
            </div>
        </div>
    </body>



    • Edited by Zhi Lv Thursday, June 20, 2019 11:12 AM
    • Marked as answer by sina9386 Monday, June 24, 2019 8:03 AM
    Thursday, June 20, 2019 11:06 AM

All replies

  • It seems like it is a browser behavior, in IE/Edge, it will filter the datalist based the start value (if you remove the JavaScript code, it will show the same issue). 

    I suggest you could try to use the following code:

        <div id="myFirstWidget">
            <input list="Fruit" name="Search" id="Search" title="Search" onkeyup="updateList();" oninput="updateInput();" autocomplete="on">
            <datalist name="Fruit" id="Fruit">
                <option>apple</option>
                <option>pineapple</option>
                <option>mango</option>
                <option>grape</option>
            </datalist>
        </div>
        <script type='text/javascript'>
            function updateList(that) {
                if (!that) {
                    return;
                }
                var lastValue = that.lastValue,
                    value = that.value,
                    array = [],
                    pos = value.indexOf('|'),
                    start = that.selectionStart,
                    end = that.selectionEnd,
                    options;
    
                if (that.options) {
                    options = that.options;
                } else {
                    options = Object.keys(that.list.options).map(function (option) {
                        return that.list.options[option].value;
                    });
                    that.options = options;
                }
    
                if (lastValue !== value) {
                    that.list.innerHTML = options.filter(function (a) {
                        return ~a.toLowerCase().indexOf(value.toLowerCase());
                    }).map(function (a) {
                        return '<option value="' + value + '|' + a + '">' + a + '</option>';
                    }).join();
                    updateInput(that);
                    that.lastValue = value;
                }
            }
    
            function updateInput(that) {
                if (!that) {
                    return;
                }
                var value = that.value,
                    pos = value.indexOf('|'),
                    start = that.selectionStart,
                    end = that.selectionEnd;
    
                if (~pos) {
                    value = value.slice(pos + 1);
                }
                that.value = value;
                that.setSelectionRange(start, end);
            }
    
            document.getElementById('Search').addEventListener('keyup', function (e) {
                updateList(this);
            });
            document.getElementById('Search').addEventListener('input', function (e) {
                updateInput(this);
            });
        </script>

    The screenshot in IE/Microsoft Edge browser as below:

    Besides, you could also use the JQuery UI Autocomplete widget to achieve the same behavior. code as below:

    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
        <link rel="stylesheet" href="/resources/demos/style.css">
        <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
        <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
        <script>
            $(function () {
                var availableFruits = [
                    "apple",
                    "pineapple",
                    "mango",
                    "grape",
                ];
                $("#Fruit").autocomplete({
                    source: availableFruits
                });
            });
        </script>
    </head>
    <body>
        <div id="myFirstWidget">
            <div class="ui-widget">
                <label for="Fruit">Fruit: </label>
                <input id="Fruit">
            </div>
        </div>
    </body>



    • Edited by Zhi Lv Thursday, June 20, 2019 11:12 AM
    • Marked as answer by sina9386 Monday, June 24, 2019 8:03 AM
    Thursday, June 20, 2019 11:06 AM
  • That works perfectly!Thanks a lot!!
    Monday, June 24, 2019 8:03 AM
  • Hello I know this was posted and answered a month ago. Thanks for that. But i have an issue which is that the filter UI works perfectly but this is part of a form submit and the selected value is not send appropriately. So how can i get the value which is selected. I can explain more: suppose i type 'app' now i do see 'apple' and 'pineapple' in the list, but then i select 'apple' from the list and click submit button, then i check the backend it is not stored as 'apple'. So how can i check on form submit for the value of datalist selected item. I tried few ways from google but it shows empty or undefined. I have the value in the input 'Search' field but i think it is not mapped correctly with the datalist. Can you please advise soon. 
    Thursday, August 1, 2019 9:28 AM