DEMETR Создание сайтов в Казани

Опубликовано

Темизация Exposed Filters в Drupal

Темизация Exposed Filters в DrupalViews является очень мощным модулем, расширяющий базовые возможности Drupal. Любой список нод можно вывести в любом виде, если есть небольшие познания в php.

У меня появилась задача темизировать вывод exposed filters таким образом, чтобы сначала показывались несколько полей, затем ссылка «расширенный поиск» — при нажатии показывать остальные поля для фильтрации.

Логика действий понятна:

  • сначала выводим первые поля
  • ссылка «расширенный поиск».
  • При нажатии на ссылку показываем дополнительные фильтры через JQuery

Итак, у нас есть представление, еxposed filters вынесены в блок, начинаем работу.

Представление имеет название automarket. Шаблон для вывода — views-view-table—automarket—page.tpl

По-умолчанию фильтры отобразятся следующим образом:

Темизация Exposed Filters в Drupal

Колонка становится очень длинной, и большинству пользователей могут не понадобиться дополнительные настройки фильтрации, к тому же два поля Цена от и Цена до можно уместить в одну строку.

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

Теперь создаем файл php по следующей схеме:

views-exposed-form—automarket—page.tpl.php

Жирным я выделил имя нужного представления. Открываем этот файл и пишем следующее:

<label for="&lt;?php print $widgets['filter-field_myfield']-&gt;id; ?&gt;">
<!--?php print $widgets['filter-field_myfield']--->label; ?&gt;
</label>
<!--?php print $widgets['filter-field_myfield']--->widget; ?&gt;

$widgets[‘filter-field_myfield’]->id — id нашего фильтра
$widgets[‘filter-field_myfield’]->label — заголовок
$widgets[‘filter-field_myfield’]->widget — и сам фильтр

Название полей можно узнать в редактировании представления. Главное не забыть ставить «filter-» перед каждым из них.

Теперь можно выводить фильтры в любом месте, последовательности, обернуть в нужные блоки.

Темизация Exposed Filters в Drupal

Дополнительные фильтры я обернул в блок:

<!--В самом конце нашего файла не забываем вставить кнопку для фильтрации-->
<!--?php print $button; ?-->

В нужном месте вставляем ссылку для открытия/скрытия доп.фильтров:

<a id="openaddfilter" href="#">Расширенный поиск</a>

Создаем js-файл, который подключаем к нашей теме и пишем в нем:

$(document).ready(
function(){
	$('a#openaddfilter').click(function(){
		if($('div#addoptions').css('display') == 'none'){
			$('div#addoptions').show();
		} else{
			$('div#addoptions').hide();
		}
		return false;
	});
});

Скрипт можно дополнить, чтобы он сохранял, выбранное пользователем, состояние фильтра. Для этого необходимо подключить плагин jquery.cookie, подробнее в этой статье.

Дополнение (25.07.2013)

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

	<?php print_r($widgets);?>

Выводится список. Например у меня поле с select выводится

<?php print $widgets['filter-price']->widget; ?>

Идем далее к js. Не всем понятно, как оно работает. Для корректной работы скрипта не важна версия Drupal. Скрипт получает команду: при клике по ссылке с id «pushme» проверить показан ли блок с id «showme»; если не показан — показать, показан — скрыть. Все. Тут есть небольшая заминка. Нужно подгрузить более свежую версию JQuery и чтобы не было конфликта версий, использовать noconflict.

Подгружаем jquery

<script async src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

И теперь верхний кусок js изменится на:

var $jq = jQuery.noConflict();
 
$jq(document).ready(function(){
    $jq('a#openaddfilter').click(function(){
        if($('div#addoptions').css('display') == 'none'){
            $jq('div#addoptions').show();
        } else{
            $jq('div#addoptions').hide();
        }
    });
});

Дополнение (31.07.2013)
Благодаря Максиму нашлось решение, как запустить этот js без noconflict. Статья на хабре.

<script type="text/javascript">
(function ($) {
  $(function () {
   $('a#openaddfilter').click(function(){
    if ($('div#addoptions').css('display') == 'none'){
      $('div#addoptions').show();
    } else{
      $('div#addoptions').hide();
    }
   });
 
  });
}) (jQuery);
</script>

