Как сделать заполнитель для поля "выбрать"?
Я использую заполнители для ввода текста, который работает просто отлично. Но я также хотел бы использовать заполнитель для моих селекторов. Конечно, я могу просто использовать этот код:
<select>
<option value="">Select your option</option>
<option value="hurr">Durr</option>
</select>
но "Выберите свой вариант" находится в черном, а не светло-серый. Поэтому мое решение может быть основано на CSS. jQuery тоже в порядке.
Это только делает опцию серой в выпадающем списке (так что после нажатия на стрелку):
option:first {
color: #999;
}
Edit: вопрос в том, как люди создать заполнители в окна? Но на него уже ответили, ура.
и использование этого приводит к тому, что выбранное значение всегда будет серым (даже после выбора реальной опции):
select {
color:#999;
}
23 ответа:
Как насчет ответа без CSS - no javascript/jQuery?
<select> <option value="" disabled selected>Select your option</option> <option value="hurr">Durr</option> </select>
просто наткнулся на этот вопрос, вот что работает в FireFox & Chrome (по крайней мере)
<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>
отключенная опция останавливает
<option>
выбирается с помощью мыши и клавиатуры, в то время как просто с помощью'display:none'
позволяет пользователю выбрать с помощью стрелок клавиатуры. Элемент'display:none'
стиль просто делает список выглядеть "хорошо".Примечание: с помощью пустой
value
атрибут на опции "заполнитель" позволяет проверку (требуется атрибут), чтобы обойти наличие "заполнителя", поэтому, если опция не изменена, но требуется; браузер должен предложить пользователю выбрать опцию из списка.Обновление (Июль 2015):
этот метод подтверждается работой в следующих браузерах:
- Гугл Хром - В. 43.0.2357.132
- Mozilla Firefox-V. 39. 0
- Safari-V. 8. 0. 7 (заполнитель виден в выпадающем списке, но не является выбирается)
- Microsoft Internet Explorer-V. 11 (заполнитель отображается в раскрывающемся списке, но не выбирается)
- Project Spartan-V. 15. 10130 (заполнитель виден в выпадающем списке, но не выбирается)
Обновление (Октябрь 2015):
удалены
style="display: none"
в пользу атрибута HTML5hidden
, который имеет широкую поддержку. Элементhidden
элемент имеет аналогичные черты, какdisplay: none
в Safari, т. е. (проект Spartan нуждается проверка) где тоoption
отображается в выпадающем списке, но не выбирается.Обновление (Январь 2016):
когда
select
элементrequired
это позволяет использовать:invalid
псевдо-класс CSS, который позволяет вам стилизоватьselect
элемент, когда он находится в состоянии "заполнитель".:invalid
работает здесь из-за пустого значения в местозаполнительoption
.после того, как значение было установлено на
:invalid
псевдо-класс будет удален. Вы можете по желанию также используйте:valid
если вы так хотите.большинство браузеров поддерживают этот псевдо-класс. IE10+. Это лучше всего работает с пользовательским стилем
select
элементы; в некоторых случаях т. е. (Mac в Chrome / Safari) вам нужно будет изменить внешний вид по умолчанию
для необходимого поля в современных браузерах есть решение pure-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>
что-то вроде этого возможно?
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();
пример: http://jsfiddle.net/Zmf6t/
Я просто добавил скрытый атрибут в опции, как показано ниже, он отлично работает для меня.
<select> <option hidden>Sex</option> <option>Male</option> <option>Female</option> </select>
это решение работает и в FireFox:
Без каких-либо JS.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>
у меня была такая же проблема и во время поисков наткнулся на этот вопрос, и после того, как я нашел хорошее решение для меня, я хотел бы поделиться им с вами в случае, если кто-то может извлечь из этого пользу. вот оно: 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; }
JS:
jQuery(".dropdown").change(function () { jQuery(this).removeClass("place_holder"); });
после того, как клиент делает первый выбор, нет необходимости в сером цвете, поэтому JS удаляет класс
place_holder
. Надеюсь, это кому-то поможет :)обновление: спасибо @user1096901, как a работа вокруг для браузера IE, вы можете добавить
place_holder
класс снова в случае, если первый вариант выбран снова :)
вот мой
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>
нет необходимости в каких-либо JS или CSS, только 3 атрибута:
<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>
Он вообще не показывает опцию, просто устанавливает значение опции по умолчанию.
однако, если вы просто Не нравится заполнитель, который имеет тот же цвет, что и остальные, вы можете исправить это встроенное следующим образом:
<!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>
очевидно, что вы можете разделить функции и, по крайней мере, CSS select на отдельные файлы.
Примечание: функция onload исправляет ошибку обновления.
Я вижу признаки правильных ответов, но чтобы собрать все это вместе, это было бы моим решением.
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>
здесь я изменил ответ Дэвида (принятый ответ). На его ответ он поставил отключенный и выбранный атрибут на теге опции, но когда мы также поместим скрытый тег, он будет выглядеть намного лучше. Добавляя дополнительный скрытый атрибут на теге option, предотвратит повторный выбор опции " выберите свой вариант "после выбора опции" Durr".
<select> <option value="" disabled selected hidden>Select your option</option> <option value="hurr">Durr</option> </select>
еще одна возможность в JS:
$('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'); } });
здесь CSS решение, которое прекрасно работает. Содержимое добавляется (и абсолютно позиционируется относительно контейнера) после содержащего элемента (через :после псевдо-класс). Он получает свой текст из атрибута-заполнителя, который я определил, где я использовал директиву ( attr (заполнитель)). Еще одним ключевым фактором является указатель-события: отсутствует - это позволяет нажимать на текст заполнителя, чтобы перейти к выбору. В противном случае это не будет выпадать, если пользователь нажимает на текст.
добавить .пусто класс сам в моей директиве select, но обычно я нахожу, что angular добавляет / удаляет. ng-пустой для меня (я предполагаю, что это b / c я впрыскиваю версию 1.2 Angular в моем примере кода)
(в Примере также показано, как обернуть HTML-элементы в angularJS для создания собственных пользовательских входов)
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>
вы можете сделать это без использования
Javascript
используя толькоHTML
вам нужно установить опцию выбора по умолчаниюdisabled=""
иselected=""
и выберите тегrequired="".
браузер не позволяет пользователю отправлять форму без выбора опции.<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>
Я хотел, чтобы выбор был серым, пока не выбран так для этого фрагмента HTML:
<select> <option value="" disabled selected>Select your option</option> <option value="hurr">Durr</option> </select>
я добавил эти определения CSS:
select { color: grey; } select:valid { color: black; }
Он работает так, как ожидалось в Chrome / Safari, возможно, и в других браузерах, но я не проверял.
Я не мог заставить ни один из них работать в настоящее время, потому что для меня это (1) не требуется и (2) нужна возможность вернуться к выбору по умолчанию. Итак, вот тяжелый вариант, если вы используете 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>
попробуйте это для разнообразия
$("select").css("color","#757575"); $(document).on("change","select",function(){ if ($(this).val() != "") { $(this).css("color",""); } else { $(this).css("color","#757575"); } });
вход
[type="text"]
заполнитель стиля для выбранных элементовследующее решение имитирует заполнитель, как это относится к
input[type="text"]
элемент:$( '.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>
Я не довольствуюсь только решениями HTML / CSS, поэтому я решил создать пользовательский
select
С помощью JS.это то, что я написал в последние 30 минут, таким образом, он может быть дополнительно улучшен.
все, что вам нужно сделать, это создать простой список с несколько атрибутов данных. Код автоматически превращает список в выбираемый выпадающий список. Он также добавляет скрытый
input
для удержания выбранного значения, чтобы его можно было использовать в форма.вход:
<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>
выход:
<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>
текст элемента, который должен быть заполнителем, выделен серым цветом. Заполнитель можно выбрать, если пользователь хочет отменить свой выбор. Также используя CSS, все недостатки
select
можно преодолеть (например, невозможность стилизации опций).// helper function to create elements faster/easier // https://github.com/akinuri/js-lib/blob/master/element.js var elem = function(tagName, attributes, children, isHTML) { let parent; if (typeof tagName == "string") { parent = document.createElement(tagName); } else if (tagName instanceof HTMLElement) { parent = tagName; } if (attributes) { for (let attribute in attributes) { parent.setAttribute(attribute, attributes[attribute]); } } var isHTML = isHTML || null; if (children || children == 0) { elem.append(parent, children, isHTML); } return parent; }; elem.append = function(parent, children, isHTML) { if (parent instanceof HTMLTextAreaElement || parent instanceof HTMLInputElement) { if (children instanceof Text || typeof children == "string" || typeof children == "number") { parent.value = children; } else if (children instanceof Array) { children.forEach(function(child) { elem.append(parent, child); }); } else if (typeof children == "function") { elem.append(parent, children()); } } else { if (children instanceof HTMLElement || children instanceof Text) { parent.appendChild(children); } else if (typeof children == "string" || typeof children == "number") { if (isHTML) { parent.innerHTML += children; } else { parent.appendChild(document.createTextNode(children)); } } else if (children instanceof Array) { children.forEach(function(child) { elem.append(parent, child); }); } else if (typeof children == "function") { elem.append(parent, children()); } } }; // initialize all selects on the page $("ul.select").each(function() { var parent = this.parentElement; var refElem = this.nextElementSibling; var container = elem("div", {"class": "ul-select-container"}); var hidden = elem("input", {"type": "hidden", "name": this.dataset.name, "class": "hidden"}); var selected = elem("div", {"class": "selected placeholder"}, [ elem("span", {"class": "text"}, this.dataset.placeholder), elem("span", {"class": "icon"}, "▼", true), ]); var placeholder = elem("li", {"class": "placeholder"}, this.dataset.placeholder); this.insertBefore(placeholder, this.children[0]); container.appendChild(hidden); container.appendChild(selected); container.appendChild(this); parent.insertBefore(container, refElem); }); // update necessary elements with the selected option $(".ul-select-container ul li").on("click", function() { var text = this.innerText; var value = this.dataset.value || ""; var selected = this.parentElement.previousElementSibling; var hidden = selected.previousElementSibling; hidden.value = selected.dataset.value = value; selected.children[0].innerText = text; if (this.classList.contains("placeholder")) { selected.classList.add("placeholder"); } else { selected.classList.remove("placeholder"); } selected.parentElement.classList.remove("visible"); }); // open select dropdown $(".ul-select-container .selected").on("click", function() { if (this.parentElement.classList.contains("visible")) { this.parentElement.classList.remove("visible"); } else { this.parentElement.classList.add("visible"); } }); // close select when focus is lost $(document).on("click", function(e) { var container = $(e.target).closest(".ul-select-container"); if (container.length == 0) { $(".ul-select-container.visible").removeClass("visible"); } });
.ul-select-container { width: 200px; display: table; position: relative; margin: 1em 0; } .ul-select-container.visible ul { display: block; padding: 0; list-style: none; margin: 0; } .ul-select-container ul { background-color: white; border: 1px solid hsla(0, 0%, 60%); border-top: none; -webkit-user-select: none; display: none; position: absolute; width: 100%; z-index: 999; } .ul-select-container ul li { padding: 2px 5px; } .ul-select-container ul li.placeholder { opacity: 0.5; } .ul-select-container ul li:hover { background-color: dodgerblue; color: white; } .ul-select-container ul li.placeholder:hover { background-color: rgba(0, 0, 0, .1); color: initial; } .ul-select-container .selected { background-color: white; padding: 3px 10px 4px; padding: 2px 5px; border: 1px solid hsla(0, 0%, 60%); -webkit-user-select: none; } .ul-select-container .selected { display: flex; justify-content: space-between; } .ul-select-container .selected.placeholder .text { color: rgba(0, 0, 0, .5); } .ul-select-container .selected .icon { font-size: .7em; display: flex; align-items: center; opacity: 0.8; } .ul-select-container:hover .selected { border: 1px solid hsla(0, 0%, 30%); } .ul-select-container:hover .selected .icon { opacity: 1; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <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> <ul class="select" data-placeholder="Sex" data-name="sex"> <li data-value="male">Male</li> <li data-value="female">Female</li> </ul>
обновление: я улучшил этот (выбор с помощью клавиш up/down/enter). Немного прибрался на выходе и превратил это в объект. Текущий объем производства:
<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>
инициализации:
new Liselect(document.getElementsByTagName("ul")[0]);
для дальнейшего обследования: JSFiddle,
GitHub(переименован).
обновление: снова переписан. Вместо того, чтобы использовать список, мы можем просто использовать Select. Таким образом, он будет работать даже без JS (в случае, если это нетрудоспособный.)
вход:
<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]);
выход:
<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>
Если вы используете угловой идти так
<select> <option [ngValue]="undefined" disabled selected>Select your option</option> <option [ngValue]="hurr">Durr</option> </select>
пользователь не должен видеть заполнитель в select options. Я предлагаю использовать
hidden
атрибут для опции заполнителя, и вам не нужноselected
атрибут для этой опции вы можете просто поставить его в качестве первого.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>
вот мой вклад. 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; }
можно использовать только CSS, изменяя код сервера и только устанавливая стили класса в зависимости от текущего значения свойства, но этот способ кажется проще и чище.
$('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>
вы можете добавить больше CSS (
select option:first-child
) чтобы сохранить заполнитель серым, когда он открывается, но мне было все равно что.
в отношении всех решений выше, но этот, кажется, наиболее действителен из-за спецификаций HTML:<select> <optgroup label="Your placeholder"> <option value="value">Label</option> </optgroup> </select>
обновление: Простите меня за этот неправильный ответ, это определенно не заполнитель решение для
select
элемент, но заголовок для сгруппированных параметров под открытымselect
список элемент.