Jak utworzyć symbol zastępczy dla pola „wybierz”?

1542

Używam symboli zastępczych do wprowadzania tekstu, co działa dobrze. Ale chciałbym również użyć symbolu zastępczego dla moich pól wyboru. Oczywiście mogę po prostu użyć tego kodu:

<select>
    <option value="">Select your option</option>
    <option value="hurr">Durr</option>
</select>

Ale „Wybierz opcję” ma kolor czarny zamiast jasnoszarego. Więc moje rozwiązanie może być oparte na CSS. jQuery też jest w porządku.

To powoduje, że opcja ta staje się szara w menu rozwijanym (więc po kliknięciu strzałki):

option:first {
    color: #999;
}

Pytanie brzmi: w jaki sposób ludzie tworzą symbole zastępcze w polach wyboru? Ale już na to odpowiedziano, na zdrowie.

A użycie tego powoduje, że wybrana wartość jest zawsze szara (nawet po wybraniu rzeczywistej opcji):

select {
    color: #999;
}
Tomasz
źródło
1
Na wypadek, gdyby ktoś to przeczytał - zamieściłem bardziej popularne rozwiązanie dla nowoczesnych przeglądarek z wbudowaną funkcją sprawdzania poprawności. Witamy w roku 2020;)
Jurik

Odpowiedzi:

2973

Non-CSS - brak odpowiedzi na JavaScript / jQuery:

<select>
    <option value="" disabled selected>Select your option</option>
    <option value="hurr">Durr</option>
</select>

David
źródło
134
Firefox (10) nie wyświetla wyłączonej opcji jako domyślnego wyboru (symbol zastępczy). Domyślnie pokazuje następny, w tym przypadku „Durr”.
jarnoan
53
Zazwyczaj dodaję zarówno wyłączone, jak i wybrane. Wydaje się również działać w FF.
nilskp
11
<select> <option value="" disabled selected>Select your option</option> </select>
kolypto
183
Nie jest to prawidłowa odpowiedź, ponieważ (uważam) pytający chce, aby zaznaczenie było szare, dopóki nie zostanie wybrana inna wartość. Ta odpowiedź powoduje, że opcja staje się szara w menu rozwijanym; ale nie zaznaczony element.
Bill
22
wybierz {opcja [wyłączone] {wyświetl: brak; }}
Dimael Vertigo
821

Właśnie natknąłem się na to pytanie, a oto, co działa w Firefoksie i Chrome (przynajmniej):

<style>
select:invalid { color: gray; }
</style>
<form>
<select required>
    <option value="" disabled selected hidden>Please Choose...</option>
    <option value="0">Open when powered (most valves do this)</option>
    <option value="1">Closed when powered, auto-opens when power is cut</option>
</select>
</form>

Opcja Wyłączona zatrzymuje zaznaczanie <option>zarówno myszą, jak i klawiaturą, natomiast samo użycie 'display:none'pozwala użytkownikowi nadal wybierać za pomocą strzałek na klawiaturze. 'display:none'Styl po prostu sprawia, że pole listy wygląd „miły”.

Uwaga: użycie pustego valueatrybutu w opcji „symbol zastępczy” pozwala na sprawdzenie poprawności (wymagany atrybut) w celu obejścia posiadania „symbolu zastępczego”, więc jeśli opcja nie zostanie zmieniona, ale jest wymagana, przeglądarka powinna poprosić użytkownika o wybranie opcji z listy.

Aktualizacja (lipiec 2015 r.):

Ta metoda została potwierdzona w następujących przeglądarkach:

  • Google Chrome - v.43.0.2357.132
  • Mozilla Firefox - wer. 39.0
  • Safari - wersja 8.0.7 (symbol zastępczy jest widoczny w menu rozwijanym, ale nie można go wybrać)
  • Microsoft Internet Explorer - v.11 (symbol zastępczy jest widoczny w menu rozwijanym, ale nie można go wybrać)
  • Project Spartan - v.15.10130 (symbol zastępczy jest widoczny w menu rozwijanym, ale nie można go wybrać)

Aktualizacja (październik 2015 r.):

Usunąłem na style="display: none"korzyść atrybutu HTML5, hiddenktóry ma szerokie wsparcie. hiddenElement ma podobne cechy jak display: nonew Safari, Internet Explorer (projekt Spartan wymaga kontroli), gdzie optionjest widoczny na liście rozwijanej, ale to nie jest wybierana.

Aktualizacja (styczeń 2016 r.):

Gdy selectelement jest required, pozwala na użycie :invalidpseudoklasy CSS, która umożliwia stylizację selectelementu w stanie „zastępczym”. :invaliddziała tutaj z powodu pustej wartości w symbolu zastępczym option.

