Drupal → Выбор диапазона значений в раскрытом фильтре Views с помощью виджета jQuery UI Slider

13.02.2012

Поступил вопрос — Чем можно сделать выбор диапазонов в Exposed Filter, как на Яндекс-маркете.

Отвечаю — сделать можно с помощью jQuery UI Slider Widget (в ядре) и небольшого количества кода.

Exposed Filter 'как на Яндекс.Маркете'

1. Добавляем один или несколько раскрытых фильтров (в примере это фильтр по Nid) и в качестве оператора выбираем Is between:

Настройки фильтра

Получаем:

Представление с раскрытым фильтров по Nid

2. Реализуем хук hook_form_views_exposed_form_alter() в котором подключаем jQuery UI Slider, скрипт инициализации слайдера, стиль и экстра разметку:

/**
 * Implements hook_form_views_exposed_form_alter()
 */
function mymodule_form_views_exposed_form_alter(&$form, $form_state) {
  if ($form_state['view']->name == 'myview' && $form_state['view']->current_display == 'page') {
    // Находим минимальное и максимальное значение
    $query = db_select('node');
    $query->addExpression('MIN(nid)', 'min');
    $query->addExpression('MAX(nid)', 'max');
    $limits = $query->execute()->fetch();
    
    // Оборачиваем виджет враппером с информацией о минимуме и максимуме
    $form['nid']['#prefix'] = '<div class="slider-widget-wrapper" data-min="' . $limits->min . '" data-max="' . $limits->max . '">';
    $form['nid']['#suffix'] = '</div>';
    
    // Подключаем js и css файлы
    $form['#attached']['library'][] = array('system', 'ui.slider');
    $form['#attached']['js'][] = drupal_get_path('module', 'mymodule') . '/slider-init.js';
    $form['#attached']['css'][] = drupal_get_path('module', 'mymodule') . '/slider-style.css';
  }
}

3. В slider-init.js инициализируем виджет:

(function($) {
  Drupal.behaviors.mymodule = {
    attach: function (context, settings) {
      $('.slider-widget-wrapper', context).once('slider-widget', function () {
        var $sliderWrapper = $(this);
        var $minInput = $sliderWrapper.find('input:first');
        var $maxInput = $sliderWrapper.find('input:last');
        
        // Прописываем минимум и максимум в placeholder
        $minInput.attr('placeholder', $sliderWrapper.data('min'));
        $maxInput.attr('placeholder', $sliderWrapper.data('max'));
        
        // Создаём слайдер
        var $slider = $('<div class="slider-widget" />').appendTo($sliderWrapper).slider({
          range: true,
          min: $sliderWrapper.data('min'),
          max: $sliderWrapper.data('max'),
          step: 1,
          values: [
            $minInput.val() === '' ? $sliderWrapper.data('min') : $minInput.val(),
            $maxInput.val() === '' ? $sliderWrapper.data('max') : $maxInput.val()
          ],
          slide: function (event, ui) {
            $minInput.val(ui.values[0]);
            $maxInput.val(ui.values[1]);
          }
        });

        // Описываем реакцию слайдера на ввод данных в поля min/max
        $minInput.keyup(function () {
          $slider.slider('values', 0, this.value);
        });
        $maxInput.keyup(function () {
          $slider.slider('values', 1, this.value);
        });
      });
    }
  };
})(jQuery);

Получаем:

Предварительный результат

4. В slider-style.css наводим красоту:

.slider-widget-wrapper {
  width: 200px;
}
.slider-widget-wrapper .form-item:nth-child(1) {
  float: left;
}
.slider-widget-wrapper .form-item:nth-child(2) {
  float: right;
}
.slider-widget-wrapper .form-item:nth-child(2) label {
  display: none;
}
.slider-widget-wrapper .form-item:nth-child(2) .form-text {
  text-align: right;
}
.slider-widget-wrapper .form-text {
  width: 90px;
  margin: 0 0 5px 0;
  padding: 0;
  border: 0;
  background: transparent;
}
.slider-widget-wrapper .slider-widget {
  clear: both;
}

Получаем:

Исходники примера (экспорт вьюхи в файле views-export.txt).

Добавлено 19.01.2013

Поддержка jQuery UI Slider Widget появилась в модуле Better Exposed Filters (динамически указать минимум и максимум можно в хуке hook_better_exposed_filters_settings_alter).

Написанное актуально для
Drupal 7, Views 3
Похожие записи

Комментарии

а вот вопрос, про шаг у ползунков открыт) не подскажите, возможно ли задавать?

что вам мешает ознакомиться с документацией?

думал я, что это исключительно ваше творение=)

спасибо за сыль, и сорри за беспокойство)

Гость
14.07.2014, 10:08

выкладываю результат с фильтром по категории(мало ли кому нить понадобится):

$term = taxonomy_term_load(arg(2));
$term_id = $term->tid;

arg(2) = $term->tid. Это одно и тоже, не зачем лишний раз грузить термин

Добрый день. Подобное решение для BEF не найдено?

xandeadx, я не уточнил, я про динамические значения показателей

AndreDavid
05.12.2014, 16:50

Отличный слайдер получился!
А можно как-то с датами такое сделать. Есть поле формата date, так вот бы слайдером даты менять, что бы выводились события попадающие в заданный диапазон времени.
Спасибо ))

Гость
16.07.2015, 01:25

у меня постоянно в поиск(placeholder) подставляет минимальное значение. Как от этого избавиться?

Кость
26.05.2016, 18:21

А почему бы просто не сделать обыкновенный модуль и не вложить его на D.org (или хотя бы просто тут) ?
Ей богу не понимаю.. столько телодвижений, я сейчас например как человек далёкий от программирования с трудом ковыряюсь в вашем мануале целый день.

а как выбрать диапазон, если у поля два значения (длинна в фунтах и в метрах). Создал я такое поле при помощи Measured Value Field (MVF), вношу 2 значения, каким образом можно в раскрытых фильтрах отметить чекбоксом сначала единицу измерения (например, фунты), а потом слайдером уже вести выборку по логике "между значениями"? Либо нужно создавать два поля с метрами и фунтами, ставить везде префиксы и делать два термина таксономии и связывать как-то?

Гость
12.06.2017, 20:38

Ребята подскажите пожалуйста, на 8ке в BEF cлайдер не работает - просто во вьюхе нет выбора слайдера. Он пока не готов, или я где то затупил?

Добавить комментарий