Come faccio a creare un segnaposto per una casella "seleziona"?


1542

Sto usando i segnaposto per gli input di testo che sta funzionando bene. Ma vorrei usare un segnaposto anche per le mie caselle di selezione. Ovviamente posso semplicemente usare questo codice:

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

Ma "Seleziona la tua opzione" è in nero anziché in grigio chiaro. Quindi la mia soluzione potrebbe essere basata su CSS. Anche jQuery va bene.

Ciò rende grigia l'opzione nel menu a discesa (quindi dopo aver fatto clic sulla freccia):

option:first {
    color: #999;
}

La domanda è: in che modo le persone creano segnaposto nelle caselle selezionate? Ma ha già ricevuto risposta, evviva.

E l'utilizzo di questo comporta che il valore selezionato sia sempre grigio (anche dopo aver selezionato un'opzione reale):

select {
    color: #999;
}

1
Nel caso in cui qualcuno legga questo, ho pubblicato una soluzione più comune per i browser moderni con la convalida integrata del browser. Benvenuti nell'anno 2020;)
Jurik

Risposte:


2974

Un non CSS - nessuna risposta JavaScript / jQuery:

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


134
Firefox (10) non mostra un'opzione disabilitata come selezione predefinita (segnaposto). Mostra quello successivo per impostazione predefinita, in questo caso "Durr".
Jarnoan,

53
Di solito aggiungo sia disabilitato che selezionato. Sembra funzionare anche in FF.
nilskp

11
<select> <option value="" disabled selected>Select your option</option> </select>
Kolypto,

183
Il motivo per cui questa non è la risposta corretta è perché (credo) chi chiede che la selezione sia grigia fino a quando non viene selezionato un altro valore. Questa risposta rende grigia l'opzione nel menu a discesa; ma non l'elemento select.
Bill

22
seleziona {opzione [disabilitato] {display: nessuno; }}
Dimael Vertigo l'

822

Mi sono appena imbattuto in questa domanda, ed ecco cosa funziona in Firefox e Chrome (almeno):

<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>

L' opzione Disabilitato interrompe la <option>selezione sia con il mouse che con la tastiera, mentre il solo utilizzo 'display:none'consente all'utente di selezionare ancora tramite le frecce della tastiera. Lo 'display:none'stile rende la casella di riepilogo semplicemente "piacevole".

Nota: l'utilizzo di un valueattributo vuoto sull'opzione "segnaposto" consente alla convalida (attributo obbligatorio) di aggirare il "segnaposto", quindi se l'opzione non viene modificata, ma è richiesta, il browser dovrebbe richiedere all'utente di scegliere un'opzione dall'elenco.

Aggiornamento (luglio 2015):

Questo metodo è confermato funzionando nei seguenti browser:

  • Google Chrome - v.43.0.2357.132
  • Mozilla Firefox - v.39.0
  • Safari - v.8.0.7 (il segnaposto è visibile nel menu a discesa, ma non è selezionabile)
  • Microsoft Internet Explorer - v.11 (segnaposto è visibile nel menu a discesa ma non è selezionabile)
  • Project Spartan - v.15.10130 (il segnaposto è visibile nel menu a discesa, ma non è selezionabile)

Aggiornamento (ottobre 2015):

Ho rimosso l' style="display: none"attributo a favore dell'attributo HTML5 hiddenche ha un ampio supporto. L' hiddenelemento ha tratti simili a quelli display: nonedi Safari, Internet Explorer (Project Spartan deve essere verificato) in cui optionè visibile nel menu a discesa, ma non è selezionabile.

Aggiornamento (gennaio 2016):

Quando l' selectelemento è required, consente l'uso della :invalidpseudo-classe CSS che consente di modellare l' selectelemento quando si trova nel suo stato "segnaposto". :invalidfunziona qui a causa del valore vuoto nel segnaposto option.

Una volta impostato un valore, la :invalidpseudo-classe verrà eliminata. :validSe lo desideri, puoi anche utilizzare facoltativamente .

