Formularz wyboru HTML z opcją wprowadzenia wartości niestandardowej


108

Chciałbym mieć pole wejściowe, w którym użytkownicy mogą wprowadzać niestandardową wartość tekstową lub wybierać z listy rozwijanej. Zwykły <select>oferuje tylko opcje rozwijane.

Jak mogę <select>zaakceptować niestandardową wartość? Na przykład: Ford?

<select>
  <option value="volvo">Volvo</option>
  <option value="saab">Saab</option>
  <option value="mercedes">Mercedes</option>
  <option value="audi">Audi</option>
</select>

Możesz użyć javascript, aby dynamicznie dodać opcję do zaznaczenia, ale wtedy użycie tych informacji byłoby prawdziwym problemem.
David

Nie dodałem tej opcji dla wartości niestandardowych na mojej stronie internetowej finnmglas.com/contact, jednak ktoś skontaktował się ze mną z niestandardową wartością. To takie dziwne
finnmglas

Odpowiedzi:


263

HTML5 ma wbudowane pole kombi. Tworzysz tekst inputi plik datalist. Następnie należy dodać listatrybut do inputo wartości z idz datalist.

Aktualizacja: od marca 2019 r. Wszystkie główne przeglądarki (teraz w tym Safari 12.1 i iOS Safari 12.3) obsługują datalistdo poziomu wymaganego dla tej funkcjonalności. Zobacz caniuse, aby uzyskać szczegółowe informacje o obsłudze przeglądarek.

To wygląda tak:

<input type="text" list="cars" />
<datalist id="cars">
  <option>Volvo</option>
  <option>Saab</option>
  <option>Mercedes</option>
  <option>Audi</option>
</datalist>


3
Ta funkcja jest obsługiwana tylko przez około 50% przeglądarek. Obsługują to tylko najnowsze przeglądarki Firefox, Chrome i Opera; IE, Safari i przeglądarki mobilne nie. Zobacz http://caniuse.com/
markmarijnissen

2
Jest połowa 2016 roku (ponad 2 lata później), a większość przeglądarek nadal nie w pełni to obsługuje, przynajmniej bez znaczących błędów. Przynajmniej coś będzie działać na najnowszych wersjach prawie wszystkiego oprócz Safari / Safari iOS, ale musisz przetestować, aby upewnić się, że twoje przypadki użycia działają poprawnie. To wciąż najlepsza odpowiedź.
Michael Gaskill

1
U mnie to działa dobrze. W wielu przypadkach nie potrzebujemy obsługi starych przeglądarek. Dodałem tylko obraz ze strzałką w dół w tle pola wejściowego, aby dać użytkownikom wskazówkę, że można go rozwinąć. Kod (potrzebujesz aktualnego pliku obrazu):<input type="text" list="cars" style="background:url('images/arrow_down.png') no-repeat right center">
Eugene Kardash

4
Właśnie przetestowałem w najnowszych wersjach IE, Firefox i Chrome, wszystkie działają dobrze. Myślę, że jest to świetne proste rozwiązanie tego powszechnego problemu w wielu przypadkach.
kerl

3
Naprawdę chciałem tego użyć, ale musiałem ustawić wartość domyślną. Użytkownik widzi tylko wartość domyślną na liście rozwijanej w porównaniu ze wszystkimi opcjami (ponieważ są one odfiltrowane). Musieliby wiedzieć, aby wyczyścić pole wprowadzania, zanim zobaczą wszystkie opcje.
Justin,

27

Najnowszy JSFiddle Alena Saqe nie przełączył się na mnie w Firefoksie, więc pomyślałem, że zapewnię proste obejście HTML / JavaScript, które będzie dobrze działać w formularzach (w zakresie przesyłania) do dnia, w którym tag datalist zostanie zaakceptowany przez wszystkie przeglądarki / urządzenia. Aby uzyskać więcej informacji i zobaczyć, jak to działa, przejdź do: http://jsfiddle.net/6nq7w/4/ Uwaga: nie dopuszczaj spacji między przełączanym rodzeństwem!

<!DOCTYPE html>
<html>
<script>
function toggleField(hideObj,showObj){
  hideObj.disabled=true;        
  hideObj.style.display='none';
  showObj.disabled=false;   
  showObj.style.display='inline';
  showObj.focus();
}
</script>
<body>
<form name="BrowserSurvey" action="#">
Browser: <select name="browser" 
          onchange="if(this.options[this.selectedIndex].value=='customOption'){
              toggleField(this,this.nextSibling);
              this.selectedIndex='0';
          }">
            <option></option>
            <option value="customOption">[type a custom value]</option>
            <option>Chrome</option>
            <option>Firefox</option>
            <option>Internet Explorer</option>
            <option>Opera</option>
            <option>Safari</option>
        </select><input name="browser" style="display:none;" disabled="disabled" 
            onblur="if(this.value==''){toggleField(this,this.previousSibling);}">
<input type="submit" value="Submit">
</form>
</body>
</html>


Chciałbym ponownie przejść przez te skrzypce! Wersja Witch przeglądarki Firefox nie była tam obsługiwana! Przetestowałem to z jakąś wersją, której nie pamiętam! Sława!
Alen Saqe

