tomdropov90
@tomdropov90

Как реализовать связную фильтрацию в Битрикс?

Имеется 4 selecta и таблица с данными:

6517b67a08696229714771.png

<form class="js-response-select-data" method="post" enctype="multipart/form-data">
            <div class="select-wrapper">
                <select id="cities">
                    <option value="">Все города</option>
                    <?php
                    if (CModule::IncludeModule("iblock")) {
                        $property_enums = CIBlockPropertyEnum::GetList(array("ID" => "ASC", "SORT" => "ASC"), array("IBLOCK_ID" => 27, "CODE" => "CITY"));
                        while ($enum_fields = $property_enums->GetNext()) {
                            echo "<option>";
                            echo $enum_fields["VALUE"];
                            echo "</option>";
                        }
                    }
                    ?>
                </select>

                <select id="companies">
                    <option value="">Все предприятия</option>
                    <?php
                    if (CModule::IncludeModule("iblock")) {
                        $property_enums = CIBlockPropertyEnum::GetList(array("ID" => "ASC", "SORT" => "ASC"), array("IBLOCK_ID" => 27, "CODE" => "COMPANY"));
                        while ($enum_fields = $property_enums->GetNext()) {
                            echo "<option>";
                            echo $enum_fields["VALUE"];
                            echo "</option>";
                        }
                    }
                    ?>
                </select>

                <select id="specializations">
                    <option value="">Все функции</option>
                    <?php
                    if (CModule::IncludeModule("iblock")) {
                        $property_enums = CIBlockPropertyEnum::GetList(array("ID" => "ASC", "SORT" => "ASC"), array("IBLOCK_ID" => 27, "CODE" => "SPECIALIZATION"));
                        while ($enum_fields = $property_enums->GetNext()) {
                            echo "<option>";
                            echo $enum_fields["VALUE"];
                            echo "</option>";
                        }
                    }
                    ?>
                </select>

                <select id="categories">
                    <option value="">Все категории</option>
                    <?php
                    if (CModule::IncludeModule("iblock")) {
                        $property_enums = CIBlockPropertyEnum::GetList(array("ID" => "ASC", "SORT" => "ASC"), array("IBLOCK_ID" => 27, "CODE" => "CATEGORY"));
                        while ($enum_fields = $property_enums->GetNext()) {
                            echo "<option>";
                            echo $enum_fields["VALUE"];
                            echo "</option>";
                        }
                    }
                    ?>
                </select>
                <a href="#" onclick="return false;"
                   class="js-reset-data">
                    Сбросить
                </a>
            </div>
        </form>


        <div class="table-data-wrapper">
            <div class="table-responsive">
                <table id="table">
                    <thead style="color: #000;">
                    <tr>
                        <th style="width: 100px;" scope="col">Город</th>
                        <th style="width: 100px;" scope="col">Предприятие</th>
                        <th style="width: 100px;" scope="col">Специализация</th>
                        <th style="width: 100px;" scope="col">Категория</th>
                        <th style="width: 100px;" scope="col">Заработная плата</th>
                        <th style="width: 100px;" scope="col">Дата публикации</th>
                    </tr>
                    </thead>
                    <tbody>
                    <? foreach ($arResult["ITEMS"] as $arItem): ?>
                        <tr class="js-content-data-table">
                            <td><? echo $arItem['PROPERTIES']['CITY']['VALUE']; ?></td>
                            <td><? echo $arItem['PROPERTIES']['COMPANY']['VALUE']; ?></td>
                            <td><? echo $arItem['PROPERTIES']['SPECIALIZATION']['VALUE']; ?></td>
                            <td data-category="<? echo $arItem['PROPERTIES']['CATEGORY']['VALUE']; ?>">
                                <a href="<?= $arItem["DETAIL_PAGE_URL"]; ?>" target="_blank">
                                    <? echo $arItem['NAME']; ?>
                                </a>
                            </td>
                            <td><? echo $arItem['PROPERTIES']['MONEY']['VALUE']; ?> Руб.</td>
                            <td><? echo ConvertDateTime($arItem['TIMESTAMP_X'], "DD.MM.YYYY", "ru"); ?></td>
                        </tr>
                    <? endforeach; ?>
                    </tbody>
                </table>
                <div class="container">
                    <div class="row">
                        <div class="col-md-12 d-flex justify-content-center">
                            <button style="width:50%;margin:0;margin-top:20px;margin-bottom:20px;"
                                    class="requestButton js-button-show-more-data-table">
                                Показать ещё
                            </button>
                        </div>
                    </div>
                </div>
            </div>
        </div>


