jQuery Form Styler – плагин для стилизации элементов HTML-форм (input[type=checkbox], input[type=radio], input[type=file], input[type=number], select)

Плагин 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
selectSearch false показывать поисковое поле в одиночном селекте (true – да, false – нет) data-search
selectSearchLimit 10 минимальное количество пунктов одиночного селекта, при котором показывать поиск data-search-limit
selectSearchNotFound Совпадений не найдено текст сообщения о том, что нет пунктов, удовлетворяющих поиску data-search-not-found
selectSearchPlaceholder Поиск... текст по умолчанию в поисковом поле data-search-placeholder
selectVisibleOptions 0 количество отображаемых пунктов списка в простом селекте без прокрутки data-visible-options
selectSmartPositioning true умное позиционирование для выпадающего списка селекта:
true – работает вверх и вниз
false – работает только вниз
'-1' – позиционирование отключено
data-smart-positioning
locale ru текущая локаль
locales английская локализация массив локалей с переводом соответствующих опций, подробнее смотрите здесь

Колбеки (callbacks)

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

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

$('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. В таком случае рекомендую использовать решение из этой статьи.

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

Комментарии (2614)

  1. Дмитрий
    26 ноября 2018 г. в 22:58

    Добрый день.
    Стилизовал select через плагин. Возник такой вопрос:
    Когда кликаю по селекту на мобиле iOS, происходит стандартное поведение выбора опций (карусель внизу) – все ок.
    Когда кликаю по селекту на мобиле Android, появляется стилизованный список (мне нужно попап окно с прокруткой, как при не стилизованном стелекте). Подскажите, как можно исправить?

  2. Дмитрий
    28 ноября 2018 г. в 00:19

    Добавил в jquery.formstyler.js после

    if (iOS) return;

    строку

    if (Android) return;

    При клике на селект на андроиде стилизованный список пропал, но нативный список так и не появился…Может есть какое решение, подскажите.

  3. Владимир
    13 декабря 2018 г. в 18:06

    Здравствуйте!
    На странице одиночный select с атрибутом data-search=”true”. По выбору происходит перезагрузка страницы с учетом выбранного (фильтр ajax post).
    Так вот при выборе из списка элемента происходит перезагрузка страницы с указанной опцией из select. В консоле post выглядит так: filter_date=&filter_status=0&filter_meneger=0&filter_ist=0&filter_tel=%2B7%20(XXX)%20177%207181.
    Но если воспользоваться поиском по select и выбрать элемент, то post выглядит уже так: filter_date=&filter_status=0&filter_meneger=0&filter_ist=0&filter_tel=0
    filter_date=&filter_status=0&filter_meneger=0&filter_ist=0&filter_tel=%2B7%20(XXX)%20374%203472
    .
    Т.е. при поиске он берет предыдущий выбранный пункт, соответсвенно фильтр не срабатывает на выбранный пункт. Это у меня такой глюк или так и должно быть?

  4. Andrew
    18 декабря 2018 г. в 23:50

    Всем привет! Вопрос такого плана.
    Использую jquery datepicker ui.
    Хочу закастомить селекты выбора месяца и года.
    У datepicker’а есть опция beforeShow тип которой функция с параметрами ( Element, Object ).
    В api datepicker’а написано примерно следующее:

    Функция, которая принимает поле ввода и текущий экземпляр datepicker, и возвращает объект параметров, с помощью которого можно обновить datepicker. Он вызывается непосредственно перед отображением даты.

    https://api.jqueryui.com/datepicker/#option-beforeShow

    Когда инициализирую datepicker, опции beforeShow передаю свою функцию dpSelectStyler
    Это выглядит следующим образом

    $(".default.datepicker-big").datepicker({
        showOn: "button",
        buttonImageOnly: false,
        dateFormat: 'mm.dd.yy',
        бла-бла-бла еще опции,
        beforeShow: dpSelectStyler
    });
    
    function dpSelectStyler(input, inst){
        console.log('dpSelectStyler');
        inst.dpDiv.find('select').styler();
    }
    

    Пробовал return inst.dpDiv.find(‘select’).styler();
    Пробовал эту функцию не выносить в отдельную и записать прямо после beforeShow:
    Результатов пока не добился. Не хватает JS скилла.
    Может кто сталкивался? В какую сторону смотреть?
    Спасибо!

    1. Andrew
      19 декабря 2018 г. в 01:11 / ответ на коммент Andrew

      На данный момент пришел к такому варианту, однако при смене месяца, из за новых инициализациий видно, как плагин разваливается, и собирается повторно.

      $(document).ready(function() {
          datePickerInit();
          var uiDatepickerDiv = $('#ui-datepicker-div');
      
          $(".ui-datepicker-trigger").on('click', function() {
              $(this).offset().top <= uiDatepickerDiv.offset().top ? uiDatepickerDiv.addClass('to-bottom').removeClass('to-top') : uiDatepickerDiv.addClass('to-up').removeClass('to-bottom');
              datePickerSelectStyler();
          });
      
          function datePickerSelectStyler() {
              $('#ui-datepicker-div select').styler();
          }
      
          function datePickerInit() {
              $(".default.datepicker-big").datepicker({
                  showOn: "button",
                  buttonText: "<svg class='svg-ico calendar-big'><use xmlns:xlink='http://www.w3.org/1999/xlink' xlink:href='/frontfiles/img/svg/sprite.svg#ico-calendar'></use></svg>",
                  changeMonth: true,
                  changeYear: true,
                  firstDay: 1,
                  buttonImageOnly: false,
                  dateFormat: 'mm.dd.yy',
                  onSelect: function() {
                      console.log('onSelect')
                      datePickerSelectStyler();
                  },
                  onChangeMonthYear: function() {
                      console.log('onChangeMonthYear')
                      datePickerSelectStyler();
                      setTimeout(function() {
                          datePickerSelectStyler();
                      }, 1)
                  }
              });
          }
      });
      
  5. Prooksius
    8 января 2019 г. в 19:57

    Есть проблема с отображением контролов, если они изначально скрыты (к примеру в скрытой форме попапа, которая показывается после нажатия какой-то кнопки).
    Так вот, если вызывать активацию плагина для скрытых элементов, то скрипт неправильно считает их высоту. Используется jquery функция outerHeight(), которая при скрытых элементах возвращает 0. И в итоге имеем косяки со стилями выпадающих списков и мультиселект вообще нулевой высоты. Два часа искал причину..

    1. Олег
      8 января 2019 г. в 20:42 / ответ на коммент Prooksius

      используйте .trigger(‘refresh’); после показа попапа.

  6. Евгений
    13 февраля 2019 г. в 19:26

    Здравствуйте. У меня такой вопрос:
    Есть несколько селектов и их нужно стилизовать по разному, возможно ли это реализовать?

    1. Jktu
      13 февраля 2019 г. в 19:50 / ответ на коммент Евгений

      Да, добавьте с select уникальный класс, или к родителю, от него и пляшите

  7. Виталий
    27 февраля 2019 г. в 00:28

    Здраствуйте. У меня не получаеться получить значение селекта при обработке на стороне сервера. Задал для селекта поле name но не получаеться. Можете подсказать?

  8. Сергей
    23 марта 2019 г. в 04:28

    Как динамически получить значение input tyep=number ?

  9. Олег
    22 мая 2019 г. в 19:11

    Здрасте. Вопрос на засыпку.)) – Как включить английский? Я имею введу для –

    <input type="file"/>

    А то в описании там…ссылочка не работает.!? Смотрел коменты, но про это вопросов не нашёл.

    1. Олег
      23 мая 2019 г. в 23:25 / ответ на коммент Олег

      А-а.!? Разобрался.
      п.с. Сам с собой переписку веду.))

  10. Илья
    19 июля 2019 г. в 09:02

    Если нужно стилизовать только один input number то дня него есть отдельный плагин https://number-plugin.ru

  11. Игорь
    15 октября 2019 г. в 12:58

    Привет! Подскажите, почему скрипт не передаёт неактивные элементы в select?
    То есть у стандартного select есть option с атрибутом disabled, но после стилизации данный option доступен к выбору. Как подправить это дело?

  12. Beliyadm
    8 ноября 2019 г. в 19:26

    Приветствую. Отличный плагин.
    Один вопрос – как передать в инпут селект дополнительный блок\спан? Мне нужно по клику на селект показывать список цветов такого формата

    <option value="value1"><span class="colorval">colorval</span>Item1</option>

    Где в спане будет квадратик цвета.
    Сейчас на фронте это обрезается

    <div class="jq-selectbox__select-text">colorvalItem1</div>
  13. Константин
    26 января 2020 г. в 01:26

    Делаю один проект, решил воспользоваться вашим скриптом. Не могу разобраться как открыть селект при клике на label для данного селекта. Можете подсказать? Задача достаточно популярная, но нигде не смог найти ответа.

    Заранее благодарен!

  14. Kron
    14 апреля 2020 г. в 17:33

    Всем привет!

    У кого не работают селекты (у меня не раскрывались) на Android при использовании в fancybox, попробуйте отключить у fancybox при инициализации touch. Мне помогло.

    $('selector').fancybox({
    	touch: false
    });
  15. Нарт
    10 октября 2020 г. в 16:59

    Подскажите пожалуйста. Как сделать зависимые списки на этом плагине ?

  16. Андрей
    26 октября 2020 г. в 23:25

    Как в “select” выбрать определенный “option”, который зависит от get запроса?
    Например есть сортировка select-> по умолчанию, по убыванию, по возрастанию.
    Всегда стоит “по умолчанию”, если выбрать “по убыванию” происходит перезагрузка станицы и должно брать из get параметр, что нужно указать “selected” “по убыванию”, а не возвращать по умолчанию.
    Вот такое туповатое объяснение получилось.

  17. Василий
    14 декабря 2020 г. в 22:49

    Как подключать ваш плагин в проект на gulp и sass

  18. eLig
    14 апреля 2021 г. в 23:58

    Здравствуйте!
    В select не работает поиск, если вводить в формате, например телефон: +7 (812) и т.д.
    В консоли ошибка Uncaught SyntaxError: Invalid regular expression: /.*?+7 (812).*?/: Nothing to repeat

  19. Андрей
    3 ноября 2021 г. в 09:50

    Отличный плагин, но почему-то у меня не работает в iOS, точнее не открывается выпадающий список.
    Как поправить?
    https://codepen.io/eandycat/pen/gOxoapG

  20. Alex
    30 ноября 2021 г. в 15:05

    Убрать строку if (iOS) return;
    В ios, скорее всего, уже давно всё ок! ))

Ваш комментарий

Жирный текст

Ссылка

Цитата

Внутристрочный код

CSS-код

HTML-код

JavaScript-код

PHP-код