Сортировка в компонентах Битрикс на ajax

Рассмотрим сортировку на примере компонента catalog

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

html

sections.php

<form id="sortForm" action="<?=$APPLICATION->GetCurPage()?>">
    <div class="sorting">
        <span>Сортировать по:</span>
        <div class="select__box sorting-box custom-select">
            <select class="form-select" name="catalog_sort" onchange="submitFormSorting()">
                <option value="asc"<?= $currentOrder === 'asc' ? ' selected' : '' ?>>Цена (по возрастанию)</option>
                <option value="desc"<?= $currentOrder === 'desc' ? ' selected' : '' ?>>Цена (по убыванию)</option>
            </select>
        </div>
    </div>
</form>

Далее нам нужно обрамить вызов компонента catalog.section, в котором выводятся товары следующим кодом.

<?
    // Для сортировки
    if ($request->isPost() && $request->get('sort') === "Y") {
        $currentOrder = $request->getCookieRaw('catalog_sort_order') ?? 'asc';
        $APPLICATION->RestartBuffer();
    }
?>

...Здесь вызов catalog.section и всего другого, что нужно обновлять

<?
    // Сортировка
    if ($request->isPost() && $request->get('sort') === "Y") {
        die();
    }
?>

Javascript

script.js

/**
 * Сортировка в каталоге (возрастанию / убыванию)
 */
function submitFormSorting() {
    let form = document.getElementById('sortForm');
    let select = form.querySelector('select[name="catalog_sort"]');
    let selectedValue = select.value;
    let cookieName = 'catalog_sort_order'
    let catalogSectionBlock = document.querySelector('#catalogProducts')

    BX.setCookie(cookieName, selectedValue, {expires: 86400*365});

    if (catalogSectionBlock) {

        toggleLoader(catalogSectionBlock)

        let formData = new FormData();
        formData.append(cookieName, selectedValue);
        formData.append('sort', 'Y');

        fetch(window.location.href, {
            method: 'POST',
            body: formData,
        })
        .then(response => response.text())
        .then(response => {
            catalogSectionBlock.innerHTML = response;

            let ob = BX.processHTML(response); // Разделим полученный ответ на HTML/CSS/JS
            BX.ajax.processScripts(ob.SCRIPT); // Запустим заново все js скрипты

            // Генерируем событие после обновления контента (ловим в фильтре, чтобы обновить кнопки быстрых фильтров)
            BX.onCustomEvent('onCatalogSortChanged', [{
                block: catalogSectionBlock,
                sortValue: selectedValue
            }]);
            // Loader
            toggleLoader(catalogSectionBlock, 'remove')
        })
        .catch(error => {
            toggleLoader(catalogSectionBlock, 'remove')
            console.error(error)
        });
    }
}