Filter posts with ajax form and checkboxes

I have a loop for my Custom Posts Type workshop filtered with two custom taxonomies group and teacher on the same page. The Ajax filter works perfectly.

Each links of the filter works with a <input type="checkbox">, for both taxonomies lists. When the user selects one or multiple terms in the filter, then unselects all of them, the filter returns “No posts found” because nothing is selected.

What I would like to do is, when the user unselects all the terms in the filter it displays all the posts of my Custom Posts Type.

The PHP code of the filter for the frontend:

<form action="<?php echo site_url() ?>/wp-admin/admin-ajax.php" method="POST" id="filter">

  <div>
  <?php
    if( $groups = get_terms( array( 'taxonomy' => 'group' ) ) ) :
      echo '<ul class="groups-list">';
      foreach( $groups as $group ) :
         echo '<input type="checkbox" class="" id="group_' . $group->term_id . '" name="group_' . $group->term_id . '" /><label for="group_' . $group->term_id . '">' . $group->name . '</label>';
       endforeach;
       echo '</ul>';
     endif;
   ?>
   </div>

   <div>
   <?php
     if( $teachers = get_terms( array( 'taxonomy' => 'teacher' ) ) ) :
       echo '<ul class="teachers-list">';
       foreach( $teachers as $teacher ) :
         echo '<input type="checkbox" class="" id="teacher_' . $teacher->term_id . '" name="teacher_' . $teacher->term_id . '" /><label for="teacher_' . $teacher->term_id . '">' . $teacher->name . '</label>';
                             
        endforeach;
        echo '</ul>';
     endif;
   ?>
   </div>

   <input type="hidden" name="action" value="myfilter">
</form>

The PHP code for the AJAX filter in functions.php:

function mysite_filter_function(){

//groups checkboxes
if( $groups = get_terms( array( 'taxonomy' => 'group' ) ) ) :
$groups_terms = array();

foreach( $groups as $group ) {
    if( isset( $_POST['group_' . $group->term_id ] ) && $_POST['group_' . $group->term_id] == 'on' )
         $groups_terms[] = $group->slug;
}
endif;

//teachers checkboxes
if( $teachers = get_terms( array( 'taxonomy' => 'teacher' ) ) ) :
$teachers_terms = array();

foreach( $teachers as $teacher ) {
    if( isset( $_POST['teacher_' . $teacher->term_id ] ) && $_POST['teacher_' . $teacher->term_id] == 'on' )
         $teachers_terms[] = $teacher->slug;
}
endif;



if (empty($groups_terms) || empty($teachers_terms) ) {
 $relation = 'OR';
}else{
 $relation = 'AND';
}

$args = array(
    'orderby' => 'date',
    'post_type' => 'workshop',
    'posts_per_page' => -1,
    'tax_query' => array(
        'relation' => $relation,
        array(
            'taxonomy' => 'group',
            'field' => 'slug',
            'terms' => $groups_terms
        ),
        array(
            'taxonomy' => 'teacher',
            'field' => 'slug',
            'terms' => $teachers_terms
        )
    )
);

$query = new WP_Query( $args );

if( $query->have_posts() ) :
    while( $query->have_posts() ): $query->the_post();
        echo '<h2>' . $query->post->post_title . '</h2>';

    endwhile;
    wp_reset_postdata();
else :
    echo 'No posts found';
endif;

die();
}
add_action('wp_ajax_myfilter', 'mysite_filter_function');
add_action('wp_ajax_nopriv_myfilter', 'mysite_filter_function');

The JS code:

$('#filter').change(function(){
    var filter = $('#filter');
    $.ajax({
        url:filter.attr('action'),
        data:filter.serialize(),
        type:filter.attr('method'),
        beforeSend:function(xhr){
            //filter.find('button').text('Processing...');
        },
        success:function(data){
            //filter.find('button').text('Filter');
            $('.loop-archive-workshop').html(data);
        }
    });
    return false;
});

Thanks!

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

What I would like to do is, when the user unselects all the terms in the filter it displays all the posts of my Custom Posts Type.

In that case, then make the tax query optional:

// In mysite_filter_function(), define $args like so:

$tax_query = array( 'relation' => 'AND' );

if ( ! empty( $groups_terms ) ) {
    $tax_query[] = array(
        'taxonomy' => 'group',
        'field'    => 'slug',
        'terms'    => $groups_terms,
    );
}

if ( ! empty( $teachers_terms ) ) {
    $tax_query[] = array(
        'taxonomy' => 'teacher',
        'field'    => 'slug',
        'terms'    => $teachers_terms,
    );
}

$args = array(
    'orderby'        => 'date',
    'post_type'      => 'workshop',
    'posts_per_page' => -1,
    'tax_query'      => $tax_query,
);


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x