Исторически так сложилось, что комплексный компонент 1С-Битрикс не позволяет пользователю в публичной части отсортировать товары, хотя бы по цене, дате, наименованию, а также выбрать сколько товаров на странице ему выбрать. Но ни один из интернет-магазинов не обходится без такого функционала, который кстати включен в почти все шаблоны готовых интернет-магазинов в Маркетплэйс. Но для реализовать блоки «Сортировать по: ...» и «Показать по: ...» достаточно просто. Нужно всего-лишь использовать массив $_REQUEST и метод API 1С-Битрикс GetCurPageParam() для передачи данных в этот массив.

Приступим!

Для начала определимся, что от нас хотят:

  • Вывести справа над списком товаров блок «Показать по: 18 36 54 72». (По умолчанию выводится 9).
  • Слева над списком товаров вывести блок «Сортировать по: цене, наименованию, дате».
  • Повторное нажатие на уже выбранный вариант сортировки переключает направление сортировки.
  • Дата — дата изменения, цена — отображаемая цена товара.

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

За отображение количества товаров на странице отвечает параметр PAGE_ELEMENT_COUNT. В него мы и будем передавать выбранное пользователем количество с помощью $_REQUEST и GetCurPageParam().

Для начала заведем соответствующую переменную и по-умолчанию присвоим ей значение заданное в параметрах компонента. А затем при клике пользователя на нужное ему количество элементов будем его модифицировать.

Следующий код предлагается размещать перед подключением компонента catalog.section. Если используется комплексный компонент catalog, то в файле в котором происходит вызов компонента catalog.section выводящего товары на нужной странице.

<?php
$pageElementCount = $arParams["PAGE_ELEMENT_COUNT"];
if (array_key_exists("showBy", $_REQUEST)) {
    if ( intVal($_REQUEST["showBy"]) && in_array(intVal($_REQUEST["showBy"]), array(18, 36, 54, 72)) ) {
        $pageElementCount = intVal($_REQUEST["showBy"]); 
        $_SESSION["showBy"] = $pageElementCount;
    } elseif ($_SESSION["showBy"]) {
        $pageElementCount = intVal($_SESSION["showBy"]);
    }
}
?>
<div class="show_number">
    <span class="show_title">Показать по </span>
    <span class="number_list">
        <? for( $i = 18; $i <= 72; $i+=18 ) : ?>
            <a rel="nofollow" <? if ($i == $pageElementCount): ?>class="current"<? endif; ?> 
                 href="<?= $APPLICATION->GetCurPageParam('showBy='.$i, array('showBy', 'mode')) ?>"
            >
                <span><?= $i ?></span>
            </a>
        <? endfor; ?>
    </span>
</div>

И теперь передадим полученное значение в компонент:

