Написание логики сортировки (или фильтрации) элементов на Bitrix - Сергей Житников: Web-разработчик

Написание логики сортировки (или фильтрации) элементов на Bitrix

Чтобы написать кастомную сортировку (по аналогии можно реализовать фильтрацию элементов), потребуется код и логика, которые описаны на этой странице. Можно доработать, но для описания общей концепции приведенного кода будет вполне достаточно.

Подключение компонента bitrix:catalog.section

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

<!--Обратить внимание на следующие моменты:
1. id="catalog_section" - обязательно нужен, чтобы сюда загрузить итоговые значения сортировки
2. Настройка стандартной сортировки через компонент при такой реализации сломается. Так как мы в поля "ELEMENT_SORT_FIELD" и "ELEMENT_SORT_ORDER" передаем вместо $arParams свои кастомные значения
-->
<?
global $APPLICATION;
$curPage = $APPLICATION->GetCurPage();
$request = Bitrix\Main\Application::getInstance()->getContext()->getRequest();
$request->getPostList();

?>
<div class="category__inner" id="catalog_section">
    <?php
    if (!empty($_SESSION['SORT'][$curPage])) { //если в сессии для есть хоть какие-то сохраненные значения для сортировки для текущей страницы, мы присваиваем их нашим переменным, которые передаем в компонент
        $sortField = $_SESSION['SORT'][$curPage]['field'];
        $sortOrder = $_SESSION['SORT'][$curPage]['order'];
    }

    if($request["SORT"] == "Y") //если есть свежие значения сортировки, переданные в реквесте, мы перезапишем текущие значения сортировки в сессии и включим буферизацию вывода битрикса
    {
        list($sortField, $sortOrder) = explode( '_', $request['DATA_SORT_VALUES']);
        $_SESSION['SORT'][$curPage] = [
            'field' => $sortField,
            'order' => $sortOrder
        ];
        $APPLICATION->RestartBuffer();
    }
    ?>
    <?php $intSectionID = $APPLICATION->IncludeComponent(
        "bitrix:catalog.section",
        "catalog",
        array(
            "IBLOCK_TYPE" => $arParams["IBLOCK_TYPE"],
            "IBLOCK_ID" => $arParams["IBLOCK_ID"],
            "ELEMENT_SORT_FIELD" => $sortField,
            "ELEMENT_SORT_ORDER" => $sortOrder,
            //остальные параметры компонента
        ),
        $component
    ); ?>
    <? if($request["SORT"] == "Y") //это нужно, чтобы область буфера грузилась ДО этого момента а ниже не грузилась
    {
        die();
    } ?>
</div>

При таком подходе соблюдается логика:

  • Так как буферизуем только область вывода компонента, то код, который находится выше или ниже компонента, отработает (например хедер, футер и прочие элементы будут загружены).
  • Благодаря тому, что мы буферизуем определенную область, только код, находящийся внутри  этой области попадет в буфер, а значит, в вывод на экран (код будет возвращен пользователю).
  • Так как отработала вся страница, но в вывод попала только часть, ограниченная областью буферизации, ajax в responce вернет только код, который содержится внутри буферизуемой области.
  • Так как при передаче данных через ajax, в запросе мы передаем нужные post — данные для сортировки, компонент эти данные обработает и отсортирует элементы так, как нам нужно. Соответственно, в буферизуемую область попадет уже отсортированный как нам нужно контент.
  • Последнее действие после того, как ajax получил в ответе отсортированные элементы — загрузить их в обозначенную область (в нашем случае это div с id=catalog_section )

Написание логики по нажатию кнопки сортировки bitrix:catalog.section (на js)

Общий принцип следующий:

  • Получаем нужные данные — кнопки для сортировки
  • Отправляем ajax запрос на текущую страницу с нужными данными
  • Ответ, который придет, вставляем с нужный div — Обертку над компонентом
document.addEventListener("DOMContentLoaded", function() {
  applyFilter(); // Инициируем функцию после загрузки страницы
});

function applyFilter() {
  const buttons = document.querySelectorAll('span[data-sort]');

  buttons.forEach(button => {
    button.addEventListener('click', () => {
      const dataSortValue = button.getAttribute('data-sort');
      let formData = new FormData();
      formData.append('DATA_SORT_VALUES', dataSortValues);
      formData.append('SORT', 'Y');

      fetch(window.location.href, {
        method: 'POST',
        body: formData,
      })
          .then(response => response.text())
          .then(response => {
            let catalogSectionBlock = document.getElementById('catalog_section');
            catalogSectionBlock.innerHTML = response;
            applyFilter(); // Вызываем функцию заново после получения ответа и загрузки нового содержимого
          }).catch(error => console.error(error));
    });
  });
}

Подключение обертки для самой сортировки и логика вывода выбранной сортировки

Чтобы после перезагрузки страницы выбранное значение сортировки было отображено в блоке сортировки (часть этой логики в верстке сортировки):

<?php
/**
 * @var string $curPage
 * @var array $arResult
 */

$sortInstalled = '';

//Чтобы выбранное значение сортировки выводилось после перезагрузки страницы на текущей странице
if (!empty($_SESSION['SORT'][$curPage])) {
    $sortField = $_SESSION['SORT'][$curPage]['field'];
    $sortOrder = $_SESSION['SORT'][$curPage]['order'];
    $sortInstalled = $sortField.'_'.$sortOrder;
}

//Определяем возможные значения сортировки
$sortValues = [
    'name_asc' => 'По имени (возрастание)',
    'name_desc' => 'По имени (убывание)',
    'date_asc' => 'По дате (возрастание)',
    'date_desc' => 'По дате (убывание)',
];
?>

«Представление» блока сортировки и часть логики по выводу актуального значения сортировки:

<?php
use Bitrix\Main\Localization\Loc;

/**
 * @var array $sortValues
 * @var array $arResult
 * @var string $sortInstalled
 */

include 'sort_logic.php'
?>
<!-- Внешний вид блока с сортировкой элементов. Здесь обратить внимание на следующие моменты:
1. атрибут "data-sort", в который нужно передать значения сортировки. В значениях должен быть параметр, по которому проводится сортировка и вариант сортировки ("по возрастанию" или "по убыванию")
Остальное думаю будет понятно по контексту
-->
<div class="category-sort">
    <button type="button" class="category-sort__btn" data-btn>
        <svg astro-icon="sort">
            <use xlink:href="#astroicon:sort"></use>
        </svg><?= ($sortInstalled)?$sortValues[$sortInstalled]:Loc::getMessage('ARRANGE') ?></button>
    <div class="category-sort__container">
        <?php foreach ($sortValues as $k =>$val):?>
            <label class="category-sort-item">
                <input type="radio" <?php if($sortInstalled && $sortInstalled == $k):?>checked<?php endif; ?> name="sort">
                <span class="category-sort-item__inner" data-sort="<?=$k;?>">
                  <?=$val;?>
                </span>
            </label>
        <?php endforeach; ?>
    </div>
</div>

Сергей Житников
Об авторе

Сергей Житников - Веб-разработчик

Занимаюсь веб-разработкой более 5 лет. Специализируюсь на создании адаптивных сайтов и веб-приложений на HTML5, CSS3 и JavaScript. Работаю с популярными CMS и фреймворками, а также уделяю большое внимание оптимизации производительности и чистоте кода.

Есть проект или идея? Буду рад помочь!

Связаться со мной

Последние статьи

19.06.2026
В статье собрал шпаргалку по основным компонентам Bitrix: bitrix:menu, news.list, news.detail, sale.basket.basket.line, main.include и breadcrumb. Разобрал настройку меню из разделов и элементов инфоблока через файлы .menu_ext.php, показываю полные конфигурации компонентов с пояснениями ключевых параметров. Готовые примеры для быстрого копирования и использования в проектах.
19.06.2026
Купоны в Битрикс неразрывно связаны с правилами работы с корзиной — без привязки к правилу они не сработают, а правило без купонов применит скидку на все товары. Разбираю создание купонов через DiscountCouponTable::add(): обязательные и опциональные поля, типы купонов, флаги активности. Показываю примеры работы с датами через объект DateTime (прибавление дней, месяцев и минут).
19.06.2026
Разбираю готовые примеры работы с изображениями в PHP: сохранение на сервер, вывод в браузер, рисование линий и прямоугольников. Отдельно — нюансы с форматами файлов (JPEG/PNG) и поддержкой кириллицы через шрифты.