jQuery Form Styler - плагин для стилизации селектов, чекбоксов, радиокнопок, файловых и числовых полей

Плагин jQuery Form Styler

Данный плагин позволяет стилизовать с помощью CSS следующие HTML-элементы:

  • флажок <input type="checkbox">;
  • переключатель <input type="radio">;
  • поле для выбора файла <input type="file">.
  • поле для ввода чисел <input type="number">.
  • раскрывающийся список <select>;

Демонстрация работы плагина

Живые примеры можно посмотреть на отдельной странице. Стоит заметить, что при оформлении элементов форм не использовано ни одного изображения, только CSS.

Достоинства

  • Общее:

    • Простота оформления с помощью CSS.
    • При отключенном JavaScript отображаются стандартные элементы форм, т.е. их работоспособность не теряется.
    • Псевдоэлементы выводятся внутристрочно, т.е. повторяют свойство стандартных элементов.
    • Поддержка работы с динамически добавляемыми/изменяемыми элементами.
    • Поддержка атрибутов checked, selected, disabled.
    • Атрибуты class, id, data-*, title, указанные у оригинальных элементов форм, передаются в соответствующие псевдоэлементы (id передается с суффиксом, чтобы избежать дублирования).
    • Поддержка динамического добавления/изменения атрибутов class, id, data-*, title.
    • Поддержка сброса формы при нажатии на <input type="reset">.
    • Умеет «ловить» нажатие клавиши Tab и позволяет переключать элементы с клавиатуры.
    • Кроссбраузерность (все современные браузеры, а также IE8 и выше).
    • Поддержка валидации HTML5.
    • Поддержка мультиязычности.
  • Для селектов:

    • Поддерживает атрибут multiple, т.е. позволяет выбирать несколько пунктов (мультиселект).
    • Поддерживает группировку элементов списка в селекте (тег <optgroup>).
    • Позволяет задать максимальную высоту для выпадающего списка (CSS-свойством max-height, либо через опцию selectVisibleOptions).
    • Поддерживает «умное позиционирование», т.е. не уходит за видимую часть страницы при открытии списка.
    • Поддержка поиска по пунктам одиночного селекта.
    • Поддержка замещающего текста (placeholder).
    • Автоматически подстраивает ширину, если она не указана.
    • Поддерживает прокрутку колесом мыши.
к содержанию ↑

Недостатки

  • При использовании некоторых нестандартных шрифтов (например, Open Sans, подключенный с Google Fonts), неправильно определяется ширина псевдоселекта, в связи с чем текст пунктов обрезается. Это связано с тем, что шрифт применяется лишь после стилизации селекта плагином. Как вариант решения этой проблемы, можно сделать отложенный запуск скрипта:

    setTimeout(function() {
    	$('input, select').styler();
    }, 100)
    

    Еще один вариант решения — использовать специальный скрипт, который переинициализирует плагин после окончания загрузки шрифта.

  • В Mac OS при переключении селекта с клавиатуры появляется нативный выпадающий список.
к содержанию ↑

Скачать

Плагин «jQuery Form Styler»

Версия: 2.0.1 | Последнее обновление: 29.08.2017

Плагин на GitHub | Плагин в CDN jsDelivr

Подключение плагина

Для работы плагина необходимо использовать jQuery не ниже версии 1.7.0.

  1. Подключите jQuery (если он еще не подключен), плагин и стили к нему, добавив следующие строки перед тегом </head>:

    <link href="путь_к_файлу/jquery.formstyler.css" rel="stylesheet" />
    <link href="путь_к_файлу/jquery.formstyler.theme.css" rel="stylesheet" />
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script src="путь_к_файлу/jquery.formstyler.min.js"></script>
    

    Файл jquery.formstyler.css — это обязательные стили, необходимые для корректной работы плагина, а jquery.formstyler.theme.css — визуальное оформление элементов форм.

  2. Для активации плагина примените метод .styler к тегам, которые хотите стилизовать:

    (function($) {
    $(function() {
    
    	$('input, select').styler();
    
    });
    })(jQuery);
    
