There is a pretty sound solution for such situations: to leave an empty datalist inner html (if empty, it will be filled on a focus event) and fill it dynamically on every input event with Javascript. In JS, it is better to alphabetically sort the array of options to be able to stop iteration when some coincidences are already found and there's no further matches. Continuing the example of this question:
const dlOptions = ["C", "C#", "C++", "CSS", "Erlang", "Go", "HTML", "Java",
"JavaScript", "PHP And HTML", "Python And C++", "Ruby And Go"].map(o => {
return [`<option value="${o}"></option>`, o.toLowerCase()];
});
function completeDataList(e) {
const fill = val => document.getElementById('languages').innerHTML = val;
if(!e.target.value) {
fill(dlOptions.reduce((sum, [html]) => sum + html, ''));
} else if(!(e instanceof InputEvent)) { // OR: else if(!e.inputType)
e.target.blur();
} else {
const inputValue = e.target.value.toLowerCase();
let result = '';
for (const [html, valuePattern] of dlOptions) {
if (!valuePattern.indexOf(inputValue)) {
result += html;
} else if (result) {
break;
}
}
fill(result);
}
}
function fillDataListIfEmpty() {
if(!document.getElementById('languages').innerHTML) {
completeDataList({ target: {} });
}
}
<h1>Datalist Demo</h1>
<label for="default">Pick a programming language</label>
<input type="text" id="default" list="languages" oninput="completeDataList(event)" onfocus="fillDataListIfEmpty()">
<datalist id="languages"></datalist>
P.S. Works like a charm on both desktop and mobile devices (I use this approach in my project, generating datalist on input out of ~80 options). However, as it was already mentioned above, for big quantities of options it is much more reasonable to resort to server solutions with database queries.
UPD: when using this approach, it should be noted that choosing a datalist option also triggers an input event (or, more precisely to say, just an instance of Event, but not of InputEvent), and, for the sake of good user experience, it should be taken into account (otherwise datalist options wrongly pop up again after choosing an option); the similar situation is with keyup event. I've just updated the code.
UPD2: I have edited the function completeDataList
according to the advice of @heretic-monkey (for details see the comments under this post). Also, for the sake performance, the array of option values is converted to another array of static search and html patterns and initialized as a global variable (in order to use these patterns on each input event instead of rebuilding them multiple times on each of events), which is crucially important in cases with large quantity of options and/or frequent calls of the function.