admin管理员组

文章数量:1402587

I am tring to make datalist in html here is example

<h1>Datalist Demo</h1>
<label for="default">Pick a programming language</label>
<input type="text" id="default" list="languages">
<datalist id="languages">
    <option value="HTML">
    <option value="CSS">
    <option value="JavaScript">
    <option value="Java">
    <option value="Ruby And Go">
    <option value="PHP And HTML">
    <option value="Go">
    <option value="Erlang">
    <option value="Python And C++">
    <option value="C">
    <option value="C#">
    <option value="C++">
</datalist>

but when i search for 'go' it show me 2 results

  • Ruby And Go
  • Go

Result When i Search for 'go'

I want that it should only show term which match the beginning of entered text and NOT from inside.
Like When I search for 'go' only one result should be displayed

  • Go

I have to implement this on more than 5000 records stored in MySQL.

I am tring to make datalist in html here is example

<h1>Datalist Demo</h1>
<label for="default">Pick a programming language</label>
<input type="text" id="default" list="languages">
<datalist id="languages">
    <option value="HTML">
    <option value="CSS">
    <option value="JavaScript">
    <option value="Java">
    <option value="Ruby And Go">
    <option value="PHP And HTML">
    <option value="Go">
    <option value="Erlang">
    <option value="Python And C++">
    <option value="C">
    <option value="C#">
    <option value="C++">
</datalist>

but when i search for 'go' it show me 2 results

  • Ruby And Go
  • Go

Result When i Search for 'go'

I want that it should only show term which match the beginning of entered text and NOT from inside.
Like When I search for 'go' only one result should be displayed

  • Go

I have to implement this on more than 5000 records stored in MySQL.

Share Improve this question asked Mar 4, 2017 at 6:38 A VyomA Vyom 1351 silver badge9 bronze badges 3
  • 3 I don't think its a good idea to have all 5000 records loaded in the datalist, I would suggest to go for auto-plete/type-ahead controls (lots of jQuery plugin's available) for this and hit the server to retrieve the records matching the rule you need. And for your question - stackoverflow./questions/29154877/… - might help – Developer Commented Mar 4, 2017 at 6:49
  • 2 Possible duplicate of Use HTML5 (datalist) autoplete with 'contains' approach, not just 'starts with'. I know this is technically the opposite question, but the underlying desire for control over the <datalist> behavior is the same. – gyre Commented Mar 4, 2017 at 6:54
  • I suggest you to use str.length method.For this example get the lenght of 'Ruby and Go' and the length of 'Go' and return only the Go.You must consider an a possible space entry before the word Go. – liontass Commented Mar 4, 2017 at 7:08
Add a ment  | 

2 Answers 2

Reset to default 5

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 pleteDataList(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) {
        pleteDataList({ target: {} });
    }
}
<h1>Datalist Demo</h1>
<label for="default">Pick a programming language</label>
<input type="text" id="default" list="languages" oninput="pleteDataList(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 pleteDataList according to the advice of @heretic-monkey (for details see the ments 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.

For exact matches you can set pattern attribute value dynamically to RegExp [\\w\\s+#]{${this.value.length}} at input event

<h1>Datalist Demo</h1>
<label for="default">Pick a programming language</label>
<input type="text" id="default" list="languages" pattern="">
<datalist id="languages">
    <option value="HTML">
    <option value="CSS">
    <option value="JavaScript">
    <option value="Java">
    <option value="Ruby And Go">
    <option value="PHP And HTML">
    <option value="Go">
    <option value="Erlang">
    <option value="Python And C++">
    <option value="C">
    <option value="C#">
    <option value="C++">
</datalist>
<script>
  document.querySelector("#default")
  .oninput = function() {
    this.pattern = `[\\w\\s+#]{${this.value.length}}`;
  }
</script>

本文标签: javascriptHow to make datalist match result from beginning onlyStack Overflow