Obecnie <datalist>
element HTML5 jest obsługiwany w większości głównych przeglądarek (z wyjątkiem Safari) i wydaje się interesującym sposobem dodawania sugestii do danych wejściowych.
Wydaje się jednak, że istnieją pewne rozbieżności między implementacją value
atrybutu a tekstem wewnętrznym w <option>
. Na przykład:
<input list="answers" name="answer">
<datalist id="answers">
<option value="42">The answer</option>
</datalist>
Jest to obsługiwane inaczej w różnych przeglądarkach:
Chrome i Opera:
FireFox i IE 11:
Po wybraniu jednego, dane wejściowe są wypełniane wartością, a nie tekstem wewnętrznym. Chcę tylko, aby użytkownik zobaczył tekst („Odpowiedź”) w menu rozwijanym i w danych wejściowych, ale przekazał wartość 42
podczas przesyłania, tak jak w select
przypadku.
Jak sprawić, by wszystkie przeglądarki wyświetlały na liście rozwijanej etykiety (tekst wewnętrzny) <option>
, ale wysyłały value
atrybut po przesłaniu formularza?
źródło
value=""
powinno mieć pierwszeństwo przed ciągiem znaków w tagach, gdy tylko jestvalue=""
zadeklarowane. Zatem sugestią byłoby uczynienie „odpowiedzi” swoim atrybutem wartości.Odpowiedzi:
Zwróć na to uwagę
datalist
to nie to samo, co plikselect
. Pozwala użytkownikom wprowadzić niestandardową wartość, której nie ma na liście, i niemożliwe byłoby pobranie alternatywnej wartości dla takich danych wejściowych bez uprzedniego zdefiniowania jej.Możliwe sposoby obsługi danych wejściowych użytkownika to przesłanie wprowadzonej wartości tak, jak jest, przesłanie pustej wartości lub zapobieżenie przesłaniu. Ta odpowiedź dotyczy tylko dwóch pierwszych opcji.
Jeśli chcesz całkowicie zabronić wprowadzania danych przez użytkownika, być może
select
byłby lepszym wyborem.Aby wyświetlić tylko wartość tekstową
option
w menu rozwijanym, używamy do tego tekstu wewnętrznego i pomijamyvalue
atrybut. Rzeczywista wartość, którą chcemy przesłać, jest przechowywana w niestandardowymdata-value
atrybucie:Aby to przesłać,
data-value
musimy użyć pliku<input type="hidden">
. W tym przypadku pomijamyname="answer"
zwykłe wejście i przenosimy je do ukrytej kopii.<input list="suggestionList" id="answerInput"> <datalist id="suggestionList"> <option data-value="42">The answer</option> </datalist> <input type="hidden" name="answer" id="answerInput-hidden">
W ten sposób, gdy tekst w oryginalnym wejściu zmieni się, możemy użyć javascript, aby sprawdzić, czy tekst również występuje w pliku
datalist
i pobrać jegodata-value
. Ta wartość jest wstawiana do ukrytych danych wejściowych i przesyłana.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.getAttribute('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; } } });
Identyfikator
answer
orazanswer-hidden
zwykłe i ukryte dane wejściowe są potrzebne, aby skrypt wiedział, które wejście należy do której ukrytej wersji. W ten sposób możliwe jest umieszczenie wieluinput
adresów na tej samej stronie, przy czym jeden lub więcejdatalist
zawiera sugestie.Wszelkie dane wejściowe użytkownika są przesyłane bez zmian. Aby przesłać pustą wartość, gdy dane wejściowe użytkownika nie są obecne w danych, zmień
hiddenInput.value = inputValue
nahiddenInput.value = ""
Działające przykłady jsFiddle: zwykły javascript i jQuery
źródło
Rozwiązanie, którego używam, jest następujące:
<input list="answers" id="answer"> <datalist id="answers"> <option data-value="42" value="The answer"> </datalist>
Następnie uzyskaj dostęp do wartości, która ma zostać wysłana na serwer, używając JavaScript w następujący sposób:
var shownVal = document.getElementById("answer").value; var value2send = document.querySelector("#answers option[value='"+shownVal+"']").dataset.value;
Mam nadzieję, że to pomoże.
źródło
input
element atrybutemdata-value="1"
. Następnie napisałem następujący blok w miejscach, w których wartość byłaif (typeof $(this).attr('data-value') != 'undefined') { var id = $(this).attr('name'); val = $('#'+id).find('option[value="'+val+'"]').attr('data-value'); }
Zdaję sobie sprawę, że może to być trochę za późno, ale natknąłem się na to i zastanawiałem się, jak radzić sobie z sytuacjami z wieloma identycznymi wartościami, ale różnymi kluczami (zgodnie z komentarzem bigbearzhu).
Dlatego nieznacznie zmodyfikowałem odpowiedź Stephana Mullera:
Datalist z nieunikalnymi wartościami:
<input list="answers" name="answer" id="answerInput"> <datalist id="answers"> <option value="42">The answer</option> <option value="43">The answer</option> <option value="44">Another Answer</option> </datalist> <input type="hidden" name="answer" id="answerInput-hidden">
Gdy użytkownik wybierze opcję, zastępuje przeglądarka
input.value
zvalue
tegodatalist
wariantu zamiastinnerText
.Poniższy kod następnie sprawdza, czy występuje
option
z tymvalue
, wypycha go do ukrytego pola i zastępujeinput.value
goinnerText
.document.querySelector('#answerInput').addEventListener('input', function(e) { var input = e.target, list = input.getAttribute('list'), options = document.querySelectorAll('#' + list + ' option[value="'+input.value+'"]'), hiddenInput = document.getElementById(input.getAttribute('id') + '-hidden'); if (options.length > 0) { hiddenInput.value = input.value; input.value = options[0].innerText; } });
W konsekwencji użytkownik widzi wszystko, co
innerText
mówi opcja , ale unikalny identyfikatoroption.value
jest dostępny po przesłaniu formularza. Demo jsFiddleźródło
Po kliknięciu przycisku wyszukiwania można go znaleźć bez pętli.
Po prostu dodaj do opcji atrybut o potrzebnej wartości (lubię
id
) i wyszukaj go dokładnie.$('#search_wrapper button').on('click', function(){ console.log($('option[value="'+ $('#autocomplete_input').val() +'"]').data('value')); })
źródło
Używając PHP, znalazłem dość prosty sposób na zrobienie tego. Chłopaki, po prostu użyj czegoś takiego
<input list="customers" name="customer_id" required class="form-control" placeholder="Customer Name"> <datalist id="customers"> <?php $querySnamex = "SELECT * FROM `customer` WHERE fname!='' AND lname!='' order by customer_id ASC"; $resultSnamex = mysqli_query($con,$querySnamex) or die(mysql_error()); while ($row_this = mysqli_fetch_array($resultSnamex)) { echo '<option data-value="'.$row_this['customer_id'].'">'.$row_this['fname'].' '.$row_this['lname'].'</option> <input type="hidden" name="customer_id_real" value="'.$row_this['customer_id'].'" id="answerInput-hidden">'; } ?> </datalist>
Powyższy kod pozwala formularzowi nosić identyfikator również wybranej opcji.
źródło
customer_id_real
przesłanej, a nie wybraną wartość.