La maggior parte dei browser supporta questa pseudo-classe. Internet Explorer 10 e versioni successive. Funziona meglio con selectelementi personalizzati ; in alcuni casi ad es. (Mac in Chrome / Safari) dovrai cambiare l'aspetto predefinito della selectscatola in modo che vengano visualizzati determinati stili, ad es . background-colore color. Puoi trovare alcuni esempi e altro sulla compatibilità su developer.mozilla.org .

Aspetto elemento nativo Mac in Chrome:

Seleziona la casella Mac nativo in Chrome

Utilizzando l'elemento del bordo alterato Mac in Chrome:

Modificato selezionare la casella Mac in Chrome


5
@jaacob Nei browser che ho testato, lo stile "display: none" nasconde la "Per favore scegli" dall'elenco che lo rende semplicemente più bello.
William Isted,

38
È importante notare che un'opzione disabilitata non può essere ri-selezionata: se la selezione è obbligatoria, va bene, ma non se la selezione è facoltativa.
Robert Mark Bram,

2
Explorer11 ignora lo display:nonestile.
T30,

1
Complimenti a @MattW per aver lavorato :invalidmolto prima di me.
William Isted,

3
È inoltre possibile aggiungere una regola per "ripristinare" colorle opzioni nei browser di supporto come in questo violino . Ciò contribuirebbe a rafforzare il fatto che il disoccupato optionè un segnaposto. (Modifica: vedo che MattW lo ha già trattato nella sua risposta)
Shaggy,

251

Per un campo obbligatorio, esiste una soluzione CSS pura nei browser moderni:

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>


7
Incredibile: era la risposta in fondo (senza ancora voti) che era la più semplice e in realtà funziona perfettamente. Grazie! Spero che questa risposta salga in cima.
Dan Nissenbaum,

2
@DanNissenbaum Ero in ritardo al gioco, inoltre ha bisogno requireddi funzionare, quindi non serve a niente se vuoi che il campo sia opzionale.
Matt,

1
A parte questo, il :requiredselettore non è supportato in IE8 e versioni successive. Il :invalidselettore non è supportato in IE9 e versioni successive. quirksmode.org/css/selectors
Matt Wagner,

4
Nessuna soluzione per una selezione non necessaria?
user3494047

1
@utente3494047 non con questo approccio: la requiredcondizione è ciò che induce il browser ad applicare la :invalidpseudo-classe quando viene selezionato il segnaposto. [value=""]non funzionerà come sostituto perché ciò che viene aggiornato dall'interazione dell'utente è la proprietà value ma che la sintassi CSS si riferisce ad un attributo (inesistente) .
Matt

105

Qualcosa come questo:

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();

Esempio di lavoro: http://jsfiddle.net/Zmf6t/


8
questo è esattamente quello che ho fatto di recente. ma ho aggiunto un gestore keyup in modo che la modifica si verifichi anche quando un'opzione è selezionata tramite tastiera (usando le frecce o le scorciatoie da lettera) jsfiddle.net/Zmf6t/131
Radu

questo mi ha messo sulla strada giusta ... tuttavia ho fatto il valore = "" (niente tra le virgolette) in modo che quando il pulsante di invio è stato cliccato, non è ancora riuscito a convalidare la prima opzione e un popup del browser sembrerebbe informarti per selezionare un'opzione ... grazie @Albireo
Craig Wayne il

Perché hai chiamato esplicitamente la funzione di modifica.
sempre il

@Foreever perché ho impostato la classe CSS nel gestore di eventi change della selezione, quindi se non si genera manualmente l'evento quando viene creato il controllo lo stile non viene applicato (verrà applicato solo quando l'utente modifica manualmente il valore).
Albireo,

Questo non funziona su JQeury 3.4.1
geobudex

45

Ho appena aggiunto un attributo nascosto in un optionsimile di seguito. Funziona bene per me.

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


2
Solo per la cronaca, questo non funziona per me (Chrome su Win10).
Chris Rae,

Ma non puoi disinserirlo. Finisci per sceglierne uno ma non riesci a resettarlo se cambi idea.
Thielicious