Нужно реализовать связную фильтрацию.
Пример: выбираем Город из select и получаем все записи по этому городу, потом если выбрали Предприятие из другого select, то выводим в таблицу те предприятия, которые соответствуют выбранному Городу в select, по аналогии, тоже самое касается и Категорий, и Специализаций. Нужна возможность выводить записи как по одному свойству, так и по множеству свойств.

Я решил это сделать путём AJAX-запроса на бекенд, который фильтрует входящие данные, и отдаёт готовый JSON для вывода в таблицу.

AJAX-запрос:
$(document).ready(function () {
    $('.js-response-select-data').change(function () {
        const selectCityValue = $(this).find('#cities').val();
        const selectCompanyValue = $(this).find('#companies').val();
        const selectSpecializationsValue = $(this).find('#specializations').val();
        const selectCategoriesValue = $(this).find('#categories').val();

        const form = $(this)[0];
        const formData = new FormData(form);
        formData.append('CITY', selectCityValue);
        formData.append('COMPANY', selectCompanyValue);
        formData.append('SPECIALIZATION', selectSpecializationsValue);
        formData.append('CATEGORY', selectCategoriesValue);

        $.ajax({
            type: "POST",
            url: '/send-select-data-for-table-vacancy.php',
            cache: false,
            contentType: false,
            processData: false,
            data: formData,
            success: function () {
                console.log('Успешно отправлено!');
            },
            error: function () {
                console.log('Неуспешно отправлено!');
            },
        });
    });
});


Backend:
<?php
require_once($_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/include/prolog_before.php");

CModule::IncludeModule('iblock');

$iblockId = 27; // Замените на ID вашего инфоблока

// Получение данных из AJAX-запроса
$cityToFind = $_POST['CITY'];
$companyToFind = $_POST['COMPANY'];
$specializationToFind = $_POST['SPECIALIZATION'];
$categoryToFind = $_POST['CATEGORY'];

$arFilter = [
    "IBLOCK_ID" => $iblockId,
    "ACTIVE" => "Y",
];

// Добавление фильтров на основе полученных данных
if (!empty($cityToFind)) {
    $arFilter["PROPERTY_CITY"] = $cityToFind;
}

if (!empty($companyToFind)) {
    $arFilter["PROPERTY_COMPANY"] = $companyToFind;
}

if (!empty($specializationToFind)) {
    $arFilter["PROPERTY_SPECIALIZATION"] = $specializationToFind;
}

if (!empty($categoryToFind)) {
    $arFilter["PROPERTY_CATEGORY"] = $categoryToFind;
}

$arSelect = ["ID", "NAME"];
$res = CIBlockElement::GetList([], $arFilter, false, false, $arSelect);

$arResult = [];

while ($ob = $res->GetNextElement()) {
    $arFields = $ob->GetFields();
    $arResult[] = [
        "ID" => $arFields["ID"],
        "NAME" => $arFields["NAME"],
    ];
}

// Отправка JSON-ответа
header('Content-Type: application/json');
echo json_encode($arResult);

require_once($_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/include/epilog_after.php");
?>

Если указать только один параметр фильтрации на бэкенде, например Город, то бэк отдаёт данные без проблем, но если добавить ещё 3 свйоства для фильтрации, то я получаю сообщение "No properties". Вопрос, как правильно реализовать связную фильтрацию на бэке в Битрикс, чтобы я получал элементы из инфоблока, которые соответствуют AJAX-запросу?
  • Вопрос задан
  • 162 просмотра
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы