jQuery UI Slider — ползунок выбора диапазона

Автор: Александр Головко Дата публикации: 16.06.2011

При верстке какого-нибудь магазина часто приходится сталкиваться с задачей реализовать удобный для пользователя выбор ценового диапазона. Выглядеть это может, например, так:

выбор диапазона цен с помощью ползунков

Идея, надеюсь, понятна. Перетягиваем ползунки, значения полей input синхронно меняются. Попробуем это реализовать.

Задача

Отыскать кроссбраузерное решение на js для интерфейса выбора диапазона. Требования:

  • инпуты и ползунки связанны (изменение значения одних тут же отражается на других);
  • гибкость стилизации (все должно выглядеть по дизайну).

Решение

Будем использовать плагин jQuery UI Slider. Сам по себе он просто создает ползунок, но подружить его с инпутами не составит труда.

Традиционный демо-пример.

Проверено в:

  • IE 6-8
  • Firefox 4
  • Opera 11
  • Safari
  • Chrome

Итак, вначале давай представим, что инпутов нет, и посмотрим, как работает сам плагин.

Что качать?

Быстрый старт

Подключаем библиотеки:

<script type="text/javascript" src="js/jquery-1.6.1.min.js" ></script>
<script type="text/javascript" src="js/jquery.ui-slider.js"></script>

В CSS добавляем правила для стилизации ползунка. Подробнее об этом ниже.

В HTML создаем элемент, который плагин заменит на ползунок и присваиваем ему id:

<div id="slider"></div>

Инициализируем ползунок скриптом:

<script type="text/javascript">
jQuery("#slider").slider({
	min: 0,
	max: 1000,
	values: [0,1000],
	range: true
});
</script>

А теперь подробнее

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

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

Настройки

При инициализации плагина можно задать его параметры:

Название параметра Описание Тип данных Значение по-умолчанию
disabled Отключает (true) или включает (false) слайдер. boolean false
animate Определяет, будет ли ползунок передвигаться в точку плавно, когда пользоваль щелкает на точку на полосе. Также может принимать значение string представляющая одну из трех скоростей на выбор ("slow", "normal", или "fast") или число миллисекунд, определяющее продолжительность анимации (например, 1000). boolean, string, int false
max Максимальное значение слайдера. Number 100
min Минимальное значение слайдера. Number 0
orientation Определяет ориентацию шкалы: слева направо или снизу вверх. Возможные значения: "horizontal", "vertical". String horizontal
range Если выставлено в true, на слайдере будет двуа ползунка и диапазон между ними, который можно стилизовать. Два других значения это "min" и "max". Значение "min" создает диапазон от минимума шкалы до ползунка. Значение "max" создает диапазон от ползунка до максимума шкалы. boolean, string false
step Определяет шаг слайдера. Полный диапазон шкалы (max − min) должен равномерно делится на шаг. Number 1
value Определяет значение слайдера, если есть только однин ползунок. Если имеется более одного ползунка, определяет значение первого ползунка. Number 0
values Эта опция может использоваться для указания нескольких ползунков. Если range имеет значение true, значений "values" должно быть 2. Array null

События

События — это функции, которые будут выполняться в определенные моменты жизни ползунка. Задавать их можно при инициализации. Например:

jQuery("#slider").slider({
	stop: function(event, ui) {
		alert('Ползунок переехал на новую позицию!');
    }
});

Перечень событий:

create Событие возникает в момент создания ползунка
start Событие возникает в момент, когда пользователь начинает двигать ползунок.
slide Событие происходит при каждом перемещения мыши во время прокрутки. Используйте ui.value (слайдеры с одним ползунком), чтобы получить текущее значение ползунка, $(..).slider("value", index), чтобы получить значение ползунка для слайдеров с несколькими ползунками.
change Событие происходит при остановке прокрутки или если величина изменяется программным способом (посредством метода value). Принимает аргументы event и ui. Используйте event.orginalEvent, чтобы определить, изменилось ли значение с помощью мыши, клавиатуры или программно. Используйте ui.value (слайдеры с одним ползунком), чтобы получить текущее значение ползунка, $(this).slider("values", index), чтобы получить значение ползунка для слайдеров с несколькими ползунками.
stop Событие возникает в момент, когда пользователь закончил двигать ползунок.

Методы

Вызов этих функций позволяет повлиять на работу ползунка, налету изменив его параметры. Делается это с помощью конструкции .slider(), например вот так:

jQuery("#slider").slider("values",0, 100);

Перечень методов:

destroy Удаляет функционал ползунка, возвращая элемент к первоначальному состоянию.
disable Отключает слайдер.
enable Включает слайдер.
option Получает или устанавливает любую опцию слайдера. Если значение не указано, будет выступать в качестве получателя. Синтаксис: .slider("option", optionName , [value])
option Устанавливает сразу несколько опций слайдера путем предоставления опций объекта. Синтаксис: .slider( "option", options )
widget Возвращает элемент .ui-slider.
value Устанавливает или возвращает значение слайдера. Для слайдеров с одним ползунком.
values Устанавливает или возвращает значение слайдера. Для слайдеров с несколькими ползунками или с диапазоном.

Настройка стилей

