2

I wanted to know how to limit the number of datalist options displayed on a datalist dropdown.

I found this solution which uses a datalist wrapping around a template, plus some javascript.

But, I want return the innerHTML corresponding to the selected datalist option. So, if I select option value = "California" I want to return >"CA"<.

document.getElementById("optionInnerHTML").innerHTML = [].find.call(document.getElementById('searchresults').getElementsByTagName('option'), ({ value }) => value === a).innerHTML;

I've tried adding document.getElementById('resultstemplate') to the code above however nothing has worked. What do I need to change to make the function return the option innerHTML value?

Before adding the datalist options limit (notice that the displayed dropdown options aren't limited yet, but I successfully get the option innerHTML value:

/* listen for ENTER click to submit datalist option input */  
function loadDoc() {
var n = document.getElementById("search");
n.addEventListener("keyup", function(event) {
    event.preventDefault();
    if (event.keyCode === 13) {
        document.getElementById("myButton").click();
}
});
    
/* find search value */  
var n = document.getElementById("search");
var a = n.value;
document.getElementById("searchValue").innerHTML = a;
    
/* find datalist option innerHTML */  
document.getElementById("optionInnerHTML").innerHTML = [].find.call(document.getElementById('searchresults').getElementsByTagName('option'), ({ value }) => value === a).innerHTML;
}
<datalist id="searchresults">
<option value="Alabama">AL</option>
<option value="California">CA</option>
<option value="Florida">FL</option>
<option value="Michigan">MI</option>
<option value="New York">NY</option>
<option value="Wisconsin">WI</option>
</datalist>
    
<input type="text" name="search" id="search"  placeholder="type state name or code" list="searchresults" autocomplete="off" />

<button id="myButton" type="button"
onclick="loadDoc()">Submit
</button>

<p>search value: <span id="searchValue"></span></p>
<p>datalist option innerHTML: <span id="optionInnerHTML"></span></p>

After adding the <template> and datalist options limit (Notice how the displayed options are now limited during input, but on submit I no longer get the option innerHTML value):

/* Limit length of datalist options dropdown */
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) || inputVal.test(el.value)) && (search.value != el.value) && frag.children.length < 5) frag.appendChild(el);
        return frag;
    }, document.createDocumentFragment());
    results.appendChild(set);
});


/* listen for ENTER click to submit datalist option input */  
function loadDoc() {
var n = document.getElementById("search");
n.addEventListener("keyup", function(event) {
    event.preventDefault();
    if (event.keyCode === 13) {
        document.getElementById("myButton").click();
}
});
    
/* find search value */  
var n = document.getElementById("search");
var a = n.value;
document.getElementById("searchValue").innerHTML = a;
    
/* find datalist option innerHTML */  
document.getElementById("optionInnerHTML").innerHTML = [].find.call(document.getElementById('searchresults').getElementsByTagName('option'), ({ value }) => value === a);
}
<datalist id="searchresults">
<template id="resultstemplate">
<option value="Alabama">AL</option>
<option value="California">CA</option>
<option value="Florida">FL</option>
<option value="Michigan">MI</option>
<option value="New York">NY</option>
<option value="Wisconsin">WI</option>
</template>
</datalist>
    
<input type="text" name="search" id="search"  placeholder="type state name or code" list="searchresults" autocomplete="off" />

<button id="myButton" type="button"
onclick="loadDoc()">Submit
</button>

<p>search value: <span id="searchValue"></span></p>
<p>datalist option innerHTML: <span id="optionInnerHTML"></span></p>
logoologist
  • 205
  • 3
  • 15

1 Answers1

3

Since you have the template saved off, you can use it to search for the matching option:

const options = templateContent.querySelectorAll('option');
const matchingOption = [].find.call(options, ({ value }) => value === a);
document.getElementById("optionInnerHTML").innerHTML = matchingOption.innerHTML;

Full working example:

/* Limit length of datalist options dropdown */
var search = document.querySelector('#search');
var results = document.querySelector('#searchresults');
var templateContent = document.querySelector('#resultstemplate').content;
search.addEventListener('keyup', function handler(event) {
    if (event.keyCode === 13) {
      return;
    }

    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) || inputVal.test(el.value)) && (search.value != el.value) && frag.children.length < 5) frag.appendChild(el);
        return frag;
    }, document.createDocumentFragment());
    results.appendChild(set);
});


/* listen for ENTER click to submit datalist option input */  
function loadDoc() {
var n = document.getElementById("search");
n.addEventListener("keyup", function(event) {
    event.preventDefault();
    if (event.keyCode === 13) {
        document.getElementById("myButton").click();
}
});
    
/* find search value */  
var n = document.getElementById("search");
var a = n.value;
document.getElementById("searchValue").innerHTML = a;
    
/* find datalist option innerHTML */  
const matchingOption = [].find.call(templateContent.querySelectorAll('option'), ({ value }) => value === a);
document.getElementById("optionInnerHTML").innerHTML = matchingOption.innerHTML;
}
<datalist id="searchresults">
<template id="resultstemplate">
<option value="Alabama">AL</option>
<option value="California">CA</option>
<option value="Florida">FL</option>
<option value="Michigan">MI</option>
<option value="New York">NY</option>
<option value="Wisconsin">WI</option>
</template>
</datalist>
    
<input type="text" name="search" id="search"  placeholder="type state name or code" list="searchresults" autocomplete="off" />

<button id="myButton" type="button"
onclick="loadDoc()">Submit
</button>

<p>search value: <span id="searchValue"></span></p>
<p>datalist option innerHTML: <span id="optionInnerHTML"></span></p>
Jacob
  • 77,566
  • 24
  • 149
  • 228