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 - 19 февраля, 2012 в 21:00

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

    [Ответить]

  • Dr. MOON — 08.06.2012 в 00:26 #

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

    [Ответить]

    Demetr - 8 июня, 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 - 11 февраля, 2013 в 19:23

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

    [Ответить]

  • nurik — 11.02.2013 в 19:38 #

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

    [Ответить]

    Demetr - 11 февраля, 2013 в 20:04

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

    [Ответить]

    nurik - 11 февраля, 2013 в 20:07

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

    [Ответить]

    Demetr - 11 февраля, 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 - 9 апреля, 2013 в 13:58

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

    [Ответить]

    nurik - 9 апреля, 2013 в 14:13

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

    [Ответить]

    Demetr - 9 апреля, 2013 в 14:20

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

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

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

  • Artem — 11.04.2013 в 16:24 #

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

    [Ответить]

    Demetr - 11 апреля, 2013 в 16:28

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

    [Ответить]

  • Artem — 11.04.2013 в 16:46 #

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

    [Ответить]

    Demetr - 11 апреля, 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 - 23 апреля, 2013 в 14:40

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

    [Ответить]

    Demetr - 23 апреля, 2013 в 15:28

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

    [Ответить]

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

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

    [Ответить]

    Demetr - 24 июля, 2013 в 22:57

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

    [Ответить]

    Макс - 25 июля, 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 - 25 июля, 2013 в 06:56

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

    Demetr - 25 июля, 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 - 27 июля, 2013 в 08:40

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

    [Ответить]

    Demetr - 31 июля, 2013 в 09:42

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

    [Ответить]

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

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

    [Ответить]

    Demetr - 8 октября, 2014 в 11:40

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

    [Ответить]

  • Sergey Korzh — 05.04.2015 в 23:35 #

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

    [Ответить]

    Demetr - 6 апреля, 2015 в 20:15

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

    [Ответить]