Вообще-то стилизация элементов jQuery UI (одним из которых является данный слайдер) происходит путем выбора понравившейся темы и загрузки с официального сайта готового CSS. Лично меня такой подход не устраивает совершенно. Поэтому я выбрал из ихнего (очень избыточного, если использовать только слайдер) CSS только нужный код, который здесь и привожу с комментариями.

/* Ширина слайдера */
#slider {
	width: 200px;
}
/* Контейнер слайдера */
.ui-slider {
	position: relative;
}
/* Ползунок */
.ui-slider .ui-slider-handle {
	position: absolute;
	z-index: 2;
	width: 13px;   /* Задаем нужную ширину */
	height: 13px;  /* и высоту */
	background: url(../img/slider.png) no-repeat; /* картинка изображающая ползунок. Или можно залить цветом, задать бордюр и скругления */
	cursor: pointer
}
.ui-slider .ui-slider-range {
	position: absolute;
	z-index: 1;
	font-size: .7em;
	display: block;
	border: 0;
	overflow: hidden;
}
/* горизонтальный слайдер (сама полоса по которой бегает ползунок) */
.ui-slider-horizontal {
	 height: 3px; /* задаем высоту согласно дизайна */
}
/* позиционируем ползунки */
.ui-slider-horizontal .ui-slider-handle { 
	top: -5px;
	margin-left: -6px;
}
.ui-slider-horizontal .ui-slider-range {
	top: 0;
	height: 100%;
}
.ui-slider-horizontal .ui-slider-range-min { 
	left: 0;
}
.ui-slider-horizontal .ui-slider-range-max {
	right: 0;
}
/* оформление полосы по которой ходит ползунок */
.ui-widget-content { 
	border: 1px solid #D4D4D4;
	background: #fff;
}
/* оформление активного участка (между двумя ползунками) */
.ui-widget-header { 
	border: 1px solid #D4D4D4;
	background: #f00;
}
/* скругление для полосы слайдера */
.ui-corner-all {
	-moz-border-radius: 4px;
	-webkit-border-radius: 4px;
	border-radius: 4px;
}

Некотоые из этих правил можно объединить, так как плагин щедро награждает элементы множеством классов. Например, мой изначальный

<div id="slider">

превращается в

<div class="ui-slider ui-slider-horizontal ui-widget ui-widget-content ui-corner-all" id="slider">

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

Добавляем связанные инпуты

Теперь самое интересное. Добавим два инпута, в которых будем отображать значения, выбранные на слайдере.

<input type="text" id="minCost" value="0"/>
<input type="text" id="maxCost" value="1000"/>
<div id="slider"></div>

При инициализации слайдера используем события stop и slide — первое обеспечит корректное значение в момент остановки ползунка, а второе придаст интерактивности (значение инпута будет меняться в реальном времени, синхронно движению ползунка).

Код обоих событий одинаков — берем текущее значение с помошью метода .slider("values",X) и помещаем в нужный инпут:

jQuery("#slider").slider({
	min: 0,
	max: 1000,
	values: [0,1000],
	range: true,
	stop: function(event, ui) {
		jQuery("input#minCost").val(jQuery("#slider").slider("values",0));
		jQuery("input#maxCost").val(jQuery("#slider").slider("values",1));
    },
    slide: function(event, ui){
		jQuery("input#minCost").val(jQuery("#slider").slider("values",0));
		jQuery("input#maxCost").val(jQuery("#slider").slider("values",1));
    }
});

Осталось организовать обратную связь. Учим ползунок перемещаться, если пользователь вводит значение в инпут. Тут можно использовать событие keypress, чтобы ползунок реагировал на каждую нажатую клавишу или событие change, если хотим, чтобы изменение вступало в силу после завершения ввода и ухода из поля. Дело вкуса.

Заодно я вставил проверку выхода верхнего значения за пределы диапазона (у меня это 1000) и проверку, чтобы нижний ползунок не получил значение больше верхнего:

jQuery("input#minCost").change(function(){
	var value1=jQuery("input#minCost").val();
	var value2=jQuery("input#maxCost").val();

    if(parseInt(value1) > parseInt(value2)){
		value1 = value2;
		jQuery("input#minCost").val(value1);
	}
	jQuery("#slider").slider("values",0,value1);	
});

	
jQuery("input#maxCost").change(function(){
	var value1=jQuery("input#minCost").val();
	var value2=jQuery("input#maxCost").val();
	
	if (value2 > 1000) { value2 = 1000; jQuery("input#maxCost").val(1000)}

	if(parseInt(value1) > parseInt(value2)){
		value2 = value1;
		jQuery("input#maxCost").val(value2);
	}
	jQuery("#slider").slider("values",1,value2);
});

Последняя деталь — нужно обеспечить чтобы пользователь не смог поломать плагин, введя в инпуты буквы или некорректрые числовые значения. Этот момент подробно не рассматриваю, так как он не касается непосредственно темы статьи. Любопытных отсылаю к демо-примеру, где это, конечно, реализовано.

В одной из следующих публикаций мы усложним задачу. Я покажу, как на основе этого решения можно сделать выбор значения с неравномерным шагом и разным масштабом. То есть когда требуется, чтобы, например, на первую половину слайдера приходился диапазон значений от 0 до 100, а на вторую от 100 до 1000.

Подобные варианты достаточно часто встречаются в интернет-магазинах — это удобно, ведь на маленьких суммах делализация более важна, а удобство пользователя, как известно, прежде всего.

Материал:

Показать комментарии