jQuery-плагин для стилизации select’ов
Внимание! Дальнейшее развитие и поддержка плагина остановлены в связи с тем, что теперь он является частью другого плагина.
* * *
Одна из самых неприятных (и я бы даже сказал ужасных) вещей в веб-разработке – это верстка html-форм. К сожалению, не существует единого стандарта отображения элементов форм, независимо от браузера и операционной системы, так же, как и нет возможности произвольно оформить некоторые из этих элементов, используя каскадные таблицы стилей.
Не поддаются полной стилизации следующие элементы html-форм:
- раскрывающийся список
<select>
; - флажок
<input type="checkbox">
; - переключатель
<input type="radio">
. - поле для отправки файла
<input type="file">
.
Как уже понятно из заголовка поста, здесь речь пойдет только про селекты.
Существует немало готовых решений в виде jQuery-плагинов для стилизации раскрывающихся списков. Но я (ввиду того, что ни один из плагинов меня не устроил по тем или иным причинам) решил пойти путем изобретения своего колеса и написал собственный плагин, которым и делюсь в данной статье.
Сразу хочу заметить, что данный плагин не подходит для всех возможных случаев применения селектов (читайте недостатки).
Демонстрация работы плагина
На отдельной странице вы можете посмотреть пример стилизации селектов с помощью моего плагина. Их оформление я сделал без использования изображений.
Достоинства
- При отключенном JavaScript отображаются стандартные селекты.
- Небольшой размер скрипта, примерно 4 килобайта.
- Работает в IE6+ и всех современных десктопных браузерах.
- Выводится внутристрочно.
- Легко поддается оформлению через CSS.
- Позволяет задать максимальную высоту для выпадающего списка (CSS-свойством
max-height
). - Автоматически подстраивает ширину, если она не указана.
- Поддерживает прокрутку колесом мыши.
- Имеет “умное позиционирование”, т.е. не уходит за видимую часть страницы при открытии списка.
- Умеет “ловить” нажатие клавиши Tab и переключаться стрелками на клавиатуре.
- Поддерживает атрибут “disabled”.
- Работает и с динамически добавляемыми/изменяемыми селектами.
Недостатки
- Не поддерживает атрибут
multiple
, т.е. не позволяет выбирать несколько пунктов (мультиселект). - Не поддерживает группировку элементов списка (тег
<optgroup>
). - Не поддерживает переключение стрелками на клавиатуре, когда список раскрыт кликом мыши.
Скачать
Плагин недоступен, т.к. он уже не актуален.
jQuery-плагин “SelectBox Styler”
Версия: 1.0.1 | Загрузок: 11104 | Размер: 7 Кб | Последнее обновление: 07.10.2012
Обновления
- 22.09.2012
- Переделал скрипт в плагин (в том числе сделал минимизированный вариант), а также добавил поддержку динамического добавления/изменения селектов.
- 07.10.2012
- Исправлено поведение скрипта при использовании метода
onchange
у тега<select>
.
Подключение плагина
-
Если на сайте еще не подключен jQuery, то добавьте следующую строку перед тегом
</head>
:<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
-
Сразу после jQuery подключите файл со скриптом:
<script src="ПУТЬ_К_ФАЙЛУ/jquery.selectbox.min.js"></script>
-
Далее задействуйте плагин:
<script> (function($) { $(function() { $('select').selectbox(); }) })(jQuery) </script>
Этот код поместите перед тегом
</head>
после вышеуказанных файлов. -
При динамическом изменении селектов необходимо запустить триггер
refresh
, например:(function($) { $(function() { $('button').click(function() { $('select').find('option:nth-child(5)').attr('selected', true); $('select').trigger('refresh'); }) }) })(jQuery)
HTML-код после выполнения плагина
Его структура выглядит следующим образом:
<span class="selectbox" style="display: inline-block; position: relative">
<div class="select" style="float: left; position: relative; z-index: 10000">
<div class="text">-- Выберите --</div>
<b class="trigger"><i class="arrow"></i></b>
</div>
<div class="dropdown" style="position: absolute; z-index: 9999; overflow-y: auto; overflow-x: hidden; list-style: none; left: 0; display: none">
<ul>
<li>-- Выберите --</li>
<li>Пункт 1</li>
<li>Пункт 2</li>
<li>Пункт 3</li>
</ul>
</div>
</span>
<select style="position: absolute; top: -9999px">
<option>-- Выберите --</option>
<option>Пункт 1</option>
<option>Пункт 2</option>
<option>Пункт 3</option>
</select>
CSS-классы, используемые для оформления селекта
Чтобы оформить селекты с помощью CSS, используйте следующие классы:
.selectbox |
родительский контейнер для всего селекта |
.selectbox .select |
селект в свернутом состоянии |
.selectbox.focused .select |
фокус на селекте, когда нажата клавиша Tab |
.selectbox .select .text |
вложенный тег для свернутого селекта на случай вставки фонового изображения по технике “раздвижных дверей” |
.selectbox .trigger |
правая часть свернутого селекта (условный переключатель) |
.selectbox .trigger .arrow |
вложенный тег для переключателя (стрелка) |
.selectbox .dropdown |
обертка для выпадающего списка |
.selectbox .dropdown ul |
выпадающий список |
.selectbox li |
пункт (опция) селекта |
.selectbox li.selected |
выбранный пункт селекта |
.selectbox li.disabled |
отключенный (недоступный для выбора) пункт селекта |
Заключение
Создание подобного скрипта – довольно кропотливое занятие, поскольку приходится учитывать множество различных моментов. Очень надеюсь, что никаких серьезных багов не вылезет. Но, если что, сообщайте в комментариях.
В ближайших постах планирую поделиться аналогичными скриптами для <input type="checkbox">
и <input type="radio">
.
Комментарии (105)
Никто не говорит про multiple?
Множественный выбор немного другое свойство.
Я про про боксовый селект.
Скорее всего такой скрипт не решит такой задачи.
Не понимаю, что за “боксовый селект”.
Спасибо, удобная штука. Не громоздкая и названия классов нормальные.
Классная статья. Но только пока не могу определиться, где применять этот скрипт массово..
Спасибо за данное решение, очень помогло, как раз искала что-нибудь легкое без всяких наворотов.
как быть если имеются связанные поля типа Страна-Регион-город, стиль только применяется к стране, как быть?
Пока скрипт это не умеет, в будущем планирую сделать.
Спасибо ждемс
Здравствуйте! Почитал комментарии и немного не понял как сделать разные селекты? Не могли бы Вы описать попобробнее? А лучше с примерами кода и какие изменения куда вносить?)
Например, так:
Хммм.. Логично! Спасибо большое. И чё я сам не догадался?))
http://msdn.microsoft.com/en-us/library/windows/desktop/aa511484.aspx
Вот красочный пример того что такое листбокс – список не выпадающий а развернутый.
А multiple это свойство позволяющее выбирать сразу несколько пунктов в списке.
В общем я так понимаю что плаг не поддерживает listbox.
Может кто-то знает решение для listbox?
Все замечательно, одна проблема не отрабатывает событие onchange привязанное к элементу. Как бы это реализовать?
Объясните поподробнее, что хотите сделать.
Смотрите есть список
и есть скрипт
При выборе города должен скрываться/показываться один из divов, но этого не происходит если подключен ваш плагин, если убрать $(“.town”).selectbox(); то все отрабатывает как надо, но выглядит не красиво ))
Только что проверил – все работает. В вашем коде сразу 2 ошибки. Правильно вот так:
Огромное спасибо и за оперативность и за подсказку. На самом деле все работает, пробовал разные варианты и получилась “каша” в итоге поэтому и не работало.
Пожалуйста ;)
Селект просто прелесть, но есть и проблема. Отправляя ajax запрос, параметры формы плагином jquery.js получить не удается. То есть, значения методом: var login=$(“#login”).val()
Может подскажете как их совместить?
Приведите конкретный пример скрипта. Пока непонятно, что пытаетесь сделать.
Перестает работать, подключая в
Удалив, все запросы выполняются и ответ с сервера идет.
По идее должно бы работать. На выходных попробую у себя это воспроизвести.
Проверил – у меня все работает. Значит вы где-то сделали ошибку.
Вот мои тестовые файлы – https://dl.dropbox.com/u/7312900/ajax.zip
Спасибо. Нашел проблему. Подводные камни были не в Вашем замечательном селекте, а в совместимости библиотек jQuery. Теперь все отлично работает.
Спасибо так же, за оперативность.
Ну вот и отлично. Пожалуйста.
Привет! У меня возникла следующая ситуация:
При таком подходе получается, что старый селект остаётся, а новый добавляется “не проинициализированным” надеюсь правильно выразился)
В итоге дом после 1-го изменения #departCities выглядит так:
Помогите, как обойти эту ситуацию,а то я не силён в JS?
PS Извините что громоздко
Мне сложно понять, что тут происходит.
Согласен, не совсем понятно расписано. Попробую проще:
1. Есть 2 селекта один создаеётся ещё в пхп, второго на странице на момент загрузки не существует (на его месте просто пустой span с таким же id).
После того как вся страница загрузилась, запускается функция: LoadCountries($(“#departCities”).val()); , которая получает аяксом весь select и заменяет пустой спан на этот селект.
После этого запускаю $(‘select’).selectbox();
Первый селект оформляется нормально, а второй почему-то нет…
По логике все правильно сделано. Не знаю, почему не срабатывает.
Самое интересное, что до этого работало, но я подгружал не весь select а только его внутренние options После этого делал, например, $(‘#countries’).trigger(‘refresh’); и всё срабатывало.
Может быть вас это натолкнёт на какую-то мысль?!
Замечательный скрипт но есть недоделки. Кое что подправил кое что не могу, потому как мало знаком с jquery.
Надо исправить:
когда выбираешь пункт option с checked – ом(уже выбранный) происходит событие onChenge. По моему это неправильно. В моем случае запускается реагирующая функция. Вот от этого я хотел бы избавится!
Можете показать живой пример, чтобы я убедился, что это действительно нужно исправить?
При таком раскладе, выбрав автомобили запускается функция validateForm, а не должна потому что value не изменилось!!!
Понял. Сегодня исправлю этот недочет.
Исправил. Скачайте новую версию плагина. Спасибо, что сообщили об этой проблеме!
Вот так лучше!
Да, согласен.
Недостатоток огараничение ширины у выпадающего списка, то есть если select 100px то и выпадающий список тоже 100px, и значение option будет записываться больше одной строке!
Привет.
не работает. Он все равно активен.
Подскажи в чем дело. спасибо.
у вас проблема со скриптом. Если значение value у option не совпадает с текстом в нём, то что глюк в скрипте?
я сделал так.
При генерации списка ddlist добавил значение option в id li
А при клике:
Не понял, что вы хотели этим сказать.
Привет.
не работает. Селект все равно активен.
Подскажи в чем дело. спасибо.
Сюрприз, однако.
disabled
я реализовал только для тегаoption
, а проselect
и думать забыл, что у него тоже может этот параметр использоваться. В скором времени добавлю поддержку.Спасибо. Ждем.
Дальнейшее развитие и поддержка плагина остановлены в связи с тем, что теперь он является частью другого плагина.