<?php
$APPLICATION->IncludeComponent(
    "bitrix:catalog.section",
    ...
    "PAGE_ELEMENT_COUNT" => $pageElementCount,
    ...
?>

Теперь разберемся с сортировкой. Она не намного сложнее, за исключением того, что нам нужно проверять текущее направление и менять его. Для этого в методе GetCurPageParam() мы будем передавать два параметра sortBy и orderBy. А затем в соответствующих переменных передавать их в параметры компонента "ELEMENT_SORT_FIELD" и "ELEMENT_SORT_ORDER" соответственно. По умолчанию сортировка должна осуществляться с помощью внутреннего поля сортировки 1С-Битрикс — sort.

Проверяем направление сортировки и меняем в случае необходимости:

<?php
if (isset($_REQUEST['orderBy'])) {
    if ($_REQUEST['orderBy'] == 'asc') {
        $orderBy = 'desc';
    } else {
        $orderBy = 'asc';
    }
} else {
    $orderBy = 'asc';
}
?>

Выводим ссылки на сортировку:

<div class="sort-section">
Сортировать по:
    <a rel="nofollow" <? if ($sortBy == 'price') : ?> class="current-sort" <? endif; ?>
         href="<?= $APPLICATION->GetCurPageParam('sortBy=price&orderBy='.$orderBy, array('sortBy', 'orderBy')) ?>"
    >
        <span class="sort">цене</span>
    </a>
    <a rel="nofollow" <? if ($sortBy == 'name') : ?> class="current-sort" <? endif; ?>
	 href="<?= $APPLICATION->GetCurPageParam('sortBy=name&orderBy='.$orderBy, array('sortBy', 'orderBy')) ?>"
    >
	<span class="sort">наименованию</span>
    </a>
    <a rel="nofollow" <? if ($sortBy == 'date') : ?> class="current-sort" <? endif; ?>
         href="<?= $APPLICATION->GetCurPageParam('sortBy=date&orderBy='.$orderBy, array('sortBy', 'orderBy')) ?>"
    >
	<span class="sort">дате</span>
    </a>
</div>

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

Для даты нам нужно значение поля 'timestamp_x', отвечающего за дату изменения. Для цены мы должны узнать наименование типа цены, которая выводится из поля элемента инфоблока. Для этого нужно распечатать массив $arItem в шаблоне компонента (в моем случае catalog.section) либо с помощью var_dump($arItem);, либо echo '<pre>'; print_r($arItem); echo '</pre>';. Находим поле массива отвечающего за вывод цены и копируем его название, в моем случае это оказалось CATALOG_PRICE_1. Стоит обратить внимание, что в случае с ценой использовать нужно название того поля, которые содержит значение цены без валюты.

И передадим полученные данные в переменную $sortBy:

<?php
if (isset($_REQUEST['sortBy'])) {
    $sortBy = $_REQUEST['sortBy'];
} else {
    $sortBy = 'sort';
}
if ($sortBy=='price') {
    $sortBy = 'CATALOG_PRICE_1';
}
if ($sortBy=='date') {
    $sortBy = 'timestamp_x';
}
?>

И передадим значения в параметры компонента:

<?php
$APPLICATION->IncludeComponent(
    "bitrix:catalog.section",
    ...
    "ELEMENT_SORT_FIELD" => $sortBy,
    "ELEMENT_SORT_ORDER" => $orderBy,
    ...
?>

Вот собственно и все. В результате получится примерно такая строка:

image

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

Комментарии (24)


  1. DeadikGudwin
    20.11.2015 10:21

    Пару раз сталкивался с битриксом в связи с чем вопрос — он без допилов хоть что нибудь полезное умеет?


    1. Elendai
      20.11.2015 10:26

      Битрикс идеален в поставляемой конфигурации. Перекрасил стандартные компоненты, як-як и в продакшн. Но если нужно что-то кастомное, то лучше даже не пытаться в него лезть. А уметь… сервер он отлично умеет грузить: Р


      1. DeadikGudwin
        20.11.2015 10:36

        Вот и я о том же, у меня сложилось впечатление что он расчитан на установил, поменял css и забил. Когда в проект было необходимо добавить кастомный функционал я начал рыться в документации и официальном форуме обнуружил что документация часто противоречит реальности, составлена местами очень неграмотно (словосочетание «java скрипт» увидел на нескольких страницах), а форум представляет из себя тонны вопросов в стиле «Куда нужно нажать» или «Что нужно купить».


        1. Suntechnic
          20.11.2015 12:57

          Очень редко хожу в документацию. В основном в код.


        1. Alexufo
          20.11.2015 14:08

          Документация это жесть. Мало того что она устаревает местами, так это устаревает местами только у вас!
          У меня есть два магазина, и в одном событие работает, а в другом — нет. Чистая копипаста. Оказывается, модули интернет магазина разные, что меня немного смутило. Ну ведь оба магаза же обновляются. Другими словами пошла фрагментация и параллельная разработка модуля магазина. Такое ощущение что набралась критическая масса старого кода, который просто так битриксу не закопаешь. Потому если что не пашет — доступ на сайт и в техподдержку с подробным писанием. По другому увы.


          1. Suntechnic
            20.11.2015 16:25

            Не понял. Вы утверждаете что модули ИМ магазина имеющие одну версию отличаются по коду?


            1. Alexufo
              20.11.2015 16:30

              Сам модуль sale — модуль интернет магазина имеет разные версии 14 и 15. Просто один магазин покупался 5 лет назад — другой 3 года назад. Оба обновляются. Если в 14 работает кое что из API то в 15 нет.(точнее со вчера в бете уже да, поправили в теч двух дней) Документашка одна.


              1. Suntechnic
                20.11.2015 17:19

                А — ну так-то да. А что за событие? Ну чтобы знать.


    1. Suntechnic
      20.11.2015 12:56

      Так же как и другая какая-нибудь CMS — умеет всё, что нужно для того чтобы можно было её продать. Ну или «продать» в отношении свободных CMS.


    1. Alexufo
      20.11.2015 13:58

      Как меня обижает кастомизация компонентов. Если раньше оформление товара состояло из 6-8 php файлов то новый из 10-15 + css и два js.
      К тому же вот первый раз ковыряю новый компонент, уже пошло у них в багтеркер мое замечение по компоненту и по событию из api. Оно просто не работало. Похоже да, битрикс не все кастомизируют если можно так взять и найти багу — из API и не пашет событие. но если есть 1С-ка обмен, инет магаз, то выбора практически нет. Печаль но это так.


      1. DeadikGudwin
        20.11.2015 14:07

        Если кастомизация не нужна, то есть ucoz, umi.ru и прочие конструкторы, которых сейчас навалом.
        Протокол обмена данными с 1С подробно описан, на многие cms уже есть решения для обмена данными, которые принимают CommerceML2 в качестве входных данных, для обмена достаточно на сайте иметь шлюз который будет принимать запрос с выгрузкой со стороны 1С, поэтому наличие обмена с 1С никак не сужает круг выбора CMS до одной системы.


        1. Alexufo
          20.11.2015 14:14

          Конструкторы не перевариваю, не факт что будут дешевле. Обмен с 1С под гигабайт. Хоть протокол и открытый, но нет нигде удобнее модуля обмена чем в битриксе. Плюс и какие же у нас еще есть инетмагазы такого уровня? Они либо стоят ЧУТЬ дешевле, либо бесплатные с платными модулями и что там что-то удобнее или безглючнее такой же спорный вопрос.


  1. philosophocat
    20.11.2015 11:58

    В комментариях vk.com справедливо заметили, что такие вещи либо неинтересны, либо учатся в первую неделю освоения платформы.
    P.S. это вы игнорируете функционал платформы, залезая напрямую в $_SESSION и $_REQUEST или битрикс такой злодейский?


    1. Suntechnic
      20.11.2015 12:59

      P.S. это вы игнорируете функционал платформы, залезая напрямую в $_SESSION и $_REQUEST или битрикс такой злодейский?

      Юзанье $_REQUEST в порядке вещей. $_SESSION как правило не нужна. Но в данном случае вполне можно так заюзать. Никаких интерфейсов для работы с этим в Bitrix-Framework действительно нет.


      1. Straven
        20.11.2015 13:25

        Залезание в $_SESSION необходимо по той причине, что иначе значения не сохранятся при возвращении из просмотра детальной страницы элемента.


        1. Suntechnic
          20.11.2015 13:38

          Да я понял. Потому и пишу:

          Но в данном случае вполне можно так заюзать.

          Я такие вещи в куки обычно пишу.


  1. Diden05
    20.11.2015 13:38

    Как быть в данном случае с технологией композитный сайт?


    1. Suntechnic
      20.11.2015 13:47

      Как и в любом случае — лучше не использовать ;)
      А если серьёзно — а в чем тут проблема? Я сам не очень знаю, поскольку когда мне потребовалось для одного ресурса, я посмотрел на эту технологию… и навелосипедил свою, чисто под этот ресурс.
      Мне кажется оно не взлетит. Как не взлетели HL блоки.


      1. Diden05
        20.11.2015 14:27

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


        1. Suntechnic
          20.11.2015 16:24

          Возможно. В тех проектах что попадают ко мне, я не вижу активного использования HL потому и делаю такой вывод. С другой стороны это некоторые ценз. Вряд ли если разработчик работает хорошо, проект вообще попадет ко мне. Он скорее всего у него же и останется. Специфика накладывает отпечаток…


  1. Straven
    20.11.2015 13:59

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


  1. andrew72ru
    21.11.2015 09:12

    Н-да… Казалось бы, несколько лет прошло с того момента, когда я в последний раз битрикс изнутри видел.
    Но нет.
    По-прежнему всё так же, как и было.
    Всё так же лезем руками в $_REQUEST и сессию.
    Всё так же код не по стандартам.
    По-прежнему дикая мешанина из php и html.
    По-прежнему нет генерации тэгов html.

    Один только вопрос занимает меня – почему за это вот ещё и денег просят. Да ещё и платят некоторые!


    1. pilezkiy
      23.11.2015 02:28

      За это денег просят потому, что вся эта мешанина работает и приносит деньги владельцам сайта. Пока сайт работает, как оно там внутри устроено никого не волнует — ни посетителя, ни хозяина этого сайта.
      Для любителей писать код много и красиво идет переход на ядро D7.


      1. andrew72ru
        23.11.2015 06:54

        Пока сайт работает

        То есть пока не нужны обновления, пока (в связи с отсутствием обновлений, ведь они не нужны) не загнали какого-нибудь зловреда, пока не понадобилось (даже в малой части!) поменять структуру и так далее и далее и далее.

        За это денег просят в первую очередь из-за неграмотности в сфере IT большинства «владельцев» сайтов, и их нежелания хоть чуть-чуть потратиться на тех, кто может их в этом вопросе проконсультировать. НУ и благодаря агрессивной маркетинговой кампании одной там организации с желто-красным логотипом, а так же из-за обилия халтурно работающих «программистов», которые пишут вот это вот

        <a rel="nofollow" <? if ($sortBy == 'date') : ?> class="current-sort" <? endif; ?>
                 href="<?= $APPLICATION->GetCurPageParam('sortBy=date&orderBy='.$orderBy, array('sortBy', 'orderBy')) ?>"
            >
        


        Потому что найдись в окружении будущих выгодоприобретателей сайта человек, который перед началом разработки скажет «Вот opensouce-движок, вот за 4 000 модуль оплаты через банк, вот за 2 000 модуль синхронизации с учетной системой», картина использования битрикса была бы совсем другой. Кардинально другой.