Po ustawieniu wartości :invalidpseudoklasa zostanie porzucona. Opcjonalnie możesz również użyć, :validjeśli chcesz.

Większość przeglądarek obsługuje tę pseudoklasę. Internet Explorer 10 i nowszy. Działa to najlepiej w przypadku niestandardowych selectelementów; w niektórych przypadkach, np. (Mac w Chrome / Safari), musisz zmienić domyślny wygląd selectpudełka, aby wyświetlały się określone style, tj . background-colori color. Przykłady i więcej informacji na temat zgodności można znaleźć na stronie developer.mozilla.org .

Wygląd elementu natywnego Mac w Chrome:

Wybierz pole macierzystego Maca w Chrome

Używanie zmienionego elementu obramowania Mac w Chrome:

Zmieniono zaznaczone pole Mac w Chrome

William Isted
źródło
5
@jaacob W testowanych przeze mnie przeglądarkach styl „display: none” ukrywa na liście opcję „Proszę wybrać”, dzięki czemu wygląda ładniej.
William Isted
38
Ważne jest, aby pamiętać, że wyłączonej opcji nie można ponownie wybrać: jeśli wybór jest obowiązkowy, jest to w porządku - ale nie, jeśli wybór jest opcjonalny.
Robert Mark Bram
2
Explorer11 ignoruje display:nonestyl.
T30
1
Wyrazy uznania dla @MattW za wypracowanie :invalidsposobu, zanim to zrobiłem.
William Isted
3
Możesz również dodać regułę, aby „zresetować” coloropcje obsługi przeglądarek tak jak w tym skrzypce . Pomogłoby to potwierdzić, że wyłączony optionjest symbolem zastępczym. (Edycja: Widzę, że MattW już to omówił w swojej odpowiedzi)
Kudłaty
251

W przypadku wymaganego pola istnieje nowoczesne rozwiązanie CSS w czysto CSS:

select:required:invalid {
  color: gray;
}
option[value=""][disabled] {
  display: none;
}
option {
  color: black;
}
<select required>
  <option value="" disabled selected>Select something...</option>
  <option value="1">One</option>
  <option value="2">Two</option>
</select>

MattW
źródło
7
Niesamowite - to była odpowiedź na dole (bez opinii), która była najprostsza i faktycznie działa idealnie. Dzięki! Mam nadzieję, że ta odpowiedź osiągnie szczyt.
Dan Nissenbaum
2
@ DanNissenbaum Spóźniłem się na grę, a do tego musi requireddziałać, więc nie ma sensu, jeśli chcesz, aby pole było opcjonalne.
MattW,
1
Nawiasem mówiąc, :requiredselektor nie jest obsługiwany w IE8 i niższych wersjach. :invalidSelektor nie jest obsługiwana w IE9 i poniżej. quirksmode.org/css/selectors
Matt Wagner
4
Brak rozwiązania dla niewymaganego wyboru?
user3494047,
1
@ user3494047 nie z tym podejściem - requiredwarunek powoduje, że przeglądarka stosuje :invalidpseudoklasę po wybraniu symbolu zastępczego. [value=""]nie będzie działać jako zamiennik, ponieważ to, co jest aktualizowane przez interakcję użytkownika, jest właściwością value, ale ta składnia CSS odnosi się do (nieistniejącego) atrybutu .
MattW
105

Coś takiego:

HTML:

<select id="choice">
    <option value="0" selected="selected">Choose...</option>
    <option value="1">Something</option>
    <option value="2">Something else</option>
    <option value="3">Another choice</option>
</select>

CSS:

#choice option { color: black; }
.empty { color: gray; }

JavaScript:

$("#choice").change(function () {
    if($(this).val() == "0") $(this).addClass("empty");
    else $(this).removeClass("empty")
});

$("#choice").change();

Przykład roboczy: http://jsfiddle.net/Zmf6t/

Albireo
źródło
8
to właśnie zrobiłem ostatnio. ale dodałem moduł obsługi klawiszy, aby zmiana nastąpiła również po wybraniu opcji za pomocą klawiatury (za pomocą strzałek lub skrótów literowych) jsfiddle.net/Zmf6t/131
Radu,
postawiło mnie to na właściwej drodze ... jednak zrobiłem wartość = "" (nic między cudzysłowami), więc kiedy kliknięto przycisk wysyłania, nadal nie udało się zweryfikować pierwszej opcji i pojawiło się okienko przeglądarki informujące o tym wybrać opcję ... dzięki @Albireo
Craig Wayne
Dlaczego wyraźnie wywołałeś funkcję zmiany?
Forever
@ Na zawsze, ponieważ ustawiłem klasę CSS w module obsługi zmiany zdarzenia select, więc jeśli nie podniesiesz ręcznie zdarzenia podczas budowania formantu, styl nie zostanie zastosowany (zostanie zastosowany tylko wtedy, gdy użytkownik ręcznie zmieni wartość).
Albireo
To nie działa w JQeury 3.4.1
geobudex
45

Właśnie dodałem ukryty atrybut w optionpodobny sposób poniżej. Dla mnie działa dobrze.

<select>
  <option hidden>Sex</option>
  <option>Male</option>
  <option>Female</option>
</select>

Ajithkumar S.
źródło
2
Dla przypomnienia, to nie działa dla mnie (Chrome na Win10).
Chris Rae,
Ale nie można tego rozbroić. W końcu wybierasz jedną, ale nie możesz zresetować, jeśli zmienisz zdanie.
Thielicious,
Tak! Ale wewnątrz formularza użytkownik musi wybrać jedną z tych opcji. Jeśli nie jest to pole wymagane, usuń ukryty atrybut.
Ajithkumar S
35

Poniższe rozwiązanie działa również w przeglądarce Firefox bez JavaScript:

option[default] {
  display: none;
}
<select>
  <option value="" default selected>Select Your Age</option>
  <option value="1">1</option>
  <option value="2">2</option>
  <option value="3">3</option>
  <option value="4">4</option>
</select>

Dani-Br
źródło
26

Miałem ten sam problem i podczas wyszukiwania natknąłem się na to pytanie, a kiedy znalazłem dla siebie dobre rozwiązanie, chciałbym się z wami podzielić na wypadek, gdyby ktoś mógł z niego skorzystać.

Oto on:

HTML:

<select class="place_holder dropdown">
    <option selected="selected" style=" display: none;">Sort by</option>
    <option>two</option>
    <option>something</option>
    <option>4</option>
    <option>5</option>
</select>

CSS:

.place_holder {
    color: gray;
}
option {
    color: #000000;
}

JavaScript:

jQuery(".dropdown").change(function () {
    jQuery(this).removeClass("place_holder");
});

Po tym, jak klient dokona pierwszego wyboru, szary kolor nie jest potrzebny, więc kod JavaScript usuwa klasę place_holder.

Dzięki @ user1096901, jako obejście dla przeglądarki Internet Explorer, możesz place_holderponownie dodać klasę na wypadek, gdyby pierwsza opcja została ponownie wybrana :)

rramiii
źródło
2
W niektórych przeglądarkach wciąż może wybrać ekran: brak opcji, ponieważ nie jest ukryty.
Srneczek
Obejściem tego problemu jest ponowne dodanie klasy „place_holder” na wypadek, gdyby wybrana była pierwsza opcja :)
rramiii
23

Nie ma potrzeby używania JavaScript ani CSS, tylko trzy atrybuty:

<select>
    <option selected disabled hidden>Default Value</option>
    <option>Value 1</option>
    <option>Value 2</option>
    <option>Value 3</option>
    <option>Value 4</option>
</select>

W ogóle nie pokazuje opcji; po prostu ustawia wartość opcji jako domyślną.

Jeśli jednak nie podoba ci się symbol zastępczy tego samego koloru, co pozostałe , możesz to naprawić w następujący sposób:

<!DOCTYPE html>
<html>
    <head>
        <title>Placeholder for select tag drop-down menu</title>
    </head>

    <body onload="document.getElementById('mySelect').selectedIndex = 0">
        <select id="mySelect" onchange="document.getElementById('mySelect').style.color = 'black'"     style="color: gray;    width: 150px;">
          <option value="" hidden>Select your beverage</option> <!-- placeholder -->
          <option value="water" style="color:black" >Water</option>
          <option value="milk" style="color:black" >Milk</option>
          <option value="soda" style="color:black" >Soda</option>
        </select>
    </body>
</html>

Oczywiście możesz podzielić funkcje i przynajmniej CSS select na osobne pliki.

Uwaga: funkcja onload naprawia błąd odświeżania.

Jacob Schneider
źródło
To nie działa, jeśli ukryta opcja jest jedyna
Eridanis
ale dlaczego miałbyś mieć rozwijane menu z tylko jedną opcją?
Jacob Schneider
Mam wyskakujące okienko z zakładkami, a menu rozwijane z tab3 pobiera dane z tab2, które wyświetla. Twoja odpowiedź jest dobra i jest to przypadek narożny, ale spodziewałbym się, że domyślna wartość pojawi się jako pierwsza opcja, zamiast tego pojawi się pusta lista rozwijana. Zobacz tutaj: jsfiddle.net/n66L7sza
Eridanis
To dobry punkt, w którym to przypadku możesz zeskanować długość listy rozwijanej, jeśli jest ona zerowa, a następnie usuń ukryty atrybut
Jacob Schneider
To nie wydaje się działać poprawnie w Google Chrome 65.0.3325.181 na MacOS, nie pokazuje ukrytego wpisu i wybiera ten pod nim.
Jamie H,
19

Użytkownik nie powinien widzieć symbolu zastępczego w wybranych opcjach. Sugeruję użycie hiddenatrybutu dla opcji zastępczej i nie potrzebujesz selectedatrybutu dla tej opcji. Możesz to po prostu ustawić jako pierwszy.

select:not(:valid) {
  color: #999;
}
<select required>
    <option value="" hidden>Select your option</option>
    <option value="0">First option</option>
    <option value="1">Second option</option>
</select>

Roman Jakowów
źródło
2
lub select:invalidjest również ważny.
elquimista
2
Polecam ten, ponieważ nie zawiera tekstu zastępczego na liście, przynajmniej w Chrome.
JoeRaid
Zwróć uwagę, że styl nie działa bezrequired
akmalhakimi1991,
18

Tutaj zmodyfikowałem odpowiedź Dawida (odpowiedź zaakceptowana). Na swoją odpowiedź umieścił wyłączony i wybrany atrybut na optiontagu, ale kiedy również umieścimy ukryty tag, będzie on wyglądał znacznie lepiej.

Dodanie dodatkowego ukrytego atrybutu do optiontagu zapobiegnie ponownemu wybraniu opcji „Wybierz opcję” po wybraniu opcji „Durr”.

<select>
    <option value="" disabled selected hidden>Select your option</option>
    <option value="hurr">Durr</option>
</select>

Nawaraj
źródło
Dzięki za aktualizację, ale odpowiedź wciąż nie wyjaśnia, dlaczego wygląda inaczej. Na przykład ta odpowiedź zapobiega ponownemu wybraniu opcji „Wybierz opcję” po wybraniu opcji „Durr” . Który atrybut powoduje takie zachowanie?
bgran
16

Tutaj jest moje:

select:focus option.holder {
  display: none;
}
<select>
    <option selected="selected" class="holder">Please select</option>
    <option value="1">Option #1</option>
    <option value="2">Option #2</option>

</select>

Will Wang
źródło
Możesz po prostu dodać <option value="" selected disabled>Please select</option>jako pierwszą opcję.
sstauross
Nie czyni obiektu zastępczego jasnoszarym.
Chloe,
12

Widzę oznaki poprawnych odpowiedzi, ale aby to wszystko połączyć, oto moje rozwiązanie:

select {
  color: grey;
}

option {
  color: black;
}

option[default] {
   display: none;
}
<select>
    <option value="" default selected>Select your option</option>
    <option value="hurr">Durr</option>
</select>

użytkownik3520445
źródło
8
Durrjest zaznaczone na szaro po wybraniu. Zmusza to zawsze zamknięte pole wyboru do szarości.
Chloe,
9

Jeśli używasz Angulara, wykonaj następujące czynności:

<select>
    <option [ngValue]="undefined"  disabled selected>Select your option</option>
    <option [ngValue]="hurr">Durr</option>
</select>

Arun Kumar
źródło
Możesz dodać hiddenatrybut, aby ta opcja nie była wyświetlana podczas otwierania select. Ale dzięki w jakikolwiek sposób za tę odpowiedź, zadziałała dla mnie.
dcg
5

To HTML + CSSrozwiązanie działało dla mnie:

form select:invalid {
  color: gray;
}

form select option:first-child {
  color: gray;
}

form select:invalid option:not(:first-child) {
  color: black;
}
<form>
  <select required>
    <option value="">Select Planet...</option>
    <option value="earth">Earth</option>
    <option value="pandora">Pandora</option>
  </select>
</form>

Powodzenia...

Akash
źródło
Wydaje się, że nie działa w JQuery 3.4.1
geobudex
5

Inna możliwość w JavaScript:

 $('body').on('change', 'select', function (ev){
    if($(this).find('option:selected').val() == ""){
        $(this).css('color', '#999');
        $(this).children().css('color', 'black');
    }
    else {
        $(this).css('color', 'black');
        $(this).children().css('color', 'black');
    }
});

JSFiddle

Jean-Philippe Emond
źródło
4

Uwielbiam przyjęte rozwiązanie i działa świetnie bez JavaScript.

