Limit total entries displayed by datalist
Asked Answered
D

3

27

When there is a long set of elements in a datalist, they will all get displayed with a scroll bar next to them. Is there an easy way to only display the top 5, and just cut the others off?

For example: http://jsfiddle.net/yxafa/

<input type="text" name="search" id="search" placeholder="type 'r'" list="searchresults" autocomplete="off">
<datalist id="searchresults">
    <option>Ray0</option>
    <option>Ray1</option>
    <option>Ray2</option>
    <option>Ray3</option>
    <option>Ray01</option>
    <option>Ray11</option>
    <option>Ray21</option>
    <option>Ray31</option>
    <option>Ray02</option>
    <option>Ray12</option>
    <option>Ray22</option>
    <option>Ray32</option>
    <option>Ray012</option>
    <option>Ray112</option>
    <option>Ray212</option>
    <option>Ray312</option>
    <option>Ray03</option>
    <option>Ray13</option>
    <option>Ray23</option>
    <option>Ray33</option>
    <option>Ray013</option>
    <option>Ray113</option>
    <option>Ray213</option>
    <option>Ray313</option>
    <option>Ray023</option>
    <option>Ray123</option>
    <option>Ray223</option>
    <option>Ray323</option>
    <option>Ray0123</option>
    <option>Ray1123</option>
    <option>Ray2123</option>
    <option>Ray3123</option>
</datalist>
Drus answered 26/2, 2013 at 19:26 Comment(3)
Come on! Interesting question, +1! Why there are no answers!?Synchroflash
Well, i don't think this i possible atm. You can only reduce the set of displayed items by adding other requirement like maxlength="4" or pattern="Ray[0123]\d"Coincide
Also note that, at the time of writing (May 2014) the template tag is only supported in Chrome, Opera Desktop, and Mozilla FF. See here. Same for datalist, + partial support for IE 10+Drifter
L
13

With some modern javascript and html you could do something like this.

Here's the document:

<template id="resultstemplate">
    <option>Ray0</option>
    <option>Ray1</option>
    <option>Ray2</option>
    <option>Ray3</option>
    <option>Ray01</option>
    <option>Ray11</option>
    <option>Ray21</option>
    <option>Ray31</option>
    <option>Ray02</option>
    <option>Ray12</option>
    <option>Ray22</option>
    <option>Ray32</option>
    <option>Ray012</option>
    <option>Ray112</option>
    <option>Ray212</option>
    <option>Ray312</option>
    <option>Ray03</option>
    <option>Ray13</option>
    <option>Ray23</option>
    <option>Ray33</option>
    <option>Ray013</option>
    <option>Ray113</option>
    <option>Ray213</option>
    <option>Ray313</option>
    <option>Ray023</option>
    <option>Ray123</option>
    <option>Ray223</option>
    <option>Ray323</option>
    <option>Ray0123</option>
    <option>Ray1123</option>
    <option>Ray2123</option>
    <option>Ray3123</option>
</template>
<input type="text" name="search" id="search"  placeholder="type 'r'" list="searchresults" autocomplete="off" />
<datalist id="searchresults"></datalist>

And here's the js:

var search = document.querySelector('#search');
var results = document.querySelector('#searchresults');
var templateContent = document.querySelector('#resultstemplate').content;
search.addEventListener('keyup', function handler(event) {
    while (results.children.length) results.removeChild(results.firstChild);
    var inputVal = new RegExp(search.value.trim(), 'i');
    var clonedOptions = templateContent.cloneNode(true);
    var set = Array.prototype.reduce.call(clonedOptions.children, function searchFilter(frag, el) {
        if (inputVal.test(el.textContent) && frag.children.length < 5) frag.appendChild(el);
        return frag;
    }, document.createDocumentFragment());
    results.appendChild(set);
});

And here's a live example: http://jsfiddle.net/gildean/yxafa/6/

Latoyia answered 30/5, 2014 at 11:56 Comment(2)
Just wonderin', why use document.querySelector in this case instead of getElementById when the latter is much faster & more efficient? jsperf.com/getelementbyid-vs-queryselectorDrifter
It's just a nicer api to remember. And in this example we're only doing all of the selecting once, so it makes no difference.Latoyia
H
2

This is not an answer to the original question (where the developer wants to limit the items shown in the datalist)

However I arrived at this question because I was concerned about a different limitation (where the developers does not want to limit the items shown in the datalist; but the browser has a limit (Chrome has a limit of 512; only shows up to 512 options at a time)

This JSFiddle demonstrates the problem; see screenshot below.

Of course, as the user begins typing in the input (which filters the options shown in the datalist), there may be fewer than 512 results, so this browser-limitation would not be noticeable. But if your user expects to see every single option in your datalist and the filtered results count >512, be careful of the Chrome limitation.

searchresults = document.getElementById('searchresults');

// Even though you add 1000 options to the datalist 
// chrome will only show up to 512 of those options at one time
for (let i = 0; i < 1000; i++) {
  let option = document.createElement('option');
  option.innerText = 'Val ' + (i+1);
  searchresults.appendChild(option);
}

on the left, code shows adding 1000 options to a datalist, on the right the UI shows only up to 512 of those options will be listed at once

If you need to show > 512 options...

Consider a <select> instead (in many browser implementations, a user can focus on a select, start typing, and in doing so "filter" the selected option. But this is limited to searching the start of a word, and may not handle special characters.)

Consider a UI library with "autocomplete"/"combobox" control (example in KendoUI's "Combobox") or creating your own (example in AngularJS)

Holierthanthou answered 10/12, 2022 at 18:26 Comment(0)
C
1

No javascript example:

  <input list="site" name="f" minlength="2" style="height:5.1em">
  <datalist id="site" style="height:5.1em;overflow:hidden">

Took me a minute :)

This uses CSS style and HTML attributes. PS: The minimum length should protect against empty submissions. However, you'll need to select the object and then hit backspace to see :|

Connel answered 15/5, 2020 at 7:23 Comment(2)
a minute of experimenting, and a minute for explanation. I'm sure you can do better explanation of the settings.Pontifical
Oh yes, sorry. The extra entries will be hidden, because they will exceed the height of "5.1em". I've edited the example to include "overflow:hidden".Connel

© 2022 - 2024 — McMap. All rights reserved.