Сравнение товаров в Drupal 7





Сравнение товаров в Drupal 7

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

Для создания страницы сравнения товаров нам понадобятся: собственно сами товары (обычные ноды), модули flag, views, ctools, views_hacks.

Итак, запасемся терпением и поехали!

Шаг 1: создаем флаг





При установке модуля flag по умолчанию создается флаг "bookmarks". Можно использовать его, можно создать свой.
Настройки флага: скриншот #1, скриншот #2.

Настройки прав относительно данного флага распространяются только на администраторов сайта и авторизованных пользователей. Это достаточно неудобно, так как необходимо, чтобы любой анонимный пользователь мог добавлять товары к сравнению. Для решения этой проблемы необходимо установить модуль Session API. После инсталляции модуля в настройках флага появится чекбокс, в котором можно указать и права для анонимных пользователей.

Итак, теперь мы можем лицезреть следующую картину:

Ок, ссылка на добавление товара к сравнению у нас имеется. Переходим к следующему шагу.

Шаг 2: создаем страницу сравнения

Создаем страницу:

  • скриншот создания страницы представления (обратите внимание, что в качестве формата отображения используется “Table” и отсутствует сортировка);
  • сохраняем, переходим на страницу редактирования представления;
  • добавляем зависимость Flags: Node flagскриншот;
  • добавляем различные поля (уже на ваше усмотрение), также можно добавить поле flag/unflagскриншот;

Конечные настройки представления на этом этапе у меня выглядят следующим образом:
 создаем страницу сравнения
Сохраняем представление, проходимся по продуктам, добавляем их к сравнению, переходим на страницу site.com/compare (если вы не меняли адрес расположения страницы представления) и видим следующую картину:

 создаем страницу сравнения

Поздравляю! Страница сравнения товаров у вас готова!

Возможно, такой вид отображения таблицы вас не устраивает. Хочется, чтобы товары отображались не строками а столбцами. В этом случае, вам поможет дополнительный модуль Views Hacks. Установив его (а конкретно субмодуль Views Flipped Table), на странице редактирования представления вы можете поменять формат отображения с Table на Flipped Table (скриншот). После сохранения представления, наша страница сравнения изменится:

 создаем страницу сравнения

Вот теперь все выглядит по-взрослому! И как раз на этом этапе начинаются танцы с бубном. Суть в том, что если добавить 10-15 товаров к сравнению, то вся таблица либо порвет верстку страницы и уйдет за правый край вселенной (скриншот), либо будет скролиться, а это очень неудобно, так как, когда вы прокрутите до последнего столбца, вы потеряете из вида «шапку» с описанием ячеек. А хотелось бы, чтобы столбец с названием ячеек всегда оставался при скроле.

Шаг 3: танцы с бубном

Сначала нам необходимо поменять шаблон отображения таблицы. Для этого из папки views_hacks\views_flipped_table копируем в папку templates нашей темы файл views-flipped-table.tpl.php и переименовываем его views-flipped-table--[машинное_имя_представления].tpl.php

Дальше следующий код:

<div id="compare-products-table" class="clearfix">
    <div class="headers">
      <table>
        <tbody>
        <?php foreach ($rows_flipped as $field_name => $row) : ?>
        <tr class="<?php print $row_classes_flipped[$field_name] . '&nbsp; tr_' . $field_name; ?>">
          <th>
            <?php echo $header[$field_name]; ?>
          </th>
        </tr>
          <?php endforeach; ?>
        </tbody>
      </table>
    </div>
    <div class="prods">
      <table>
        <tbody>
        <?php foreach ($rows_flipped as $field_name => $row) : ?>
        <tr class="<?php print $row_classes_flipped[$field_name] . '&nbsp; tr_' . $field_name; ?>">
          <?php foreach ($row as $index => $item): ?>
          <td>
            <?php echo $item; ?>
          </td>
          <?php endforeach; ?>
        </tr>
          <?php endforeach; ?>
        </tbody>
      </table>
    </div>
  </div>

По сути он создает 2 div’a, в одном находятся заголовки ячеек, во втором – сами ячейки с полями продукта.
Сохраням и видим следующую картину: скриншот.
Теперь немного CSS:

#compare-products-table .headers {
    float: left;
    width: 120px; /* ширина столбца с заголовками ячеек */
}
#compare-products-table .prods {
    display: inline;
    float: right;
    overflow-x: auto;  /* прокрутка */
    width: 570px;  /* ширина дива с продуктами */
}

