I am trying to build a timetable to display classes by time. I have a taxonomy of Day, which I am looping over to create a column for each day of the week. In side the column is a WP_Query which filters using the day taxonomy and meta_key
classes_entry_start_time
to orderby meta_value_num
. The timetable is then filtered using ajax.
$calendarDays = get_terms([
'taxonomy' => 'calendar-day',
'hide_empty' => false,
]);
$calendarDays_count = count( $calendarDays );
if ( $calendarDays_count > 0 && is_array( $calendarDays ) ) {
echo '<div class="classes-calendar">';
// Display filter
$classesFilter = array_map(function($class) {
return [
'value' => $class->term_id,
'title' => $class->name
];
}, get_terms('calendar-class-type'));
get_part('classes-filter', [
'id' => 'classes-filter',
'title' => 'All',
'items' => array_merge( $classesFilter )
]);
// Loop over day taxonomy
echo '<div id="response" class="container classes-wrap">';
foreach ( $calendarDays as $day ) {
echo '<div class="classes-col">';
echo '<strong>' . $day->name . '</strong>';
$args = array(
'post_type' => 'calendar',
'meta_key' => 'classes_entry_start_time',
'orderby' => 'meta_value_num',
'order' => 'ASC',
'posts_per_page' => '-1',
'tax_query' => array(
array(
'taxonomy' => 'calendar-day',
'field' => 'id',
'terms' => $day->term_id,
)
),
);
// echo '<div id="response" class="container">';
echo '<ul id="" class="response">';
$query = new WP_Query( $args );
if( $query->have_posts() ):
while( $query->have_posts() ):
$query->the_post();
get_part('classes-item', ['classesEntry' => get_field('classes_entry')]);
endwhile;
else:
echo 'No data to show';
endif;
wp_reset_query();
echo '</ul>';
// echo '</div>'; // END response
echo '</div>'; // END classes-col
} // END foreach
echo '</div>'; // END response
echo '<div class="section container center">';
echo '<a href="#" class="btn">Book class</a>';
echo '</div>';
echo '</div>'; // END classes-calendar
} // END if
The main query works as expected and the ajax request works as expected to return the correct values, but only when I am not using a foreach
loop in the ajax handler.
Below is the ajax handler function which is getting the correct posts based on the chosen filter, but it displays the same result for all options.
The foreach loop is based on a taxonomy which displays columns representing each day of the week: Monday – Sunday.
For example, it's returning:
Monday: Post one Tuesday: Post one Wednesday: Post one ...
But really it should be returning:
Monday: Post one, Post two Tuesday: Post three Wednesday: Post four ...
Whats the best way to filter WP_Query based on the two taxonomies and also display the query inside foreach loops so that the filter only shows posts assigned to the filter types and displays them in the correct day column, without it updating all columns of the foreach
loop?
Is using a foreach loop wrong for what I am trying to achieve?
Filtering query where the issue are
add_action('wp_ajax_classfilter', 'load_posts_by_ajax_callback');
add_action('wp_ajax_nopriv_classfilter', 'load_posts_by_ajax_callback');
function load_posts_by_ajax_callback() {
check_ajax_referer('load_more_posts', 'security');
$calendarDays = get_terms([
'taxonomy' => 'calendar-day',
'hide_empty' => false,
]);
foreach($calendarDays as $day) {
$args = array(
'post_type' => 'calendar',
'post_status' => 'publish',
'meta_key' => 'classes_entry_start_time',
'orderby' => 'meta_value_num',
'order' => 'ASC',
'tax_query' => array(
array(
'taxonomy' => 'calendar-day',
'field' => 'id',
'terms' => $day->term_id
)
)
);
if( isset( $_POST['theClass'] ) )
$args['tax_query'] = array(
array(
'taxonomy' => 'calendar-class-type',
'field' => 'id',
'terms' => $_POST['theClass']
)
);
$loop = new WP_Query($args);
if($loop->have_posts()) {
echo '<div class="classes-col">';
echo '<strong>' . $day->name . '</strong>';
echo '<ul>';
while($loop->have_posts()) : $loop->the_post();
get_part('classes-item', ['classesEntry' => get_field('classes_entry')]);
endwhile;
wp_reset_postdata();
echo '</ul>';
echo '</div>';
}
else {
echo '<div class="classes-col">';
echo '<strong>' . $day->name . '</strong>';
echo '</div>';
}
}
wp_die();
}
If anyone can point me in the right direction that would be great. I've spent days trying different options with no luck! The only way I can get it to work as it should is by removing the foreach loop completely which I can't do as I need the columns of the week.
For reference, here is the ajax request
import axios from 'axios';
const classesFilter = () => {
const el = document.querySelector('#classes-filter');
if (el) {
el.addEventListener('change', e => {
e.preventDefault();
const formData = new FormData(el);
formData.append('action', 'classfilter');
formData.append('security', WP.security);
// Axios POST request
axios({
method: 'POST',
url: WP.ajax,
data: formData,
})
// handle success
.then(function (response) {
console.log(response.data);
console.log(response.status);
document.getElementById("response").innerHTML = response.data;
// document.getElementsByClassName("response").innerHTML = response.data;
},
(error) => {
console.log(error);
});
});
}
};
export default classesFilter;```