Вопрос или проблема
Я создал пользовательский тип записи с “Реселлерами”, чтобы ввести свои личные товары реселлеров. У поста “Реселлеры” есть таксономии, такие как “Страны” и “Департаменты”.
У меня возникла проблема:
При первом отображении страницы данные из таксономий моего пользовательского типа записи не загружаются. Если я нажимаю на одну из моих ссылок, данные успешно обновляются. Проблема заключается в том, что страна без назначенной категории “Департамент” (например, Германия) = результаты отображаются, но выпадающий список “Департамент” должен быть скрыт.
Может кто-нибудь сказать, где я сделал ошибку?
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. Убедитесь, что вы проверили, правильно ли установлены все таксономии и что запросы возвращают ожидаемые результаты. Если вы столкнётесь с дополнительными проблемами, проверьте консоль браузера на наличие сообщений об ошибках, так как они могут указать на проблемы в запросе или в обработке данных.