к содержанию ↑

Отключение плагина (метод destroy)

Если есть необходимость отвязать плагин от стилизованного элемента, то задействуйте метод destroy:

$('select').styler('destroy');

Динамическое изменение

При динамическом изменении элементов формы необходимо запустить триггер refresh, например:

$('button').click(function(e) {
	e.preventDefault();
	/* делаем чекбокс неактивным */
	$('input:checkbox').attr('disabled', true)
		/* обновляем состояние псевдочекбокса */
		.trigger('refresh');
});

При использовании сторонних плагинов, например, jQuery Validation, которые меняют атрибуты элементов формы, событие .trigger('refresh') необходимо запускать, используя setTimeout, иначе состояния псевдоэлементов не изменится. Пример с вышеуказанным плагином:

$('form').validate({
	invalidHandler: function() {

		setTimeout(function() {
			$('input, select').trigger('refresh');
		}, 1)

	}
});
к содержанию ↑

Опции плагина

Большинство опции плагина можно переопределить для конкретного тега, указав ему соответствующий data-атрибут.

ОпцияПо умолчаниюОписаниеdata-атрибут
idSuffix-stylerсуффикс к атрибуту id, передаваемому от стилизуемого элемента
filePlaceholderФайл не выбрантекст по умолчанию в поле выбора файла (когда файл не выбран)data-placeholder
fileBrowseОбзор...текст кнопки у поля для выбора файлаdata-browse
fileNumberВыбрано файлов: %sтекст после выбора нескольких файлов, вместо %s вставится числоdata-number
selectPlaceholderВыберите...замещающий текст (плейсхолдер) в одиночном селекте; отображается, если по умолчанию выбран первый пункт с отсутствующим текстом: <option></option>data-placeholder
selectSearchfalseпоказывать поисковое поле в одиночном селекте (true — да, false — нет)data-search
selectSearchLimit10минимальное количество пунктов одиночного селекта, при котором показывать поискdata-search-limit
selectSearchNotFoundСовпадений не найденотекст сообщения о том, что нет пунктов, удовлетворяющих поискуdata-search-not-found
selectSearchPlaceholderПоиск...текст по умолчанию в поисковом полеdata-search-placeholder
selectVisibleOptions0количество отображаемых пунктов списка в простом селекте без прокруткиdata-visible-options
selectSmartPositioningtrueумное позиционирование для выпадающего списка селекта:
true — работает вверх и вниз
false — работает только вниз
'-1' — позиционирование отключено
data-smart-positioning
localeruтекущая локаль
localesанглийская локализациямассив локалей с переводом соответствующих опций, подробнее смотрите здесь
к содержанию ↑

Колбеки (callbacks)

НазваниеПо умолчаниюОписание
onSelectOpenedfunction() {}запускается при раскрытии списка селекта, целевой селект можно захватить через $(this)
onSelectClosedfunction() {}запускается при закрытии списка селекта, целевой селект можно захватить через $(this)
onFormStyledfunction() {}запускается после выполнения плагина

Пример использования:

$('input, select').styler({
	fileBrowse: 'Выбрать',
	singleSelectzIndex: '999',
	onSelectOpened: function() {
		// к открытому селекту добавляется красная обводка
		$(this).css('outline', '3px solid red');
	}
});
к содержанию ↑

Локализация

Плагин поддерживает многоязычность. Для этого используются опции locale и locales.

Пример локализации (английская по умолчанию включена в плагин):

$('input, select').styler({
	locale: 'en',
	locales: {
		'en': {
			filePlaceholder: 'No file selected',
			fileBrowse: 'Browse...',
			fileNumber: 'Selected files: %s',
			selectPlaceholder: 'Select...',
			selectSearchNotFound: 'No matches found',
			selectSearchPlaceholder: 'Search...'
		}
	},
});
к содержанию ↑

CSS-селекторы, используемые для оформления

