Как фильтровать данные пользовательских записей с помощью AJAX?

Вопрос или проблема

Я создал пользовательский тип записи с “Реселлерами”, чтобы ввести свои личные товары реселлеров. У поста “Реселлеры” есть таксономии, такие как “Страны” и “Департаменты”.

У меня возникла проблема:

При первом отображении страницы данные из таксономий моего пользовательского типа записи не загружаются. Если я нажимаю на одну из моих ссылок, данные успешно обновляются. Проблема заключается в том, что страна без назначенной категории “Департамент” (например, Германия) = результаты отображаются, но выпадающий список “Департамент” должен быть скрыт.

Может кто-нибудь сказать, где я сделал ошибку?

function.php

if( !function_exists( 'reseller_department' ) ){
    function reseller_department(){
        $location = get_terms( 'reseller-department', array( 'parent' => 0 ) );
        if( !empty($location) ){
            foreach( $location as $term ){
                if(isset($_GET['reseller_department']) ){
                    if($_GET['reseller_department'] == $term->slug ){
                        $selected = 'selected';
                    }else{
                        $selected = '';
                    }
                }else{
                    $selected = '';
                }
                echo '<option value="'.$term->slug.'" '.$selected.'>'.$term->name.'</option>';
            }
            if(!isset($_GET['reseller_department']) || $_GET['reseller_department'] == '-1'){
                echo '<option value="-1" selected>'.__( 'все департаменты', 'nalys-plugin' ).'</option>';
            }else{
                echo '<option value="-1">'.__( '…', 'nalys-plugin' ).'</option>';
            }
        }
    }
}

if( !function_exists( 'reseller_country' ) ){
    function reseller_country(){
        $location = get_terms( 'reseller-country', array( 'parent' => 0 ) );
        if( !empty($location) ){
            foreach( $location as $term ){
                if(isset($_GET['reseller_country']) ){
                    if($_GET['reseller_country'] == $term->slug ){
                        $selected = 'selected';
                    }else{
                        $selected = '';
                    }
                }else{
                    $selected = '';
                }
                echo '<option value="'.$term->slug.'" '.$selected.'>'.$term->name.'</option>';
            }
            if(!isset($_GET['reseller_country']) || $_GET['reseller_country'] == '-1'){
                echo '<option value="-1" selected>'.__( '...', 'nalys-plugin' ).'</option>';
            }else{
                echo '<option value="-1">'.__( '…', 'nalys-plugin' ).'</option>';
            }
        }
    }
}

archieve.js

jQuery(document).ready(function($)  {
    $("#archive-wrapper").height($("#archive-pot").height());
    $("#archive-browser select").change(function() {
        $("#archive-pot")
            .empty()
            .html("<div style="text-align: center; padding: 30px;">Загрузка...</div>");

        var d = $("#reseller_department").val();
        var e = $("#reseller_country").val();

        $.ajax({
            url: "/work/", 
            dataType: "html", 
            type: "POST",
            data: {
                "digwp_d" : d,
                "digwp_e" : e
            },

            success: function(data) {
                $("#archive-pot").html(data);
                $("#archive-wrapper").animate({
                    height: $("#archives-table tr").length * 50
                });
            }
        });
    });


    // получение всех значений опций страны реселлера 
    var values = [];
    var sel = document.getElementById('reseller_country');
    for (var i=0, n=sel.options.length;i<n;i++) {
        if (sel.options[i].value) 
        values.push(sel.options[i].value);
    }
    var jupe=""" + values.join('","') + '"';
    var dataOptionCountry = values;
    dataOptionCountry.pop();
    // console.log(dataOptionCountry);

    $("#reseller_country").change(function () {
        $("#reseller_department").prop("disabled", !(dataOptionCountry.indexOf(this.value) !== -1));
    });
});

template-reseller-getter.php

<?php
    $rd = $_POST['digwp_d'];
    $rc = $_POST['digwp_e'];
    $querystring = "cat=$rc&cat=$rd&posts_per_page=-1";
    query_posts($querystring); 
?>

<?php if (($rc == '-1') && ($rd == '-1')) { ?>
    <table id="archives-table" class="table">
        <tr>
            <td style="text-align: center; font-size: 15px; padding: 5px;"><?php _e("Пожалуйста, выберите выше.", "nalys-plugin") ?></td>
        </tr>
    </table>
<?php } else { ?>
    <div id="archives-table">
         <?php    
            $custom_args_empty_one = array(
                'post_type' => 'reseller',
                'tax_query' => array(
                    'relation' => 'OR',
                    array(
                        'taxonomy' => 'reseller-country',
                        'field'    => 'slug',
                        'terms'    => $rc,
                    ),
                    array(
                        'taxonomy' => 'reseller-department',
                        'field'    => 'slug',
                        'terms'    => $rd
                    )
                )
            );

            $custom_args = array(
                'post_type' => 'reseller',
                'tax_query' => array(
                    'relation' => 'AND',
                    array(
                        'taxonomy' => 'reseller-country',
                        'field'    => 'slug',
                        'terms'    => $rc,
                    ),
                    array(
                        'taxonomy' => 'reseller-department',
                        'field'    => 'slug',
                        'terms'    => $rd
                    )
                )
            );

            if ( $rc != '-1' && $rd == '-1' || $rc == '-1' && $rd != '-1' ) {
                $custom_query = new WP_Query( $custom_args_empty_one );
            } elseif ( $rc != '-1' && $rd != '-1' ){
                $custom_query = new WP_Query( $custom_args ); 
            }

            if ($custom_query->have_posts()) :
                $row = 0; 
                while ($custom_query->have_posts()) : 
                    $custom_query->the_post(); 
                    $count = $custom_query->post_count;

                    if($count==1){
                       // Отображение данных
                        echo '<div class="archives-table-reseller col-md-offset-4 col-md-4 col-sm-12 col-xs-12">';
                        the_title('<div class="reseller-title">', '</div>');
                        echo '<div class="reseller-address">'.get_post_meta($post->ID, '_address', true).'</div>'; 
                        echo '<div class="reseller-poscode">'.get_post_meta($post->ID, '_poscode', true).'</div>';
                        echo '<div class="reseller-telephone">Тел.'.get_post_meta($post->ID, '_telephone', true).'</div>';
                        echo '<div class="reseller-email"><a href="https://wordpress.stackexchange.com/questions/237816/mailto:".get_post_meta($post->ID, '_email', true).'">'.get_post_meta($post->ID, '_email', true).'</a></div>';
                        echo '<div class="reseller-email"><a href="http://'.get_post_meta($post->ID, '_website', true).'" target="_blank">'.get_post_meta($post->ID, '_website', true).'</a></div>';
                        echo "</div>";
                    }else{
                        // Отображение данных
                        echo '<div class="archives-table-reseller col-md-4 col-sm-12 col-xs-12">';
                        the_title('<div class="reseller-title">', '</div>');
                        echo '<div class="reseller-address">'.get_post_meta($post->ID, '_address', true).'</div>'; 
                        echo '<div class="reseller-poscode">'.get_post_meta($post->ID, '_poscode', true).'</div>'; 
                        echo '<div class="reseller-telephone">Тел.'.get_post_meta($post->ID, '_telephone', true).'</div>';
                        echo '<div class="reseller-email"><a href="https://wordpress.stackexchange.com/questions/237816/mailto:".get_post_meta($post->ID, '_email', true).'">'.get_post_meta($post->ID, '_email', true).'</a></div>';
                        echo '<div class="reseller-email"><a href="http://'.get_post_meta($post->ID, '_website', true).'" target="_blank">'.get_post_meta($post->ID, '_website', true).'</a></div>';
                        echo "</div>";
                    }


            endwhile; else:
                echo "Ничего не найдено.";
            endif; 
        ?>
    </div>
<?php } ?>

Я вижу, что ваша проблема имеет что-то общее с ошибкой в теме: Как фильтровать данные постов с помощью AJAX на странице?
Вы можете прочитать и найти решение для вашего случая.

Вы используете неправильный подход, чтобы использовать ajax в wp, вы должны следовать трем шагам.

1- Подключите js-файл, где вы делаете вызов ajax, например, пусть вызов ajax будет внутри main.js

//Добавьте это действие в ваш function.php темы или плагина.
add_action('wp_enqueue_scripts', 'enqueue_frontend');
//ИЛИ в случае вызова admin ajax
add_action('admin_enqueue_scripts', 'enqueue_frontend');

function enqueue_frontend(){
wp_enqueue_script('main-js', 'path_to_js_file' ,array('js-dependency1','js-dependency2'),'1.0', false);
//Передайте параметры в js файл, например, url вызова ajax
wp_localize_script( 'main-js', 'parameters',['ajax_url'=> admin_url('admin-ajax.php')]);
}

2- Напишите ваш вызов Ajax

               $.ajax( {
                    type: 'POST',
                    url:  parameters.ajax_url,
                    data:{
                        'action':'action_name', //Имя действия вызова Ajax
                        'param1': 'value1',
                        'param2': 'value2'
                    },
                    dataType: "json",
                  
                    success: function (json) {
                        var value1 = json.param1;
                    },
                    error : function(jqXHR, exception){
                        var msg = '';
                        if (jqXHR.status === 0) {
                            msg = 'Не подключено.\n Проверьте сеть.';
                        } else if (jqXHR.status == 404) {
                            msg = 'Запрашиваемая страница не найдена. [404]';
                        } else if (jqXHR.status == 500) {
                            msg = 'Ошибка сервера [500].';
                        } else if (exception === 'parsererror') {
                            msg = 'Не удалось разобрать запрашиваемый JSON.';
                        } else if (exception === 'timeout') {
                            msg = 'Ошибка по времени.';
                        } else if (exception === 'abort') {
                            msg = 'Запрос Ajax был прерван.';
                        } else {
                            msg = 'Неизвестная ошибка.\n' + jqXHR.responseText;
                        }
                        console.log(msg);
                    }

                } );

3- Перехватите вызов Ajax

add_action( 'wp_ajax_nopriv_action_name', 'callback_ajax' ));//то же имя действия после префикса wp_ajax_

function callback_ajax(){
  //Здесь вы можете захватить значения постов
  $value1 = $_POST['param1'];
  // Выполните вашу логику 

  //Убедитесь, что возвращаете json и завершаете с die(), чтобы вызов ajax работал
  echo json_encode(array('param1'=>'value1'));//передайте все необходимые данные здесь и используйте их в main.js
  wp_die();
}

Примечание: В случае вызова ajax на бэкенде используйте префикс wp_ajax вместо wp_ajax_nopriv_

Ответ или решение

Чтобы фильтровать пользовательские данные поста с помощью AJAX в WordPress, необходимо следовать четкой процедуре, которая включает в себя несколько ключевых шагов: настройку сценариев, обработку запросов и вывод данных. В данной статье мы рассмотрим, как определить проблему с фильтрацией данных для вашей пользовательской таксономии "Реселлеры", а также предложим структуру для решения возникшей проблемы.

Шаг 1: Подключение JavaScript файла

Для начала, вы должны правильно подключить ваш JavaScript файл, в котором будет находиться AJAX вызов. Также мы передадим URL для AJAX запроса через функцию wp_localize_script.

Добавьте следующий код в ваш functions.php:

function enqueue_frontend_scripts() {
    wp_enqueue_script('ajax-filter', get_template_directory_uri() . '/js/your-script.js', array('jquery'), null, true);
    wp_localize_script('ajax-filter', 'ajax_params', array('ajax_url' => admin_url('admin-ajax.php')));
}

add_action('wp_enqueue_scripts', 'enqueue_frontend_scripts');

Шаг 2: Создание AJAX запроса

Теперь вам необходимо создать AJAX запрос в вашем JavaScript файле. Скорректируйте ваш код следующим образом:

jQuery(document).ready(function($) {
    $("#archive-browser select").change(function() {
        var department = $("#reseller_department").val();
        var country = $("#reseller_country").val();

        $.ajax({
            type: 'POST',
            url: ajax_params.ajax_url,
            data: {
                action: 'filter_resellers',
                department: department,
                country: country
            },
            beforeSend: function() {
                $("#archive-pot").html('<div style="text-align: center; padding: 30px;">Loading...</div>');
            },
            success: function(response) {
                $("#archive-pot").html(response);
            },
            error: function(jqXHR, textStatus, errorThrown) {
                console.log(textStatus, errorThrown);
            }
        });
    });
});

Шаг 3: Обработка AJAX запроса

Теперь, когда AJAX запрос готов, нужно создать обработчик в вашем functions.php, который будет обрабатывать запрос и возвращать данные:

add_action('wp_ajax_filter_resellers', 'filter_resellers_callback');
add_action('wp_ajax_nopriv_filter_resellers', 'filter_resellers_callback');

function filter_resellers_callback() {
    $department = isset($_POST['department']) ? $_POST['department'] : '';
    $country = isset($_POST['country']) ? $_POST['country'] : '';

    $args = array(
        'post_type' => 'reseller',
        'tax_query' => array(
            'relation' => 'AND',
            array(
                'taxonomy' => 'reseller-country',
                'field' => 'slug',
                'terms' => $country,
            ),
            array(
                'taxonomy' => 'reseller-department',
                'field' => 'slug',
                'terms' => $department,
            ),
        ),
    );

    $query = new WP_Query($args);

    if ($query->have_posts()) {
        while ($query->have_posts()) : $query->the_post();
            // Здесь ваш код для вывода данных поста
        endwhile;
    } else {
        echo "Ничего не найдено.";
    }

    wp_die();
}

Шаг 4: Скрытие дропдауна "Департамент"

Теперь, чтобы скрыть дропдаун "Департамент", если выбранная страна не имеет соответствующих департаментов, вы можете изменить ваш JavaScript:

$("#reseller_country").change(function () {
    var hasDepartments = dataOptionCountry.indexOf(this.value) !== -1;
    $("#reseller_department").prop("disabled", !hasDepartments);
    if (!hasDepartments) {
        $("#reseller_department").val('-1'); // Сбросить выбранное значение
    }
});

Заключение

Эти шаги показывают, как правильно реализовать фильтрацию пользовательских данных постов с использованием AJAX в WordPress. Убедитесь, что вы проверили, правильно ли установлены все таксономии и что запросы возвращают ожидаемые результаты. Если вы столкнётесь с дополнительными проблемами, проверьте консоль браузера на наличие сообщений об ошибках, так как они могут указать на проблемы в запросе или в обработке данных.

Оцените материал
Добавить комментарий

Капча загружается...