Si! Ma all'interno del modulo l'utente deve selezionare una di queste opzioni. Se non è un campo obbligatorio, rimuovere l'attributo nascosto.
Ajithkumar S

35

La soluzione seguente funziona anche in Firefox, senza 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>


26

Ho avuto lo stesso problema e durante la ricerca mi sono imbattuto in questa domanda, e dopo aver trovato una buona soluzione per me, vorrei condividerla con voi nel caso in cui qualcuno potesse trarne beneficio.

Ecco qui:

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");
});

Dopo che il cliente ha effettuato la prima selezione, non è necessario il colore grigio, quindi il codice JavaScript rimuove la classe place_holder .

Grazie a @ user1096901, come soluzione alternativa per il browser Internet Explorer, è possibile aggiungere place_holdernuovamente la classe nel caso in cui la prima opzione venga nuovamente selezionata :)


2
In alcuni browser può ancora selezionare il display: nessuna opzione, perché non è nascosta.
Srneczek,

Il problema è di aggiungere nuovamente la classe "place_holder" nel caso in cui sia selezionata la prima opzione :)
rramiii

23

Non è necessario alcun JavaScript o CSS, solo tre attributi:

<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>

Non mostra affatto l'opzione; imposta semplicemente il valore dell'opzione come predefinito.

Tuttavia, se non ti piace un segnaposto dello stesso colore del resto , puoi sistemarlo in linea in questo modo:

<!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>

Ovviamente, puoi separare le funzioni e almeno il CSS della selezione in file separati.

Nota: la funzione onload corregge un bug di aggiornamento.


Questo non funziona se l'opzione nascosta è l'unica
Eridanis,

ma perché dovresti avere un menu a discesa con una sola opzione?
Jacob Schneider,

Ho un pop-up a schede e il menu a discesa da tab3 prende input da tab2, che mostra. La tua risposta è buona e questo è un caso angolare, ma mi sarei aspettato che il valore predefinito fosse visualizzato come prima opzione, invece otterrai un menu a discesa vuoto. Vedi qui: jsfiddle.net/n66L7sza
Eridanis

Questo è un buon punto, nel qual caso potresti scansionare la lunghezza del menu a discesa, se è zero, quindi rimuovere l'attributo nascosto
Jacob Schneider

Questo non sembra funzionare correttamente su Google Chrome 65.0.3325.181 su MacOS, non mostra la voce nascosta e seleziona quella sottostante.
Jamie H,

19

L'utente non dovrebbe vedere il segnaposto nelle opzioni selezionate. Suggerisco di utilizzare l' hiddenattributo per l'opzione segnaposto e non è necessario l' selectedattributo per questa opzione. Puoi solo metterlo come il primo.

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>


2
o select:invalidè anche valido.
elquimista,

2
Consiglio questo in quanto non presenta il testo segnaposto nell'elenco, almeno in Chrome.
Joe

Nota che lo stile non funziona senzarequired
akmalhakimi1991

18

Qui ho modificato la risposta di David (risposta accettata). Sulla sua risposta, ha messo l'attributo disabilitato e selezionato sul optiontag, ma quando mettiamo anche il tag nascosto sembrerà molto meglio.

Aggiungendo un attributo extra nascosto al optiontag, si eviterà che l'opzione "Seleziona la tua opzione" venga nuovamente selezionata dopo aver selezionato l'opzione "Durr".

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


Grazie per l'aggiornamento, ma la risposta non spiega ancora perché sembra diversa. Ad esempio, questa risposta impedisce di selezionare nuovamente l'opzione "Seleziona la tua opzione" dopo aver selezionato l' opzione "Durr" . Quale attributo causa questo comportamento?
bgran,

16

Ecco il mio:

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>


Potresti semplicemente aggiungere <option value="" selected disabled>Please select</option>come prima opzione.
sabato

Non rende il segnaposto grigio chiaro.
Chloe,

12

Vedo segni di risposte corrette, ma per mettere tutto insieme, questa sarebbe la mia soluzione:

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>


8
Durrè in grigio dopo averlo selezionato. Questo impone che la casella selezionata chiusa sia sempre grigia.
Chloe,

9

Se stai usando Angular, vai così:

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


È possibile aggiungere l' hiddenattributo in modo tale che l'opzione non sia visualizzata all'apertura di select. Ma grazie comunque per quella risposta, ha funzionato per me.
dcg

5

Questa HTML + CSSsoluzione ha funzionato per me:

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>

In bocca al lupo...


Non sembra funzionare in JQuery 3.4.1
geobudex

5

Un'altra possibilità in 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


4

Adoro la soluzione accettata e funziona benissimo senza JavaScript.

Voglio solo aggiungere come ho adottato questa risposta per un componente React a selezione controllata , perché mi ci sono voluti alcuni tentativi per capirlo. Sarebbe davvero semplice da incorporare react-selected essere fatto con esso, ma a meno che tu non abbia bisogno della straordinaria funzionalità fornita da questo repository, cosa che non faccio per il progetto in questione, non è necessario aggiungere altri kilobyte al mio pacchetto. Nota, react-selectmaniglie segnaposto seleziona attraverso un complesso di vari inputsed htmlelementi.

In React, per un componente controllato , non è possibile aggiungere l' selectedattributo alle opzioni. React gestisce lo stato della selezione tramite un valueattributo suselect se stesso, insieme a un gestore di modifica, in cui il valore deve corrispondere a uno degli attributi di valore all'interno delle opzioni stesse.

Come ad esempio

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

Dal momento che sarebbe improprio e in effetti genererebbe un errore per aggiungere l' selectedattributo a una delle opzioni, e allora?

La risposta è semplice quando ci pensi. Poiché vogliamo che il nostro primo optionsia selectedcosì come disablede hidden, dobbiamo fare tre cose:

  1. Aggiungi l' attributo hiddene disabledal primo definitooption .
  2. Imposta il valore del primo option come stringa vuota.
  3. Inizializza il valore di selectessere anche una stringa vuota.
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>

Ora puoi modellare la selezione come indicato sopra (o tramite un classNamese preferisci).

select:invalid { color: gray; }

3

[type="text"]Segnaposto stile di input per Seleziona elementi

La seguente soluzione simula un segnaposto in relazione a un input[type="text"]elemento:

$('.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>


3

Volevo che SELECT fosse grigio fino a quando non è stato selezionato, quindi per questo pezzo di HTML:

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

Ho aggiunto queste definizioni CSS:

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

Funziona come previsto in Chrome / Safari e forse anche in altri browser, ma non ho controllato.


3

Ecco una soluzione CSS che funziona magnificamente. Il contenuto viene aggiunto (e posizionato in modo assoluto rispetto al contenitore) dopo l'elemento contenitore ( tramite: dopo la pseudo-classe ).

Ottiene il suo testo dall'attributo segnaposto che ho definito dove ho usato la direttiva ( attr (segnaposto) ). Un altro fattore chiave sono gli eventi puntatore: nessuno : ciò consente ai clic sul testo segnaposto di passare alla selezione. In caso contrario, non verrà visualizzato se l'utente fa clic sul testo.

Aggiungo io stesso la classe .empty nella mia direttiva select, ma normalmente trovo che angolare aggiunge / rimuove .ng-vuoto per me (suppongo sia perché sto iniettando la versione 1.2 di Angular nel mio esempio di codice).

(L'esempio mostra anche come avvolgere gli elementi HTML in AngularJS per creare input personalizzati)

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>


3

Al momento non sono riuscito a far funzionare nessuno di questi, perché per me non è necessario (1) e (2) l'opzione per tornare alla selezione predefinita. Quindi, ecco un'opzione pesante se stai usando 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>


Grazie, questo è stato il migliore per me, come hai detto ... è richiesto l'elemento select.
Mousa Alfhaily,

3

Non sono contento di soluzioni solo HTML / CSS, quindi ho deciso di creare un personalizzato selectutilizzando JavaScript.

Questo è qualcosa che ho scritto negli ultimi 30 minuti, quindi può essere ulteriormente migliorato.

Tutto quello che devi fare è creare un semplice elenco con pochi attributi di dati. Il codice trasforma automaticamente l'elenco in un menu a discesa selezionabile. Aggiunge anche un nascostoinput per contenere il valore selezionato, quindi può essere utilizzato in un modulo.

Ingresso:

<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>

Produzione:

<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>

Il testo dell'articolo che dovrebbe essere un segnaposto è disattivato. Il segnaposto è selezionabile, nel caso in cui l'utente desideri ripristinare la propria scelta. Usando anche i CSS, tutti gli svantaggi di selectpossono essere superati (ad es. Incapacità dello stile delle opzioni).


Aggiornamento : ho migliorato questo aspetto (selezione usando i tasti su / giù / invio), riordinando un po 'l'output e trasformandolo in un oggetto. Uscita corrente:

<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>

Inizializzazione:

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

Per un ulteriore esame: JSFiddle , GitHub (rinominato).


Aggiornamento: lo ho riscritto di nuovo. Invece di usare un elenco, possiamo semplicemente usare una selezione. In questo modo funzionerà anche senza JavaScript (nel caso sia disabilitato).

Ingresso:

<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]);

