I have a section for "tours" in my page.
The tours have 2 filters (select inputs). "destino" and "duracion" (location and duration)
So far I made one of the filter work with ajax, and update the "#result" id with the new tours once you select a "destino".
But i also want to update the "duracion" select with the new options (based on the destino selected).
Problem is, i have no idea how to execute two actions and have the response on two different places.
Html part: (here I have both actions, its only executing the last one)
<form class="filtros righter" action="**********/wp-admin/admin-ajax.php" method="POST" id="filtro">
<input type="hidden" name="action" value="filtertoursajax">
<input type="hidden" name="action" value="filterduracionajax">
<input type="hidden" name="filtrodestino" value="salar-de-uyuni">
<div class="select-holder">
<label class="">Categoría</label>
<select name="categoriafilter" id="categoriafilter">
<option disabled="" selected="" value="0"> </option>
<option value="0">Todas las categorías</option>
<option value="11">Clásicos</option>
<option value="33">Elite</option>
</select>
</div>
<div class="select-holder">
<label>Duración del viaje</label>
<select name="duracionfilter" id="resultselect">
<option disabled="" selected="" value="0"> </option>
<option value="0">Todas las duraciones</option>
</select>
</div>
</form>
Js part:
<script>
jQuery(function myFunction(){
$('#filtro').change(function(){
var filter = $('#filtro');
$.ajax({
url:filter.attr('action'),
data:filter.serialize(), // form data
type:filter.attr('method'), // POST
beforeSend:function(xhr, data){
filter.find('button').text('Processing...'); // changing the button label
},
success:function(data){
filter.find('button').text('Apply filter'); // changing the button label back
$('#response').html(data); // insert data
console.log(data);
},
error: function(req, err){ console.log(err);
}
});
return false;
});
});
PHP action 1:
add_action('wp_ajax_filtertoursajax', 'filtertoursajax');
add_action('wp_ajax_nopriv_filtertoursajax', 'filtertoursajax');
function filtertoursajax(){
$args = array(
'post_type' => 'tours',
'orderby' => 'menu_order',
'order' => 'ASC',
'post_per_page' => -1,
);
if( isset($_POST['filtrodestino']) && $_POST['filtrodestino'] ) {
// for taxonomies / categoria
if( isset( $_POST['filtrodestino'] ) ) {
$args['tax_query'][] =
array(
'taxonomy' => 'destino',
'field' => 'slug',
'terms' => $_POST['filtrodestino']
);
}
}
if( isset($_POST['categoriafilter']) && $_POST['categoriafilter'] ) {
// for taxonomies / categoria
$args['tax_query'][] =
array(
'taxonomy' => 'categoria',
'field' => 'id',
'terms' => $_POST['categoriafilter']
);
}
$query = new WP_Query( $args );
if( $query->have_posts() ) :
print_r($args);
while( $query->have_posts() ): $query->the_post();
$postid = $query->post->ID;
$taxonomy = 'destino';
$terms = get_the_terms( get_the_ID(), $taxonomy );
if ( $terms && ! is_wp_error( $terms ) ) :
$term_links = array();
foreach ( $terms as $term ) {
$term_links[] = '<a href="' . esc_attr( get_term_link( $term->slug, $taxonomy ) ) . '">' . __( $term->name ) . '</a>';
}
$all_terms = join( ', ', $term_links );
$destinos = '<span class="terms-' . esc_attr( $term->slug ) . '">' . __( $all_terms ) . '</span>';
endif;
?>
<div class="box">
<div class="box__image flexer">
<?php echo wp_get_attachment_image( get_field( "foto_portada", $postid ), array('276', '180'), "", array( "class" => "img-responsive" ) ); ?>
</div>
<div class="box__content pz-1">
<span class="placeholder mb-1"><?php echo $destinos; ?></span>
<h6 class="long-title mb-2"><?php echo $query->post->post_title; ?></h6>
<div class="icon-btn"><?php $path = get_template_directory_uri().'/images/plane-icon.svg'; echo file_get_contents($path); ?>Duración: <?php echo get_field( "duracion_texto", $postid ); ?></div>
</div>
<a href="<?php echo the_permalink(); ?>" class="text-btn pl-1">Ver ficha<?php $path = get_template_directory_uri().'/images/arrow-btn.svg'; echo file_get_contents($path); ?></a>
</div>
<?php endwhile;
wp_reset_postdata();
else:
echo 'Sin resultados';
print_r($args);
endif;
die();
}
PHP action 2:
add_action('wp_ajax_filterduracionajax', 'filterduracionajax'); //
add_action('wp_ajax_nopriv_filterduracionajax', 'filterduracionajax');
function filterduracionajax(){
if( $args = array(
'posts_per_page' => -1,
'hide_empty' => 1,
'post_type' => 'tours',
'meta_key' => 'dias',
'orderby' => 'meta_value',
'order' => 'ASC',
) ) :
// create $args['tax_query'] array if one of the following fields is filled
if( isset($_POST['filtrodestino']) && $_POST['filtrodestino'] ) {
// for taxonomies / categoria
if( isset( $_POST['filtrodestino'] ) ) {
$args['tax_query'][] =
array(
'taxonomy' => 'destino',
'field' => 'slug',
'terms' => $_POST['filtrodestino']
);
}
}
// create $args['tax_query'] array if one of the following fields is filled
if( isset($_POST['categoriafilter']) && $_POST['categoriafilter'] ) {
// for taxonomies / categoria
$args['tax_query'][] =
array(
'taxonomy' => 'categoria',
'field' => 'id',
'terms' => $_POST['categoriafilter']
);
}
// query
$the_query = new WP_Query( $args );
if( $the_query->have_posts() ): ?>
<div class="select-holder">
<label>Duración del viaje</label>
<select name="duracionfilter" id="resultselect">
<option disabled="" selected="" value="0"> </option>
<option value="0" >Todas las duraciones</option>
<?php $unique_dias = array();
while( $the_query->have_posts() ) : $the_query->the_post(); ?>
<?php $dias = get_field('dias');
if( ! in_array( $dias, $unique_dias ) ) :
$unique_dias[] = $dias; ?>
<?php endif;
endwhile;
natsort($unique_dias);
foreach ( $unique_dias as $duraciones ) :
echo '<option value="'.$duraciones.'">'.$duraciones.'</option>';
endforeach;
?>
</select></div>
<?php endif;
endif;
die();
}
Im very new with Ajax, this code is made by pieces of tutorials i found. The code is mostly made following this tutorial: https://rudrastyh.com/wordpress/ajax-post-filters.html
I just need both php actions to execute on "form" change and update the "tours" on #response div and also update the select input with #resultselect id.
Thanks!
Thanks to @lewis4you I’m able to get the data on the 2 divs at the same time. But i fail to understand how to execute both actions at the same time, but with different actions from functions.php
This
add_action('wp_ajax_filterduracionajax', 'filterduracionajax'); //
add_action('wp_ajax_nopriv_filterduracionajax', 'filterduracionajax');
has to return data to #resultselect
and
add_action('wp_ajax_filtertoursajax', 'filtertoursajax');
add_action('wp_ajax_nopriv_filtertoursajax', 'filtertoursajax');
has to return data to #response div
My main problem is that i dont know how to select the action i want to execute in
$.ajax({
url:filter.attr('action'),
data:filter.serialize(), // form data
type:filter.attr('method'), // POST
2
Answers
I didn’t read the question fully but I think you want something like this:
The scenario where you send the data to the same controller from one $.ajax call:
in controller you have to store the data into array with keys so you can access it later in ajax success() function
then in your $ajax in
success:function(data)
you can access that data withHave you thought of using JS’s Fetch API instead of jQuery’s Ajax? Fetch returns a promise then it can execute a chain of .then() blocks where you can put another fetch() to your PHP url.
See an example here:
using a fetch inside another fetch in javascript