Обновляем страницу и видим следующий результат: скриншот.

Теперь осталось лишь вытянуть по высоте ячейки с заголовками, чтобы они совпадали с высотой ячеек с продуктами. Для этого я не нашел ничего более умного как прибегнуть к js'у.

(function ($) {
    $(document).ready(function() {
 
        // compare laminate
         $('#compare-products-table .prods tr').each(function(index) {
            var trHeight = $(this).height();
            var trClass = $(this).attr("class");
             $('#compare-products-table').find('tr').eq(index).attr("class", trClass).css("height", trHeight);
             // alert(trHeight);
         });
 
    });
 
})(jQuery);

Сохраняем, чистим кешы.
Тадааам:

сравнение товаров в Drupal 7

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

Эпилог

Возможно это не самый drupalway, но он работает.

Если у вас есть более грамотное решение насущной проблемы - не поленитесь отпишитесь. Буду премного благодарен!





Комментарии

Пригодится, спасибо.

Еще переведите "Comment" на Русский :)

Да, надо будет подчистить переводы. Спасибо :)

А как ограничить количество товаров для сравнения например 3 товарами, а при попытки добавить 4 товар выводить предупреждение и не выдавать и как сбросить сравнение, когда оно уже не нужно и перейти к другому

Отлично, теперь мне и видео можно не доделывать! :)

Я бы еще добавил небольшой JS, позволяющий по галочке спрятать ячейки, в которых у сравниваемого нет различий. Могу заслать, как раз под такую сравнялку делал год назад.

Было бы здорово. :)

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

Ну так сообщи, куда засылать - я зашлю :)

Подскажите, как вывести ссылку на сравнение во всех вариантах отображения товара, а не только в анонсе и полном отображении?

<?php $account = menu_get_object('node');
    print flag_create_link('compare', $node->nid);?>

Спасибо за оперативный ответ. Скажите еще пожалуйста, куда этот код вставлять?

node.tpl.php

А можете рассказать, куда помимо тизера/полной ноды вы хотите добавить флаг?

у меня есть вариант отображения "product list"

Варианты отображения настраиваются тут: site.com/admin/structure/types/manage/[тип-контента]/display

Где вы нашли product-list? Или это представление?

внизу на этой странице есть возможность добавить дополнительные варианты отображения. затем этот тип отображения выводится через views полем rendered_entity

Я, если честно, не в курсе, откуда у вас появился product-list в том списке, но это ничего не меняет, в теории для других типов дисплеев флаг можно вывести через препроцессинг ноды, выбрав там нужный тип отображения.

а если этот код вывести через views, в подвале?

Попробуйте. Только нужно будет как-то перед выводом определить переменную $node.

А можете поподробней объяснить, как вывести через препроцессинг ноды?

скажите сначала, как у вас был создан тип дисплея product-list

у меня установлена сборка commerce kickstart. там на странице admin/structure/types/manage/[тип]/display внизу списка полей есть ссылка "Расширенные параметры отображения" под ней "Использовать расширенное отображение для следующих способов вывода:
Содержимое полностью
Анонс
RSS
Маркеры
Product list
это список с радикнопками, что отмечено, то отображение собственно становится доступно для редактирования

А как сделать масштабный unflag для всех выделенных к сравнению продуктов?
Что-то вроде кнопки "Очистить", что бы не клацать по каждому товару.
Спасибо!

Присоединяюсь к предыдущему вопросу, очень интересно как можно разом обнулить все флаги. Очень полезный материал, спасибо Вам!

На деле пока руки не дошли попробовать, но есть мысль следующая:

  • создаем новый тип флага "unflag"
  • создаем новое правило в rules - по клику на этот флаг - делаем unflag всех продуктов

Спасибо за ответ, надо будет покопать в этом направлении

Спасибо за подробное описание. Все получилось замечательно.
Хочется пойти дальше, создал блок в котором отображается количество добавленных для сравнения товаров, и их названия, ну и ссылка на саму страницу сравнения. Работает, блок конечно отображается только после перезагрузки страницы, как и все изменения, удаления и добавления к сравнению. А надо, чтобы это все происходило без перезагрузки страницы. Не подскажите как сделать?

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

Plain text

  • HTML-теги не обрабатываются и показываются как обычный текст
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Строки и параграфы переносятся автоматически.