Темизация Exposed Filters в Drupal: 35 комментариев

  • CB9TOIIIA — 18.02.2012 в 11:42 #

    Позновательно 🙂

    Можешь написать еще статью, как
    [img]http://img-fotki.yandex.ru/get/25/77677229.1e/0_5fde2_9cec25b7_orig.png[/img] на JS прокрутку блоков со стрелками сделать, пример:
    http://img-fotki.yandex.ru/get/4407/77677229.1e/0_5fde3_77a63b95_orig.png

    _edinstvo-news.ru

    [Ответить]

    Demetr - Февраль 19th, 2012 в 21:00

    Это не сложно. Плагин jquery carousel подключаешь и вперед. На joomdesign он как раз и стоит.

    [Ответить]

  • Dr. MOON — 08.06.2012 в 00:26 #

    Очень познавательно и полезно.
    А вы случайно не подскажете как первый скрытый (display: none;) с помощью модуля Views Dependent Filters фильтр отобразить в форме не скрытым, а с опцией select disabled=disabled, т.е. из скрытого сделать неактивным до момента когда сработает зависимость?
    Просто необходимо чтобы поле под зависимый фильтр не скрывалось постоянно, а отображалось как неактивное.

    [Ответить]

    Demetr - Июнь 8th, 2012 в 10:39

    Здравствуйте. Очень просто, думаю. Делаете кнопку (ссылку) с классом уникальным, вешаете на него событие onclick (как в моем примере выше), дальше с помощью JQuery:

    $(‘#x’).attr(‘disabled’, true);

    где x — id нужного селекта.

    А модуль Views Dependent Filters даже не смотрел.

    [Ответить]

  • nurik — 11.02.2013 в 19:11 #

    не работает

    <label for="id; ?>»>
    label; ?>

    widget; ?>

    проект на drupal 7

    [Ответить]

    Demetr - Февраль 11th, 2013 в 19:23

    Для 7-го пока не пробовал.

    [Ответить]

  • nurik — 11.02.2013 в 19:38 #

    а не подскажете как программно вывести виджет для 7

    [Ответить]

    Demetr - Февраль 11th, 2013 в 20:04

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

    [Ответить]

    nurik - Февраль 11th, 2013 в 20:07

    спасибо за отзыв если найду решение обязательно отпишусь

    [Ответить]

    Demetr - Февраль 11th, 2013 в 20:18

    Буду очень рад.

  • nurik — 11.02.2013 в 21:02 #

    после долгих опытов устоновил разницу надо дописать всего лишь » _value»

    drupal 6
    filter-field_myfield

    drupal 7
    filter-field_myfield_value

    [Ответить]

  • Алексей — 09.04.2013 в 13:54 #

    Здравствуйте.А как вы темизировали ваш пример «цена от и цена до». Там ведь один виджет
    widget; ?>

    [Ответить]

    Demetr - Апрель 9th, 2013 в 13:58

    У типа содержимого есть поле цена. В настройках фильтра я вывел это поле два раза. В одном указал значение >= (это «цена от»). В другом <= (цена до). А фактически это одно поле.

    [Ответить]

    nurik - Апрель 9th, 2013 в 14:13

    Такая конструкция не совсем правильно работает вы тестировали ее?
    не выводится нужный диапазон решение было просто оператором выбрать «между»
    только перед этим при создание cck поля надо выбрать не текстовое поля а поле «с числовым значением» а для «года» можно так же выбрать «с числовым значением» или установить модуль что то вроде «data» этот тип поля так же поддерживает оператор «между»
    далее в label(описание) при раскрытие фильтра дописываем цена от до
    а сами «от» и «до» оборачиваем в в обертку дописываем class=»»
    и по средствам css придаем нужный нам вид
    теперь такая конструкция визуально не чем не отличается от данной в этой НО показывает весь диапазон цен лет

    [Ответить]

    Demetr - Апрель 9th, 2013 в 14:20

    Тестировал. Поле цена — integer. Все работало. Сайт этот правда так и не запустился, но точно помню, что делал именно так.

    Алексей - Апрель 9th, 2013 в 14:32

    Вот оператор «между» и не могу темизировать… При одном фильтре выводятся две формы ввода и операции с файлом —-tpl.php не проходят. Нашел в инете выход сделать два фильтра и темизировать их… буду пробовать.
    Это актуально для D7. Данная статья автора актуальна и для D7, views 3 кстати, все получится.

  • Artem — 11.04.2013 в 16:24 #

    Стать хорошая, но есть главный косяк этого примера, который заключается в отсутствии зависимых фильтров Views в (Drupal 6), не выскакивает поле по модели как на Avito,выбрал марку и листай сотню объявлений ищи нужную модель..

    [Ответить]

    Demetr - Апрель 11th, 2013 в 16:28

    Не понял в чем проблема: в отсутствии зависимых фильтров или в описанном примере?
    Для D6 таких фильтров не надо было, а для 7-ой версии есть модули. Например вот здесь http://amag16.ru/autoservice использовал.

    [Ответить]

  • Artem — 11.04.2013 в 16:46 #

    У меня проблема в том, что у меня D6ка и как раз такой случай, и мне зависимые фильтры ой как нужны!, а почему для D6 таких фильтров не надо было?
    А статья хорошая!!!

    [Ответить]

    Demetr - Апрель 11th, 2013 в 16:50

    Мне для 6-ой версии они не понадобились, потому что после начала работы в друпалом, решил переходить на 7-ую версию.
    http://serho.ru/cust-modules/filtr-dlya-views-s-ierarhicheskim-vyborom-terminov — попробуйте к нему обратится, может сделает для 6-ки вариант модуля.

    [Ответить]

  • Artem — 11.04.2013 в 17:09 #

    Спасибо

    [Ответить]

    Artem - Апрель 23rd, 2013 в 14:40

    Demetr — А как сделать чтобы раскрывающееся фильтры отъезжали от низа страница при отображении(то есть раскрывались не заграницу экрана монитора)

    [Ответить]

    Demetr - Апрель 23rd, 2013 в 15:28

    Граница блока наверное имелось ввиду?
    Тогда это на css все через position:absolute настраивать надо.

    [Ответить]

  • Макс — 24.07.2013 в 22:54 #

    Что-то js скрипт (для открытия/скрытия доп.фильтров) конфликтует с js добавлением удалением из закладок…

    [Ответить]

    Demetr - Июль 24th, 2013 в 22:57

    Возможно надо перевести jquery в noconflict.

    [Ответить]

    Макс - Июль 25th, 2013 в 00:25

    Прошу прощения, это я что-то намудрил по видимому, рабочий и без глюков js код для D7 будет выглядеть так (если где-то ошибся — поправьте):

    (function ($) {
    $(document).ready(
    function(){
    $(‘a#openaddfilter’).click(function(){
    if($(‘div#addoptions’).css(‘display’) == ‘none’){
    $(‘div#addoptions’).show();
    } else{
    $(‘div#addoptions’).hide();
    }
    return false;
    });
    });
    }) (jQuery);

    [Ответить]

    Demetr - Июль 25th, 2013 в 06:56

    Jquery без разницы какая версия друпала, он работает с указанными элементами. Код остается такой же.
    Сегодня попробую потестировать на 7-ом, отпишусь.

    Demetr - Июль 25th, 2013 в 09:16

    Дополнил материал.

  • Макс — 26.07.2013 в 23:58 #

    Не, друг, я конечно не спец, но по моему noconflict и уж тем более загрузка более новых версий jQuery не лучший вариант — 1. с новыми версиями jquery некоторые модули имеют свойство глючить или не работать (сейчас список не приведу, но с отдельными экземплярами я сталкивался не раз); 2) noconflict — вообще не нужен т.к. и без него все прекрасно работает — нужно лишь «обернуть» твой код в стандартную так сказать «обертку» для D7: http://habrahabr.ru/post/161039/

    P.S.: Если мой вклад достоин — можешь поставить ссылку на мою «записную книжку» (maksis.ru)

    [Ответить]

    Demetr - Июль 27th, 2013 в 08:40

    Привет. В пнд проверю. Спасибо за ссылку, надеюсь заработает.

    [Ответить]

    Demetr - Июль 31st, 2013 в 09:42

    Работает. Век живи — век учись, спасибо.

    [Ответить]

  • Сергей — 08.10.2014 в 11:17 #

    А как уместить поля Цена от и Цена в одну строку?
    Как обернуть 2 поля в див?

    [Ответить]

    Demetr - Октябрь 8th, 2014 в 11:40

    В статье написано как выводить виджеты фильтрации. Берете необходимые и оборачиваете/оформляете как угодно.

    [Ответить]

  • Sergey Korzh — 05.04.2015 в 23:35 #

    Также для темизации views exposed form вы можете попробовать модуль Views exposed form layout

    [Ответить]

    Demetr - Апрель 6th, 2015 в 20:15

    Спасибо. Обязательно посмотрю ваш модуль.

    [Ответить]