HTML5 datalist value vs. inner-text

2020-03-13 04:08发布

问题:

I have an issue that is manifesting between Chrome and Firefox's handling of the HTML5 datalist element.

I may be abusing it, which Firefox is handling the way I expect, but Chrome is not. I have not tried it on Opera. This is for an in-house page, so I can control the browser being used.

I set a value, as well as the inner-text, as in:

<input list="Names" placeholder="Enter Name or ID" name="txtSearchValue" autocomplete="off"/>
<datalist id="Names"><%=OptionsList%></datalist>

The server-side value "OptionsList" gets built dynamically from a database query. The end result looks, approximately, like this:

<option value="123">Sam's Fresh Sandwiches</option>
<option value="234">Sawatdee</option>

etc.

On Firefox, I can type the letters "S" then "A" (case insensitive) and both of the above entries will appear. As soon as I type a "W" or select Sawatdee with the mouse, the text box is populated with 234. This is what I desire to have happen - as I want 234 sent back to the server and not Sawatdee. It also works if I type "A" then "T".

On Chrome, I can type all the letters I want, but nothing will appear in the list. However, if I type a 2, only the second entry will appear; but in the list it will show a 2 followed by Sawatdee.

Am I over-using/abusing the datalist or does Chrome have a problem with it? Or is Chrome handling it as it is technically supposed to and I've found a Firefox bug?

回答1:

I'm trying to do something similar. I think the issue is the datalist isn't spec'ed to work like a dropdown option list. One work around is that you generate both an <%=OptionsList%> and then an array <%=OptionListValues %>...so once you get the text value in your input, you can use javascript to look for it's key in the OptionListValues and send the key instead of the description back to the server. Pain in the rear and adds an extra data load on the client side, though I guess you could do this server side as well (send the text in the input and then lookup the text and get the key on the server side).

Too bad Chrome doesn't work like FF on this, maybe in the future the browsers will work like Mozilla on this.

Or you can do something like this. Say you have the following input/datalist

<input id="datalisttestinput" list="stuff" ></input>
        <datalist id="stuff">
            <option id="3" value="Collin" >
            <option id="5" value="Carl">
            <option id="1" value="Amy" >
            <option id="2" value="Kristal">
        </datalist>

You can use jQuery (or plain javascript) to dig out the id value...here is my example, I'm sure this could be optimized a bit.

 function GetValue() {
            var x = $('#datalisttestinput').val();
            var z = $('#stuff');
            var val = $(z).find('option[value="' + x + '"]');
            var endval = val.attr('id');
            alert(endval);
        }

That should get you going.



回答2:

Slightly modifying infocyde's answer to use a hidden field to contain the value which ultimately gets sent to the server.

$('#inputStates').change(function(){
    var c =  $('#inputStates').val();
    $('#inputStates').val(getTextValue());
    $('#statesHidden').val(c);
});

function getTextValue(){
  var val =  $('#inputStates').val();
  var states = $('#states');
  var endVal = $(states).find('option[value="' + val + '"]'); 
  //depending on your logic, if endVal is empty it means the value wasn't found in the datalist, you can take some action here
  return endVal.text();  
}