Produzione:

<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 .


2

È necessaria la convalida dei moduli e i browser moderni offrono questo da zero.

Quindi non è necessario assicurarsi che l'utente non possa selezionare il campo. Perché quando lo sta facendo, la convalida del browser gli dirà che questa è una selezione sbagliata.

La funzione di convalida integrata del browser checkValidity () .

Bootstrap ha anche un bell'esempio.

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
}

1

È possibile farlo senza usare Javascriptutilizzando solo HTML, è necessario selezionare l'opzione set predefinito di disabled=""e selected=""e tag select required="".browser non permette all'utente di inviare il modulo senza selezionare un'opzione.

<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>

Questo fa sì che l'intero elemento selezionato venga disattivato fino a quando non viene scelta un'opzione, causando così un comportamento potenzialmente indesiderato.
wickedchild,

1

In Angular possiamo aggiungere un'opzione come segnaposto che può essere nascosta nel menu a discesa delle opzioni. Possiamo anche aggiungere un'icona a discesa personalizzata come sfondo che sostituisce l' icona a discesa del browser .

Il trucco è abilitare il segnaposto css solo quando il valore non è selezionato

/ ** Modello dei miei componenti * /

 <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;
    }
  }
}

1

Soluzione per Angular 2

Crea un'etichetta sopra la selezione

<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>

e applica CSS per posizionarlo in cima

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

pointer-events: none consente di visualizzare la selezione quando si fa clic sull'etichetta, che viene nascosta quando si seleziona un'opzione.


1

Ecco il mio contributo. 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;
}

È possibile utilizzare solo CSS modificando il codice del server e impostando solo gli stili di classe in base al valore corrente della proprietà, ma in questo modo sembra più semplice e pulito.

$('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>

Puoi aggiungere più CSS ( select option:first-child) per mantenere il segnaposto grigio quando si apre, ma non me ne importava.


1

Prova questo per un cambiamento:

$("select").css("color", "#757575");
$(document).on("change", "select", function(){
    if ($(this).val() != "") {
        $(this).css("color", "");
    } 
    else {
        $(this).css("color", "#757575");
    }
});

1

Ecco un esempio funzionante su come raggiungere questo obiettivo con JavaScript puro che gestisce il colore delle opzioni dopo il primo clic:

<!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>

1

Sulla base della risposta di MattW , è possibile rendere visibile l'opzione segnaposto nel menu a discesa dopo aver effettuato una selezione valida, nascondendola in modo condizionale solo mentre il segnaposto rimane selezionato (e quindi la selezione è: non valida).

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>


0

Sulla base della risposta di Albireo , questa versione non utilizza jQuery e la specificità CSS è migliore.

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>

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.