Nie wiem, na której wersji FF byłem. Właśnie spojrzałem na FF34.0 i teraz otrzymuję funkcjonalność, więc nie martw się. Jednak domyślną opcję przełączania „Inne” można wyczyścić. Kiedy usuwam „Inne”, edytując wartość, menu rozwijane nie oferuje intuicyjnej wartości do wybrania (aby uzyskać dostęp do funkcji edycji). Myślę, że sprowadza się to do osobistych preferencji. Ponieważ strzałka menu rozwijanego jest nadal obecna, gdy pole jest edytowalne, użytkownicy mogą nie zdawać sobie sprawy, że pole jest edytowalne. Nie mam do ciebie przykrości; tylko garść opinii. Mój fragment kodu uwzględnia również nazewnictwo pól wewnątrz <form>.
mickmackusa

Końcowym rezultatem tego genialnego, ale nieczytelnego (dla mnie) skryptu + html jest dołączenie wybranej wartości opcji lub wprowadzonego tekstu do GET tej samej strony, co ciąg zapytania. Czy ktoś wie, jak przekonwertować akcję na POST, abym mógł pobrać wartość w pliku php i tam coś z tym zrobić?
Han,

Skomponowałem ten skrypt ze szczególnym zamiarem, aby zachowywał się zgodnie z przesłanymi formularzami html. Czy używasz metody post jako atrybutu w tagu formularza? @Han, jeśli utworzysz link 3v4l.org do swojego izolowanego fragmentu, mogę szybko rzucić okiem i ewentualnie doradzić.
mickmackusa,

1
Chłopcze, czuję się głupio. Zapomniałem umieścić metodę w tagu formularza. Działa tak, jak opublikowano z tą bardzo niewielką modyfikacją: <form name = "BrowserSurvey" method = "post" action = "/ gotThis.php"> ... Piękny skrypt, mickmackusa. Dzięki za podpowiedź!
Han

16

Rozwiązanie jQuery!

Demo: http://jsfiddle.net/69wP6/2/

Kolejne demo poniżej (zaktualizowane!)

Potrzebowałem czegoś podobnego w przypadku, gdy miałem ustalone opcje i chciałem, aby jedna inna opcja była edytowalna! W tym przypadku wprowadziłem ukryte dane wejściowe, które nakładałyby się na opcję wyboru i byłyby edytowalne i użyłem jQuery, aby wszystko działało płynnie.

Dzielę się z wami wszystkimi skrzypcami!

HTML

<div id="billdesc">
    <select id="test">
      <option class="non" value="option1">Option1</option>
      <option class="non" value="option2">Option2</option>
      <option class="editable" value="other">Other</option>
    </select>
    <input class="editOption" style="display:none;"></input>
</div>

CSS

body{
    background: blue;
}
#billdesc{
    padding-top: 50px;
}
#test{
    width: 100%;
    height: 30px;
}
option {
    height: 30px;
    line-height: 30px;
}

.editOption{
    width: 90%;
    height: 24px;
    position: relative;
    top: -30px

}

jQuery

var initialText = $('.editable').val();
$('.editOption').val(initialText);

$('#test').change(function(){
var selected = $('option:selected', this).attr('class');
var optionText = $('.editable').text();

if(selected == "editable"){
  $('.editOption').show();


  $('.editOption').keyup(function(){
      var editText = $('.editOption').val();
      $('.editable').val(editText);
      $('.editable').html(editText);
  });

}else{
  $('.editOption').hide();
}
});

Edycja: Dodano kilka prostych elementów, aby ludzie mogli wyraźnie zobaczyć, gdzie kończy się wprowadzanie!

JS Fiddle: http://jsfiddle.net/69wP6/4/


11

Naprawdę nie możesz. Będziesz musiał mieć zarówno menu rozwijane, jak i pole tekstowe, i poprosić o wybranie lub wypełnienie formularza. Bez javascript możesz utworzyć osobny zestaw przycisków opcji, w którym wybierają menu rozwijane lub wprowadzanie tekstu, ale wydaje mi się to kłopotliwe. W przypadku niektórych skryptów javascript można przełączać wyłączanie jednego lub drugiego w zależności od tego, który wybiorą, na przykład mieć opcję „inne” w menu rozwijanym, która uruchamia pole tekstowe.


9

Jeśli opcja datalist nie spełnia Twoich wymagań, zajrzyj do biblioteki Select2 i „ Dynamicznego tworzenia opcji

$(".js-example-tags").select2({
  tags: true
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.min.js"></script>


<select class="form-control js-example-tags">
  <option selected="selected">orange</option>
  <option>white</option>
  <option>purple</option>
</select>


0

Korzystając z jednego z powyższych rozwiązań (@mickmackusa), wykonałem działający prototyp w React 16.8+ przy użyciu hooków.

https://codesandbox.io/s/heuristic-dewdney-0h2y2

Mam nadzieję, że to komuś pomoże.


Jestem zaszczycony. Właśnie sprawdziłem swoje rekordy i był to 12. post, który napisałem tutaj na Stack Overflow - wydaje się, że milion lat temu.
mickmackusa,

Właśnie grałem z twoim linkiem do dema i wygląda na to, że straciłeś efekt nieskończonego przełączania się między dwoma typami pól.
mickmackusa
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.