Чекбокс
.jq-checkboxчекбокс по умолчанию
.jq-checkbox__divдополнительный вложенный тег
.jq-checkbox.checkedвыбранный чекбокс
.jq-checkbox.disabledнеактивный (недоступный для выбора) чекбокс
.jq-checkbox.focusedфокус на чекбоксе, когда нажата клавиша Tab
.jq-checkbox spanдополнительный вложенный тег
Радиокнопка
.jq-radioрадиокнопка по умолчанию
.jq-radio__divдополнительный вложенный тег
.jq-radio.checkedвыбранная радиокнопка
.jq-radio.disabledнеактивная (недоступная для выбора) радиокнопка
.jq-radio.focusedфокус на радиокнопке, когда нажата клавиша Tab
.jq-radio spanдополнительный вложенный тег
Поле для выбора файла
.jq-fileродительский контейнер
.jq-file.focusedфокус на поле
.jq-file.changedфайл выбран
.jq-file.disabledнеактивное поле
.jq-file__nameполе с именем файла
.jq-file__browseкнопка выбора файла
Поле для ввода чисел
.jq-numberродительский контейнер
.jq-number.focusedфокус на поле
.jq-number.disabledнеактивное поле
.jq-number__fieldобертка для поля ввода
.jq-number__spin.minusкнопка «минус»
.jq-number__spin.plusкнопка «плюс»
Селект (простой)
.jq-selectboxродительский контейнер
.jq-selectbox.openedвыпадающий список селекта раскрыт
.jq-selectbox.dropupвыпадающий список селекта раскрыт вверх
.jq-selectbox.dropdownвыпадающий список селекта раскрыт вниз
.jq-selectbox.changedвыбрано значение, отличное от заданного по умолчанию
.jq-selectbox__selectселект в свернутом состоянии
.focused .jq-selectbox__selectфокус на селекте, когда нажата клавиша Tab
.disabled .jq-selectbox__selectнеактивный (недоступный для выбора) селект
.jq-selectbox__select-textдополнительный вложенный тег для свернутого селекта
.jq-selectbox .placeholderзамещающий текст
.jq-selectbox__triggerправая часть свернутого селекта (условный переключатель)
.jq-selectbox__trigger-arrowвложенный тег для переключателя (стрелка)
.jq-selectbox__dropdownобертка для выпадающего списка
.jq-selectbox__searchобертка для поискового поля
.jq-selectbox__search inputпоисковое поле
.jq-selectbox__not-foundсообщение об отсутствии результатов поиска
.jq-selectbox ulвыпадающий список
.jq-selectbox liпункт (опция) селекта
.jq-selectbox li.selectedвыбранный пункт селекта
.jq-selectbox li.disabledнеактивный (недоступный для выбора) пункт селекта
.jq-selectbox li.optgroupзаголовок для группы пунктов
.jq-selectbox li.optionпункт списка в группе
Селект (множественный)
.jq-select-multipleродительский контейнер
.jq-select-multiple.disabledнеактивный (недоступный для выбора) селект
.jq-select-multiple liпункт (опция) селекта
.jq-select-multiple li.selectedвыбранный пункт селекта
.jq-select-multiple li.disabledнеактивный (недоступный для выбора) пункт селекта
.jq-select-multiple li.optgroupзаголовок для группы пунктов
.jq-select-multiple li.optionпункт списка в группе
Прочие элементы (только CSS)
.stylerкласс, используемый для стилизации текстовых полей и кнопок (работает независимо от плагина)
к содержанию ↑

История изменений

Находится здесь.

Стилизация без плагина

Если вам необходимо стилизовать только радиокнопки или чекбоксы, то это можно сделать без данного плагина, используя лишь CSS. В таком случае рекомендую использовать решение из этой статьи.

Примеры различных решений

Полезные комментарии (10)
Комментарии (2 538)
  1. 1
    fatemax
    @

    Здравствуйте.
    Есть такая конструкция

    <option id="set2" value="#map_block" onClick="setCenter2()" data-chained="Almetevsk">Нефтяников, 37</option>

    Однако, после применения стайлера, данный пункт списка перестает работать.
    Как неоднократно писали в комментариях нужно onClick заменить на onChange, но эффекта никакого это не дало.
    Я что-то делаю не так? Как заставить отрабатывать стилизованные пункты выпадающего списка?

  2. 6
    Артем

    Здравствуйте. Подскажите пожалуйста, а как можно реализовать select сразу с input search, чтобы по клику на него выпадал список всех option’s. Вообщем, сделать такой select, только без стандартного блока selectbox__select и за место него input search с поиском по option’s.

    Пример https://ibb.co/kZoBen

  3. 8
    fatemax
    @

    Возможно ли видоизменить текст получаемый из option? Есть ли возможность, например, изменить цвет только части текста, или расстановка переносов строки в тегах ?

      • 10
        fatemax
        @

        Стал думать в сторону модификации уже выведенного на страницу текста посредством JS-скрипта. Не могу понять, как происходит сопоставление сформированных li-блоков и options исходного селекта. То есть подменив ul — li сформированные Вашим скриптом на ul — li — элементы включающие, например теги:

        <i></i> или </br>

        теряется связь c options ( если не связь, то, скажем так, клик по новому li не приводит к клику по options который обрабатывается onchange).
        Подскажите в какую сторону копать?

  4. 11
    Вениамин

    Как сделать drop_up наверх у простого селекта. Я просто тупой не могу разобраться. Что и где нужно дописать?

  5. 13

    К сожалению на днях, перестал работать одиночный селект на IOS, а точнее на Safari. Возможно подскажите решение?

    Проверял у себя на сайте и у вас на демо, с телефона и Chrome на ПК в режиме адаптивного дизайна под iPhone/iPad

  6. 19
    fatemax
    @

    Замечено, что не работает при использовании .trigger(‘refresh’), а без — мультиселект стилизуется.

  7. 23
    Никита

    А есть какой то способ сделать на андроиде нативный выпадающий список, так же как на ios барабан появляется, при нажатии на стилизованный select?

  8. 24
    Андрей

    Подскажите, как быть если у тебя на странице два селекта, и у каждого свои стили.
    Простая конструкция $(‘select’).styler(); тут определенно не поможет. Надо что то добавить. Что?

  9. 29
    Nik_Dev
    @

    Здравствуйте.
    Подскажите пожалуйста в чем может быть проблема.
    У меня есть скрипт, который заносит сумму в поле input при выборе option в select.
    При стилизации вашим select перестает работать.

    https://webchikof.com
    На сайте нажмите на кнопку «рассчитать стоимость сайта».
    Заранее благодарю )

  10. 32
    Никита

    Не получается для select применить disabled.
    Вообще, требуется, чтобы при первоначальной загрузке страницы второй из селектов был отключен, после выбора значения в первом и загрузки данных во второй, второй включился, но на первом же этапе проблема, disabled прописанное в селекте не отрабатывает(

  11. 34
    @

    Вот написал точно такое же на нативном JS. Обратил внимание, что браузер не желает отображать текущее состояние свойств checked, selected. То есть console.log( element.checked ) и console.log(element.selected) не выводит актуального состояния bool значения. Попутно загемороился с одиночным атрибутом, если указано не по системе Strict HTML, где надо прописывать атрибут selected=»selected». Собственно, я думал, что jQuery говно и баг в ней. Написал на чистом JS — баг тот же. Но jQuery все равно говно. У нее в циклах вечно параша с функциями при переборке.

    Dimox, ты на каком браузере работаешь с версткой?

  12. 36
    Александр
    @

    Подскажите, при включении опции multiple у select они скрываются. Как продиагностировать, что не так?

  13. 46
    Наталья
    @

    Добрый день! Я в jquery не сильна, но очень нужно реализовать вот это:
    Есть вот такая конструкция — https://jsfiddle.net/moireceptik/hp27xrdb/
    Задача: При выборе категории — выделить все подкатегории только у выбранной категории
    Сейчас я использовала ваш скрипт http://jsfiddle.net/Dimox/KgeSA/, но при выборе Категории № 1, отмечаются галочки абсолютно у всех категорий и подкатегорий. Что не правильно для моей задачи.
    Предполагаю что тут нужно использовать (this), но как и куда его вставить — это выше моего понимания.

  14. 50
    Максим
    @

    Наверное не совсем к Вам, но

    Страница https://v-gorod.com/_v/
    Браузеры — webkit для мобильных устройств

    http://prntscr.com/jx0r5z -> http://prntscr.com/jx0rdf — Не работает

    Меняем ориентацию http://prntscr.com/jx0rjw — работает

    Экспериментальным путем выяснил, что работоспособность зависит от положения относительно края браузера (устройства)

  1. 1
    Роман

    Может кому пригодится, вот решение:

    if (!$(this).html().match(new RegExp('\^' + query, 'i'))) {
  2. 2

    Для тех, у кого обрезается текст в селектах при подключении нестандартных шрифтов, есть вот такое решение с отложенным запуском скрипта:

    setTimeout(function() { 
    	$('input, select').styler(); 
    }, 100)
    

    Буду признателен, если кто-то предложит более красивое решение.

  3. 3

    Можно.

    <select class="myselect">
    .jq-selectbox.myselect { 
     width: 250px; 
    }
    
  4. 4

    В общем, проблема была с angular.

    Имеем: калькулятор на angularjs, данные приходят, но селекты не открываются.
    Решение: Добавить setTimeout примерно как в пятом пункте, чтобы angularjs успел заполнить данными наши селекты :)

  5. 5
    <select class="select1">
    <select class="select2">
    
    .jq-selectbox.select1 {
    	width: 200px;
    }
    .jq-selectbox.select2 {
    	width: 300px;
    }
    
  6. 6
    Денис

    Может кому нибудь пригодится.
    Строка 530

    if (bottomOffset > (minHeight + searchHeight + 20) &amp;&amp; !el.hasClass("top")) {

    Тем селектам которые надо открывать вверх, добавляем класс «top».

  7. 7

    Можно. Вот решение:

    if (window.webkitURL) {
    	$('input[type="file"]').attr('title', ' ');
    } else {
    	$('input[type="file"]').attr('title', '');
    }
    
  8. 8
    Фарит
    @
    		(function($) {
     $(function() {
     var _dropdown;
     var settings = {autoReinitialise: true};
     $('input, select').styler({
     selectSearch: true,
     onFormStyled: function(){
     _dropdown = $('.jq-selectbox__dropdown');
     _dropdown.find('ul').wrap('<div class="scroll-pane" />');
     },
     onSelectOpened: function(){
     var _ul = $(this).find('.jq-selectbox__dropdown ul');
     var height = _ul.height();
     var _srollPane = _dropdown.find('.scroll-pane');
     _srollPane.height(height);
     _ul.css('max-height', 'none');
     _srollPane.jScrollPane(settings);
     }
     });
     });
     })(jQuery);
    	
    .scroll-pane
    {
     width: 100%;
     overflow: auto;
    }
    

    извините за code style, стилезуйте на свой вкус.

  9. 9
    neoxaker

    Более правильным вариантом решения проблемы с подключаемыми шрифтами была бы переинициализация плагина после окончания загрузки шрифта. Отловить загрузку шрифта можно при помощи гугловского скрипта «webfontloader» https://github.com/typekit/webfontloader . При подключенном плагине код переинициализации выглядел бы так:

    (function(){
     if (typeof WebFont != 'undefined') {
     WebFontConfig = {
     custom: {
     families: ['Arimo']
     },
     active: function() {
     $('select, :checkbox, :radio').trigger('refresh');
     }
     };
     WebFont.load(WebFontConfig);
     }
    })();
    

    В данном случае подключалось семейство шрифтов Arimo.

  10. 10

    В плагине это не предусмотрено. Можно сделать следующим образом:

    <label><input type="checkbox" /> Чекбокс</label>
    $('input:checkbox').change(function() {
    	if ($(this).is(':checked')) {
    		$(this).closest('label').addClass('checked');
    	} else {
    		$(this).closest('label').removeClass('checked');
    	}
    });
    
Ваш комментарий