Как сделать форму поиска со связанными селектами в фильтре?

Ссылка скопирована
1 ответ

Объясню по частям:
0. Сайт про рыб. Селекты сделаны с select2.js

1. Использую обычный тип записи вопдпресса. Там у меня есть древовидные категории.
ЦАРСТВО — ТИП — КЛАСС — ОТРЯД — СЕМЕЙСТВО — РОД — ВИД (а вид - это уже название поста, это не категория).

2. У меня на странице search.php должна быть форма состоящая из 7 селектов (первые два селектор можно не делать, я их сделаю как заглушки. потому что царство (животные) и тип (хордовые) всегда одинаковые). Выбор идет сверху. Т.е. первый выбор - это КЛАСС, после него уже можно будет выбрать ОТРЯД, и т.д.
Идея заключается в том, что в селекте ОТРЯДа должны быть только те категории, которые в дереве выбранного КЛАССа.

3. Нужно также учесть, что человек уже после выбранного например селекта КЛАСС, может поменять в нем выбор, и тогда должны обновиться категории и внутри следующих селектов. Можно сделать либо чтобы изначально были все селекты и категории в них обновлялись при каждом выборе, либо чтобы Селесты друг за другом создавались. А когда в выбранном селекте переопределяли значение, то удалялись следующий/ие после него Селесты и создавалось заново.

Прикладываю скрин категорий из админки. Прикладываю скрин формы из селектов.

Надо учесть, что категории в будущем будут добавляться, поэтому нельзя их точно определить, надо брать список из базы данных (если я правильно понимаю).

Как сделать форму поиска со связанными селектами в фильтре?

Как сделать форму поиска со связанными селектами в фильтре?

Дополнительно:

Это скорее задания для фриланса, чем вопрос. Как сделать, берете и делаете) смотрите api select2.js, берете ajax и wp_query и формируете нужные селекты

Ответы:

Как при выборе в Select менять Option в другом Select?

  • Спасибо, но это зависимость от одного к другому, и данные тут определены изначально.

    А мне до этого нужно достать массив/объект дерева категорий из базы, а потом уже делать зависимости.

так в чём вопрос? Или же если подойти с другой стороны, в чём прикол? Вероятно вопрос в том как сделать селекты. Так так и пишите, как сделать селекты. https://snipp.ru/jquery/select-search
https://wordpress.org/plugins/search-filter/

Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Елена Вебер Ответ

Для связанных селектов с иерархическими категориями Вам нужно строить форму не как семь независимых списков, а как цепочку: выбран родитель — подгружаются только его дети. В WordPress это удобно делать через Ajax: первый селект получает классы, второй после выбора класса получает отряды, третий — семейства и так далее.

На сервере нужен обработчик, который получает parent_id и возвращает дочерние термины:

add_action('wp_ajax_fish_child_terms', 'fish_child_terms');
add_action('wp_ajax_nopriv_fish_child_terms', 'fish_child_terms');
 
function fish_child_terms() {
    $parent_id = absint($_GET['parent_id'] ?? 0);
 
    $terms = get_terms([
        'taxonomy' => 'category',
        'parent' => $parent_id,
        'hide_empty' => false,
    ]);
 
    $result = [];
    foreach ($terms as $term) {
        $result[] = [
            'id' => $term->term_id,
            'text' => $term->name,
        ];
    }
 
    wp_send_json($result);
}

add_action('wp_ajax_fish_child_terms', 'fish_child_terms'); add_action('wp_ajax_nopriv_fish_child_terms', 'fish_child_terms'); function fish_child_terms() { $parent_id = absint($_GET['parent_id'] ?? 0); $terms = get_terms([ 'taxonomy' => 'category', 'parent' => $parent_id, 'hide_empty' => false, ]); $result = []; foreach ($terms as $term) { $result[] = [ 'id' => $term->term_id, 'text' => $term->name, ]; } wp_send_json($result); }

На фронте при изменении селекта очищаете все нижестоящие селекты и загружаете следующий:

async function loadChildren(parentId, targetSelect) {
  const url = ajaxurl + '?action=fish_child_terms&parent_id=' + parentId;
  const response = await fetch(url);
  const terms = await response.json();
 
  targetSelect.innerHTML = '<option value="">Выберите</option>';
  terms.forEach((term) => {
    const option = new Option(term.text, term.id);
    targetSelect.add(option);
  });
}

async function loadChildren(parentId, targetSelect) { const url = ajaxurl + '?action=fish_child_terms&parent_id=' + parentId; const response = await fetch(url); const terms = await response.json(); targetSelect.innerHTML = '<option value="">Выберите</option>'; terms.forEach((term) => { const option = new Option(term.text, term.id); targetSelect.add(option); }); }

Если используете Select2, после изменения списка нужно вызвать обновление:

jQuery(targetSelect).trigger('change.select2');

jQuery(targetSelect).trigger('change.select2');

Поиск записей делайте по самому нижнему выбранному уровню. Если пользователь выбрал только класс, показывайте все записи внутри класса, включая дочерние категории. Для этого можно получить дочерние термины рекурсивно или использовать include_children => true в tax_query.

Важный момент: не загружайте все уровни сразу, если терминов много. Для сайта с рыбами дерево может быть большим, и Ajax-подгрузка по родителю будет гораздо быстрее. Также храните выбранные значения в GET-параметрах, чтобы страницу поиска можно было открыть по прямой ссылке и чтобы фильтр был индексируемым/проверяемым.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно