Телеграм: @bazarow_ru mihail@bazarow.ru Проверяю почту и телеграм 2-3 раза в день.
С 1 по 10 января 2024 будет сделан редизайн сайта.
Пришла пора освежиться!

Сортировать товары по названию, цене и свойствам в каталоге 1С-Битрикс

Просмотров: 3296

Задача: реализовать возможность сортировки товаров в разделах каталога. Сортировка должна работать с использованием AJAX. В качестве параметров сортировки используются: по алфавиту, по цене, по новизне, просмотрам и по брендам.

Сортировать товары по названию, цене и свойствам в каталоге 1С-Битрикс

В файле section.php комплексного шаблона каталога, до вывода bitrix:catalog.section добавляем:

<form class="sortline" method="post" action="/local/ajax/sort.php">
  Сортировать по:
  <select name="sortten">
    <option value="show_counter"<? echo $_COOKIE['sortten'] === 'show_counter' ? ' selected' : ' '; ?>>
      Просмотрам
    </option>
    <option value="name"<? echo $_COOKIE['sortten'] === 'name' ? ' selected' : ' '; ?>>
      Алфавиту
    </option>
    <option value="SCALED_PRICE_2"<? echo $_COOKIE['sortten'] === 'SCALED_PRICE_2' ? ' selected' : ' '; ?>>
      Цене
    </option>
    <option value="property_BRANDS_REF"<? echo $_COOKIE['sortten'] === 'property_BRANDS_REF' ? ' selected' : ' '; ?>>
      Производителям
    </option>
  </select>
</form>

Этот код отображает форму с элементом select для выбора способа сортировки элементов на странице. Форма отправляется методом POST на адрес /local/ajax/sort.php, когда пользователь выбирает один из вариантов сортировки.

Атрибут name элемента select имеет значение sortten, что указывает на то, что выбранный вариант сортировки будет передан на сервер с помощью POST-запроса в виде массива $_POST['sortten'].

Для каждого варианта сортировки определено свое значение атрибута value, которое соответствует выбранному пользователем варианту. Также в каждой опции используется PHP-код для проверки значения куки 'sortten', хранящей выбранный пользователем вариант сортировки. Если значение куки равно значению атрибута value текущей опции, то устанавливается атрибут selected, чтобы эта опция была выбрана по умолчанию.

Таким образом, при отправке формы методом POST на сервер будет передано значение выбранного варианта сортировки в виде массива $_POST['sortten']. Значение куки 'sortten' будет обновлено на сервере в соответствии с выбранным пользователем вариантом сортировки.

Отправка формы с ajax, без кнопки отправки

Здесь же, в section.php или в подключаемом js файле (рекомендую), добавляем javascript код. Обратите внимаение, что в нем используется jquery - не забудте его подключить

$(".sortline").change(function (event) {
    event.preventDefault();
    var form = $(this).closest('form')[0];
    var formData = new FormData(form);
    $('body').addClass('loading_body');
    $.ajax({
        url: form.action,
        type: form.method,
        data: formData,
        processData: false,
        contentType: false,
        success: function (response) {
            location.reload();
        },
        error: function () {
            console.log("Произошла ошибка при отправке запроса.");
        }
    });
});

Этот код реализует функцию, которая выполняется при изменении элемента с классом "sortline". Когда происходит изменение, функция отправляет AJAX-запрос на сервер с данными из формы, содержащей элемент с классом "sortline".

Затем данные формы обрабатываются объектом FormData, который позволяет удобно собирать данные формы и отправлять их в виде multipart/form-data.

После этого происходит отправка AJAX-запроса с помощью функции $.ajax(), где указывается адрес url и метод type запроса, а также данные formData.

Если запрос успешен, то функция обновляет обновляет страницу в текщем уровне прокрутки. На время отправки запроса для элемента body добавляется class 'loading_body', что бы можно было стилизовать его на время отправки запроса.

Запись в COOKIE данных из формы

В деректории "/local/ajax/" создаем файл sort.php c содержимым:

function process_form_data($data) {
    // Обработка данных формы
    if (empty($data['sortten'])) {
        return false;
    }
    return $data['sortten'];
}

function set_cookie($name, $value, $expire = 0) {
    // Установка куки
    setcookie($name, $value, $expire, '/', '', false, true);
}

// Обработка данных формы
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $sortten = process_form_data($_POST);
    if ($sortten !== false) {
        set_cookie('sortten', $sortten);
    }
}

Этот код выполняет следующие действия:

  • Определяется функция process_form_data, которая принимает данные формы в качестве аргумента $data.
  • Функция проверяет, содержит ли массив $data ключ 'sortten', и если нет, то возвращает false.
  • Если ключ 'sortten' присутствует в массиве $data, то функция возвращает его значение.
  • Определяется функция set_cookie, которая принимает имя куки $name, значение $value и необязательный срок истечения действия куки $expire.
  • Функция set_cookie вызывает функцию setcookie() для установки куки с заданным именем, значением и сроком истечения.

Если метод запроса на сервер является POST ($_SERVER['REQUEST_METHOD'] === 'POST'), то выполняется следующее:

  • вызывается функция process_form_data с массивом данных формы $_POST в качестве аргумента;
  • если функция process_form_data возвращает не false, то вызывается функция set_cookie для установки куки с именем 'sortten' и значением, возвращенным функцией process_form_data.

Собственно, дело осталось за малым: нужно добавить параметры сортировки из установленных COOKIE


    <?
    if (count($_COOKIE['sortten']) > '0') {
        $sort = $_COOKIE['sortten'];
    } else {
        $sort = $arParams["ELEMENT_SORT_FIELD"];
    }
    $intSectionID = $APPLICATION->IncludeComponent(
        "bitrix:catalog.section",
        "section",
        array(
            //... сокращен catalog.section
            "ELEMENT_SORT_FIELD" => $sort,
            "ELEMENT_SORT_ORDER" => ($_COOKIE['sortten'] === 'show_counter') ? 'desc' : 'asc',
            //... сокращен catalog.section
        ),
        $component
    );
    ?>

Если сортировка еще не выбиралась, значит в COOKIE нет ключа ['sortten'], тогда используем сортировку из настроек компонента. Если ключ есть, используем параметр сортировки из него.

Обратите внимение: направление для сортировки по просмотрам перевернуто ("по убыванию"), так что бы более просматриваемые товары были в начале. Для остальных сортировок используется параметр "по возрастанию"
Михаил Базаров 22.04.2023
Сортировку можно произвести по стандартным полям, для чего можно воспользоваться приведенным ниже списком:

id - ID элемента;
sort - индекс сортировки;
timestamp_x - дата изменения;
name - название;
active_from или date_active_from - начало периода действия элемента;
active_to или date_active_to - окончание периода действия элемента;
status - код статуса элемента в документообороте;
code - мнемонический код элемента;
iblock_id - числовой код информационного блока;
modified_by - код последнего изменившего пользователя;
active - признак активности элемента;
show_counter - количество показов элемента (учитывается функцией CIBlockElement::CounterInc);
show_counter_start - время первого показа элемента (учитывается функцией CIBlockElement::CounterInc);
shows - усредненное количество показов (количество показов / продолжительность показа);
rand - случайный порядок;
xml_id или external_id - внешний код;
tags - теги;
created - время создания;
created_date - дата создания без учета времени;
cnt - количество элементов (только при заданной группировке)
SCALED_PRICE_<ID> - по ID типа цены
Гость 01.08.2023
А есть ли статья по сортировке категорий по алфавиту()?
Ни одной статьи и адекватного ответа не попалось...  
Михаил Базаров 01.08.2023
Если выводите разделы компонентом catalog.section.list можете передать ему параметр
CUSTOM_SECTION_SORT в котором массив из правил сортировки для метода CIBlockSection::GetList.
Что-то вроде этого:
Код
'CUSTOM_SECTION_SORT' => array (
      'NAME' => 'ASC'
)

Это есть в документации к catalog.section.list
Если что-то другое имели ввиду, нужен более развернутый вопрос.