2015-04-26 9 views
39

Derzeit ist das <datalist> Element HTML5 einreichen in den meisten gängigen Browsern (außer Safari) und scheint wie eine interessante Art und Weise hinzuzufügen, Vorschläge zu einem Eingang unterstützt wird.anzeigen Datalist Etikett aber den tatsächlichen Wert

Es scheint jedoch einige Diskrepanzen zwischen der Implementierung des value Attributs und dem inneren Text auf dem <option> zu geben. Zum Beispiel:

<input list="answers" name="answer"> 
<datalist id="answers"> 
    <option value="42">The answer</option> 
</datalist> 

Dies wird unterschiedlich von verschiedenen Browsern behandelt:

Chrome und Opera:
Datalist in Chrome/Opera

FireFox und IE 11:
Datalist in FireFox

Nach einer Auswahl der Eingabe wird mit dem Wert und nicht mit dem inneren Text gefüllt. Ich will nur der Benutzer den Text („Die Antwort“) in der Dropdown-Liste und in den Eingang zu sehen, aber geben Sie den Wert 42 auf einreichen, wie ein select würde.

Wie kann ich alle Browser die Dropdown-Liste zeigt die Straßennamen (Text Innen) des <option> s, aber senden Sie das value Attribut, wenn das Formular abgeschickt wird?

+0

Ich denke, Firefox und IE11 sind hier falsch; gemäß den Spezifikationen [One] (https://html.spec.whatwg.org/multipage/forms.html#the-option-element) und [Two] (http://www.w3.org/TR/2011 /WD-html5-author-20110809/the-option-element.html#the-option-element), scheint es, dass "value =" "' Vorrang vor einem String innerhalb der Tags haben sollte, wenn ein 'value = 'vorhanden ist "" erklärte. Also wäre der Vorschlag, "die Antwort" zu deinem Wertattribut zu machen. – TylerH

+0

@TylerH Nein - Firefox und IE11 sind hier korrekt: Das Label-Attribut bietet eine Bezeichnung für Element. ** Die Bezeichnung eines Optionselements ist der Wert des Label-Inhaltsattributs, falls vorhanden, oder, falls nicht, der Wert des Text-IDL-Attributs des Elements. ** http://www.w3.org/ Tr/html5/forms.html # attr-option-label – easwee

+0

@easwee Das sagt nur, dass das Label sein sollte, was in Label ist, wenn es ein Label gibt, und dass der Wert sein sollte, was in dem Wert ist, wenn es einen Wert gibt. Es gibt nicht an, welches Vorrang hat. – TylerH

Antwort

49

Beachten Sie, dass datalist als select nicht gleich ist. Benutzer können einen benutzerdefinierten Wert eingeben, der nicht in der Liste enthalten ist, und es wäre unmöglich, einen alternativen Wert für diese Eingabe abzurufen, ohne ihn zuvor zu definieren.

Mögliche Wege Benutzereingaben zu verarbeiten sind den eingegebenen Wert zu unterbreiten, wie, oder füllen sie einen leeren Wert oder einreichenden zu verhindern. Diese Antwort behandelt nur die ersten beiden Optionen.

Wenn Sie ganz Benutzereingaben nicht zulassen wollen, vielleicht select wäre eine bessere Wahl sein.


Um nur den Textwert des option in der Dropdown-Liste zu zeigen, verwenden wir den inneren Text für sie und lassen Sie die value Attribut. Der tatsächliche Wert, den wir senden möchten, wird in einem benutzerdefinierten data-value-Attribut gespeichert:

Zum Senden data-value müssen wir eine <input type="hidden"> verwenden. In diesem Fall lassen wir die name="answer" auf der regulären Eingabe weg und verschieben sie in die versteckte Kopie.

<input list="suggestionList" id="answerInput"> 
<datalist id="suggestionList"> 
    <option data-value="42">The answer</option> 
</datalist> 
<input type="hidden" name="answer" id="answerInput-hidden">

diese Weise, wenn der Text in den ursprünglichen Eingang Änderungen, die wir Javascript auch im datalist vorhanden, wenn der Text überprüfen können und seine data-value holen. Dieser Wert wird in die versteckte Eingabe eingefügt und übergeben.

document.querySelector('input[list]').addEventListener('input', function(e) { 
    var input = e.target, 
     list = input.getAttribute('list'), 
     options = document.querySelectorAll('#' + list + ' option'), 
     hiddenInput = document.getElementById(input.id + '-hidden'), 
     inputValue = input.value; 

    hiddenInput.value = inputValue; 

    for(var i = 0; i < options.length; i++) { 
     var option = options[i]; 

     if(option.innerText === inputValue) { 
      hiddenInput.value = option.getAttribute('data-value'); 
      break; 
     } 
    } 
}); 

Die ID answer und answer-hidden auf dem regulären und versteckten Eingang werden für das Skript erforderlich zu wissen, welchem ​​Eingang, an die verborgene Version gehört. Auf diese Weise ist es möglich, mehrere input s auf der gleichen Seite mit einem oder mehreren datalist s bieten Anregungen zu haben.

Alle Benutzereingaben werden unverändert übermittelt. Um einen leeren Wert einreichen, wenn die Benutzereingabe nicht in der Datenliste ist, ändern hiddenInput.value = label zu hiddenInput.value = ""


Arbeits jsFiddle Beispiele: plain javascript und jQuery

+0

Wie würden Sie mit Optionen mit demselben internen Text, aber unterschiedlichen Datenwerten umgehen? z.B. http://jsfiddle.net/7k3sovht/78/ – bigbearzhu

+1

Soweit ich sagen kann, gibt es keine Möglichkeit, zwischen den beiden Optionen zu unterscheiden. Da kein Benutzerereignis zu hören ist, ist es unmöglich zu wissen, welche der beiden tatsächlich ausgewählt wurde. Wir wissen nur, welcher Wert im Eingabefeld endet. –

+0

@StephanMuller großartige Antwort für jemanden, der mehr HTML5 wie ich lernt, danke! Wie würden Sie die Textbox für die Demo nach dem Senden löschen? – Chris22

16

die Lösung, die ich verwenden ist

<input list="answers" id="answer"> 
<datalist id="answers"> 
    <option data-value="42" value="The answer"> 
</datalist> 

Der Zugriff auf den Wert an den Server per Javascript gesendet werden als

var shownVal= document.getElementById("answer").value; 
var value2send=document.querySelector("#answers option[value='"+shownVal+"']").dataset.value; 

hoffe es hilft

+0

Ich bekomme keinen Grund undefiniert? – Dejell

+1

Problemlösung mit console.log bei jedem Schritt. Stellen Sie sicher, dass Sie denselben ID-Wert verwenden, den Sie anrufen. Und überprüfen Sie auch die Semikollonen. –

Verwandte Themen