Categories
CMS Mastering Development Wordpress

WP_Query inside foreach loop returning same value for all options when filtered using ajax

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;```


Leave a Reply

Your email address will not be published. Required fields are marked *