Chcę tylko dodać, w jaki sposób zastosowałem tę odpowiedź dla kontrolowanego komponentu React , ponieważ zajęło mi to kilka prób, aby to rozgryźć. Byłoby to naprawdę łatwe do włączenia react-selecti wykonania, ale jeśli nie potrzebujesz niesamowitej funkcjonalności, jaką zapewnia to repozytorium, czego nie mam w przypadku omawianego projektu, nie ma potrzeby dodawania więcej kilobajtów do mojego pakietu. Uwaga: react-selectobsługuje symbole zastępcze w selekcjach poprzez złożony system różnych elementów inputsi htmlelementów.

W React dla kontrolowanego komponentu nie można dodać selectedatrybutu do opcji. React obsługuje stan zaznaczenia za pomocą valueatrybutu na selectsobie, wraz z modułem obsługi zmian, w którym wartość powinna pasować do jednego z atrybutów wartości w samych opcjach.

Takich jak na przykład

<select value={this.state.selectValue} onChange={this.handleChange} required={true}>
    {options}
</select>

Ponieważ byłoby to niewłaściwe i w rzeczywistości spowodowałoby błąd dodania selectedatrybutu do jednej z opcji, co wtedy?

Odpowiedź jest prosta, gdy się nad tym zastanowisz. Ponieważ chcemy, aby nasz pierwszy optionbył selectedrównie dobry, disabledi hiddenmusimy zrobić trzy rzeczy:

  1. Dodaj atrybut hiddeni disableddo pierwszego zdefiniowanego option.
  2. Ustaw wartość pierwszego optionna pusty ciąg.
  3. Zainicjuj wartość selectto również pusty ciąg.
state = { selectValue = "" } // State or props or their equivalent

// In the render function
<select value={this.state.selectValue} onChange={this.handleChange} required={true}>
    <option key="someKey" value="" disabled="disabled" hidden="hidden">Select from Below</option>
    {renderOptions()}
</select>

Teraz możesz stylizować zaznaczenie jak wskazano powyżej (lub za pomocą a, classNamejeśli wolisz).

select:invalid { color: gray; }
wlh
źródło
3

[type="text"]Symbol zastępczy stylu wprowadzania dla wybranych elementów

Poniższe rozwiązanie symuluje symbol zastępczy, ponieważ odnosi się do input[type="text"]elementu:

$('.example').change(function () {
  $(this).css('color', $(this).val() === '' ? '#999' : '#555');
});
.example {
  color: #999;
}

.example > option {
  color: #555;
}

.example > option[value=""] {
  color: #999;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<select class="example">
  <option value="">Select Option</option>
  <option>Option 1</option>
  <option>Option 2</option>
  <option>Option 3</option>
</select>

Grant Miller
źródło
3

Chciałem, aby SELECT był szary, dopóki nie zostanie wybrany, więc dla tego fragmentu HTML:

<select>
  <option value="" disabled selected>Select your option</option>
  <option value="hurr">Durr</option>
</select>

Dodałem te definicje CSS:

select { color: grey; }
select:valid { color: black; }

Działa zgodnie z oczekiwaniami w Chrome / Safari i może także w innych przeglądarkach, ale nie sprawdziłem.

fbparis
źródło
3

Oto rozwiązanie CSS , które działa pięknie. Zawartość jest dodawana (i absolutnie pozycjonowana względem kontenera) po elemencie zawierającym ( przez: po pseudoklasie ).

Pobiera tekst z atrybutu placeholder, który zdefiniowałem w miejscu, w którym użyłem dyrektywy ( attr (placeholder) ). Kolejnym kluczowym czynnikiem są zdarzenia wskaźnikowe: brak - pozwala to na kliknięcie tekstu zastępczego w celu przejścia do zaznaczenia. W przeciwnym razie nie spadnie, jeśli użytkownik kliknie tekst.

Sam dodaję klasę .empty do mojej dyrektywy select, ale zwykle uważam, że angular dodaje / usuwa .ng-empty dla mnie (zakładam, że to dlatego, że wstrzykuję wersję 1.2 Angulara do mojej próbki kodu).

(Przykład pokazuje również, jak zawijać elementy HTML w AngularJS, aby tworzyć własne niestandardowe dane wejściowe)

var app = angular.module("soDemo", []);
app.controller("soDemoController", function($scope) {
  var vm = {};
  vm.names = [{
      id: 1,
      name: 'Jon'
    },
    {
      id: 2,
      name: 'Joe'
    }, {
      id: 3,
      name: 'Bob'
    }, {
      id: 4,
      name: 'Jane'
    }
  ];
  vm.nameId;
  $scope.vm = vm;
});

app.directive('soSelect', function soSelect() {
  var directive = {
    restrict: 'E',
    require: 'ngModel',
    scope: {
      'valueProperty': '@',
      'displayProperty': '@',
      'modelProperty': '=',
      'source': '=',
    },
    link: link,
    template: getTemplate
  };
  return directive;


  /////////////////////////////////
  function link(scope, element, attrs, ngModelController) {
    init();
    return;


    ///////////// IMPLEMENTATION

    function init() {
      initDataBinding();
    }


    function initDataBinding() {
      ngModelController.$render = function() {
        if (scope.model === ngModelController.$viewValue) return;
        scope.model = ngModelController.$viewValue;
      }

      scope.$watch('model', function(newValue) {
        if (newValue === undefined) {
          element.addClass('empty');
          return;
        }
        element.removeClass('empty');
        ngModelController.$setViewValue(newValue);
      });
    }
  }


  function getTemplate(element, attrs) {
    var attributes = [
      'ng-model="model"',
      'ng-required="true"'
    ];

    if (angular.isDefined(attrs.placeholder)) {
      attributes.push('placeholder="{{placeholder}}"');
    }

    var ngOptions = '';

    if (angular.isDefined(attrs.valueProperty)) {
      ngOptions += 'item.' + attrs.valueProperty + ' as ';
    }

    ngOptions += 'item.' + attrs.displayProperty + ' for item in source';
    ngOptions += '"';
    attributes.push('ng-options="' + ngOptions + '"');

    var html = '<select ' + attributes.join(' ') + '></select>';

    return html;
  }
});
so-select {
  position: relative;
}

so-select select {
  font-family: 'Helvetica';
  display: inline-block;
  height: 24px;
  width: 200px;
  padding: 0 1px;
  font-size: 12px;
  color: #222;
  border: 1px solid #c7c7c7;
  border-radius: 4px;
}

so-select.empty:before {
  font-family: 'Helvetica';
  font-size: 12px;
  content: attr(placeholder);
  position: absolute;
  pointer-events: none;
  left: 6px;
  top: 3px;
  z-index: 0;
  color: #888;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="soDemo" ng-controller="soDemoController">
  <so-select value-property="id" display-property="name" source="vm.names" ng-model="vm.nameId" placeholder="(select name)"></so-select>
</div>

ulotka
źródło
3

Nie mogłem sprawić, aby którykolwiek z nich działał obecnie, ponieważ dla mnie jest to (1) nie wymagane i (2) potrzebuję opcji powrotu do domyślnego wyboru. Tak więc, jeśli używasz jQuery:

var $selects = $('select');
$selects.change(function () {
  var option = $('option:default', this);
  if(option && option.is(':selected')) {
    $(this).css('color', '#999');
  }
  else {
    $(this).css('color', '#555');
  }
});

$selects.each(function() {
  $(this).change();
});
option {
    color: #555;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select name="in-op">
    <option default selected>Select Option</option>
    <option>Option 1</option>
    <option>Option 2</option>
    <option>Option 3</option>
</select>

Eric G.
źródło
Dzięki, to było dla mnie najlepsze, jak powiedziałeś ... wymagany element jest wymagany.
Mousa Alfhaily
3

Nie jestem zadowolony z rozwiązań opartych tylko na HTML / CSS, więc zdecydowałem się utworzyć niestandardowy selectza pomocą JavaScript.

Jest to coś, co napisałem w ciągu ostatnich 30 minut, dzięki czemu można go jeszcze ulepszyć.

Wszystko, co musisz zrobić, to stworzyć prostą listę z kilkoma atrybutami danych. Kod automatycznie zamienia listę w rozwijalne menu do wyboru. Dodaje również ukryty inputdo przechowywania wybranej wartości, dzięki czemu można go użyć w formularzu.

Wejście:

<ul class="select" data-placeholder="Role" data-name="role">
  <li data-value="admin">Administrator</li>
  <li data-value="mod">Moderator</li>
  <li data-value="user">User</li>
</ul>

Wynik:

<div class="ul-select-container">
    <input type="hidden" name="role" class="hidden">
    <div class="selected placeholder">
        <span class="text">Role</span>
        <span class="icon"></span>
    </div>
    <ul class="select" data-placeholder="Role" data-name="role">
        <li class="placeholder">Role</li>
        <li data-value="admin">Administrator</li>
        <li data-value="mod">Moderator</li>
        <li data-value="user">User</li>
    </ul>
</div>

Tekst elementu, który ma być symbolem zastępczym, jest wyszarzony. Symbol zastępczy można wybrać na wypadek, gdyby użytkownik chciał cofnąć swój wybór. Również za pomocą CSS selectmożna przezwyciężyć wszystkie wady (np. Niemożność stylizacji opcji).


Aktualizacja : Ulepszyłem to (wybór za pomocą klawiszy góra / dół / enter), trochę posprzątałem wynik i zamieniłem go w obiekt. Wyjście prądowe:

<div class="li-select-container">
    <input type="text" readonly="" placeholder="Role" title="Role">
    <span class="arrow"></span>
    <ul class="select">
        <li class="placeholder">Role</li>
        <li data-value="admin">Administrator</li>
        <li data-value="mod">Moderator</li>
        <li data-value="user">User</li>
    </ul>
</div>

Inicjalizacja:

new Liselect(document.getElementsByTagName("ul")[0]);

Do dalszego badania: JSFiddle , GitHub (przemianowany).


Aktualizacja: przepisałem to ponownie. Zamiast korzystać z listy, możemy po prostu użyć opcji select. W ten sposób będzie działać nawet bez JavaScript (w przypadku, gdy jest wyłączony).

Wejście:

<select name="role" data-placeholder="Role" required title="Role">
    <option value="admin">Administrator</option>
    <option value="mod">Moderator</option>
    <option>User</option>
</select>

new Advancelect(document.getElementsByTagName("select")[0]);

Wynik:

<div class="advanced-select">
    <input type="text" readonly="" placeholder="Role" title="Role" required="" name="role">
    <span class="arrow"></span>
    <ul>
        <li class="placeholder">Role</li>
        <li data-value="admin">Administrator</li>
        <li data-value="mod">Moderator</li>
        <li>User</li>
    </ul>
</div>

JSFiddle , GitHub .

akinuri
źródło
2

Potrzebujesz sprawdzania poprawności formularza, a nowoczesne przeglądarki oferują to od zera.

Nie musisz więc uważać, aby użytkownik nie mógł wybrać pola. Ponieważ kiedy to robi, walidacja przeglądarki powie mu, że jest to zły wybór.

Przeglądarka ma wbudowaną funkcję sprawdzania poprawności checkValidity () .

Bootstrap ma również dobry przykład.

HTML

<form class="needs-validation">
  <select required>
    <option value="">Please select an option</option>
    <option value="1">Foo</option>
    <option value="2">Bar</option>
  </select>
<form>

JavaScript

form = document.getElementByClassName('needs-validation');
if(form.checkValidity() === true) {
  //form validation succeeded
} else {
  //form validation failed
}
Jurik
źródło
1

Można to zrobić bez użycia Javascriptużywając tylko HTMLtrzeba ustawić domyślne wybierz opcję disabled=""i selected=""i wybierz tag required="".przeglądarka nie pozwalają użytkownikowi wysłać formularz bez wybierając odpowiednią opcję.

<form action="" method="POST">
    <select name="in-op" required="">
        <option disabled="" selected="">Select Option</option>
        <option>Option 1</option>
        <option>Option 2</option>
        <option>Option 3</option>
    </select>
    <input type="submit" value="Submit">
</form>
Tak więc Wickramasinghe
źródło
Powoduje to, że cały element select jest wyszarzony do momentu wybrania opcji, co powoduje potencjalnie niepożądane zachowanie.
wickedchild
1

W Angular możemy dodać opcję jako symbol zastępczy, który można ukryć w menu rozwijanym opcji. Możemy nawet dodać niestandardową ikonę rozwijaną jako tło, która zastępuje ikonę rozwijaną przeglądarki .

Sztuką jest, aby umożliwić zastępczy css tylko wtedy, gdy wartość nie jest wybrany

/ ** Mój szablon komponentu * /

 <div class="dropdown">
      <select [ngClass]="{'placeholder': !myForm.value.myField}"
 class="form-control" formControlName="myField">
        <option value="" hidden >Select a Gender</option>
        <option value="Male">Male</option>
        <option value="Female">Female</option>
      </select>
    </div>

/ ** My Component.TS * /

constructor(fb: FormBuilder) {
  this.myForm = this.fb.build({
    myField: ''
  });
}

/**global.scss*/

.dropdown {
  width: 100%;
  height: 30px;
  overflow: hidden;
  background: no-repeat white;
  background-image:url('angle-arrow-down.svg');
  background-position: center right;
  select {
    background: transparent;
    padding: 3px;
    font-size: 1.2em;
    height: 30px;
    width: 100%;
    overflow: hidden;

    /*For moz*/
    -moz-appearance: none;
    /* IE10 */
    &::-ms-expand {
      display: none;
    }
    /*For chrome*/
    -webkit-appearance:none;
    &.placeholder {
      opacity: 0.7;
      color: theme-color('mutedColor');
    }
    option {
      color: black;
    }
  }
}
Mukundhan
źródło
1

Rozwiązanie dla Angular 2

Utwórz etykietę na górze zaznaczenia

<label class="hidden-label" for="IsActive"
    *ngIf="filterIsActive == undefined">Placeholder text</label>
<select class="form-control form-control-sm" type="text" name="filterIsActive"
    [(ngModel)]="filterIsActive" id="IsActive">
    <option value="true">true</option>
    <option value="false">false</option>
</select>

i zastosuj CSS, aby umieścić go na wierzchu

.hidden-label {
    position: absolute;
    margin-top: .34rem;
    margin-left: .56rem;
    font-style: italic;
    pointer-events: none;
}

pointer-events: none pozwala wyświetlić opcję wyboru po kliknięciu etykiety, która jest ukryta po wybraniu opcji.

edu
źródło
1

Oto mój wkład. Haml + CoffeeScript + SCSS

Haml

=f.collection_select :country_id, [us] + Country.all, :id, :name, {prompt: t('user.country')}, class: 'form-control'

CoffeeScript

  $('select').on 'change', ->
    if $(this).val()
      $(this).css('color', 'black')
    else
      $(this).css('color', 'gray')
  $('select').change()

SCSS

select option {
  color: black;
}

Można używać tylko CSS, zmieniając kod serwera i ustawiając style klas tylko w zależności od bieżącej wartości właściwości, ale ten sposób wydaje się łatwiejszy i czystszy.

$('select').on('change', function() {
  if ($(this).val()) {
    return $(this).css('color', 'black');
  } else {
    return $(this).css('color', 'gray');
  }
});

$('select').change();
    select option {
      color: black;
    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select class="form-control" name="user[country_id]" id="user_country_id">
  <option value="">Country</option>
                      <option value="231">United States</option>
                      <option value="1">Andorra</option>
                      <option value="2">Afghanistan</option>
                      <option value="248">Zimbabwe</option></select>

Możesz dodać więcej CSS ( select option:first-child), aby zachować symbol zastępczy szary, gdy się otworzy, ale mnie to nie obchodziło.

Chloe
źródło
1

Wypróbuj to dla odmiany:

$("select").css("color", "#757575");
$(document).on("change", "select", function(){
    if ($(this).val() != "") {
        $(this).css("color", "");
    } 
    else {
        $(this).css("color", "#757575");
    }
});
Jordan Lipana
źródło
1

Oto działający przykład, jak to osiągnąć za pomocą czystego JavaScript, który obsługuje kolor opcji po pierwszym kliknięciu:

<!DOCTYPE html>
<html>
  <head>
    <style>
      #myselect {
        color: gray;
      }
    </style>
  </head>

  <body>
    <select id="myselect">
      <option disabled selected>Choose Item
      </option>

      <option>Item 1
      </option>

      <option>Item 2
      </option>

      <option>Item 3
      </option>
    </select>

    <script>
      // Add event listener to change color in the first click
      document.getElementById("myselect").addEventListener("click", setColor)
      function setColor()
      {
        var combo = document.getElementById("myselect");
        combo.style.color = 'red';
        // Remove Event Listener after the color is changed at the first click
        combo.removeEventListener("click", setColor);
      }
    </script>
  </body>
</html>
jonathana
źródło
1

Opierając się na odpowiedzi MattW , możesz uczynić opcję wyboru symbolu zastępczego widoczną w menu rozwijanym po dokonaniu prawidłowego wyboru, warunkowo ukrywając ją tylko wtedy, gdy symbol zastępczy pozostaje wybrany (a zatem wybór jest: nieważny).

select:required:invalid {
  color: gray;
}
select:invalid > option[value=""][disabled] {
  display: none;
}
option {
  color: black;
}
<select required>
    <option value="" disabled selected>Select something...</option>
    <option value="1">One</option>
    <option value="2">Two</option>
</select>

Matthew Millar
źródło
0

Na podstawie odpowiedzi Albireo ta wersja nie używa jQuery, a specyfika CSS jest lepsza.

const triggerEvent = (el, eventName) => {
  let event = document.createEvent('HTMLEvents')
  event.initEvent(eventName, true, false)
  el.dispatchEvent(event)
}

let select = document.querySelector('.placeholder-select')
select.addEventListener('change', (e) => {
  e.target.classList[e.target.value == 0 ? 'add' : 'remove']('empty')
})
triggerEvent(select, 'change')
.placeholder-select option {
  color: #000000;
}
.placeholder-select option:first-child {
  color: #444444;
  font-style: italic;
  font-weight: bold;
}
.placeholder-select.empty {
  color: #7F7F7F;
}
<select class="placeholder-select">
  <option value="0" selected="selected">Choose...</option>
  <option value="1">Something</option>
  <option value="2">Something else</option>
  <option value="3">Another choice</option>
</select>

Pan Polywhirl
źródło