Skip to content

Instantly share code, notes, and snippets.

@laurelstreng
Last active March 13, 2023 18:53
Show Gist options
  • Save laurelstreng/d09cd6806c7d95f5139a8d2baa35cfcf to your computer and use it in GitHub Desktop.
Save laurelstreng/d09cd6806c7d95f5139a8d2baa35cfcf to your computer and use it in GitHub Desktop.
WordPress filtering content with multiple dropdowns, 1 taxonomy with different children, using ajax.
<?php
/**
* The template for displaying archive pages
*/
get_header();
global $wp_query;
?>
<form id="misha_filters" action="#">
<?php
if( $terms = get_terms( array( 'taxonomy' => 'success_stories', 'orderby' => 'name', 'child_of' => 481, ) ) ) :
echo '<select name="categoryfilter" id="categoryfilter"><option value="">Select Industry...</option>';
foreach ( $terms as $term ) :
echo '<option value="' . $term->slug . '">' . $term->name . '</option>'; // ID of the category as the value of an option
endforeach;
echo '</select>';
endif;
if( $terms = get_terms( array( 'taxonomy' => 'success_stories', 'orderby' => 'name', 'child_of' => 495, ) ) ) :
echo '<select name="topicfilter"><option value="">Select Topic...</option>';
foreach ( $terms as $term ) :
echo '<option value="' . $term->slug . '">' . $term->name . '</option>'; // ID of the category as the value of an option
endforeach;
echo '</select>';
endif;
?>
<label for="misha_number_of_results">Per page</label>
<select name="misha_number_of_results" id="misha_number_of_results">
<!--<option>--><?php //echo get_option( 'posts_per_page' ) ?><!--</option> it is from Settings > Reading -->
<option>3</option>
<option>9</option>
<option>15</option>
<option value="-1">All</option>
</select>
<button id="apply">Apply filter</button>
<input type="hidden" name="action" value="mishafilter">
</form>
<div id="misha_posts_wrap"></div>
<?php if ( $wp_query->max_num_pages > 1 ) :
echo '<div id="misha_loadmore">More posts</div>';
endif; ?>
<?php get_footer(); ?>
<?php
/**
* Enqueue Styles
*/
function my_scripts(){
// absolutely need it, because we will get $wp_query->query_vars and $wp_query->max_num_pages from it.
global $wp_query;
// when you use wp_localize_script(), do not enqueue the target script immediately
wp_register_script( 'misha_scripts', get_stylesheet_directory_uri() . '/js/script.js', array('jquery') );
// passing parameters here
// actually the <script> tag will be created and the object "misha_loadmore_params" will be inside it
wp_localize_script( 'misha_scripts', 'misha_loadmore_params', array(
'ajaxurl' => admin_url() . 'admin-ajax.php', // WordPress AJAX
'posts' => json_encode( $wp_query->query_vars ), // everything about your loop is here
'current_page' => $wp_query->query_vars['paged'] ? $wp_query->query_vars['paged'] : 1,
'max_page' => $wp_query->max_num_pages,
'first_page' => get_pagenum_link(1)
) );
wp_enqueue_script( 'misha_scripts' );
}
add_action( 'wp_enqueue_scripts', 'my_scripts' );
/**
* Load More Functionality
*/
add_action('wp_ajax_loadmorebutton', 'misha_loadmore_ajax_handler');
add_action('wp_ajax_nopriv_loadmorebutton', 'misha_loadmore_ajax_handler');
function misha_loadmore_ajax_handler(){
// prepare our arguments for the query
$params = json_decode( stripslashes( $_POST['query'] ), true ); // query_posts() takes care of the necessary sanitization
$params['paged'] = $_POST['page'] + 1; // we need next page to be loaded
$params['post_status'] = 'publish';
$params['post_type'] = 'successstories';
// it is always better to use WP_Query but not here
query_posts( $params );
if( have_posts() ) :
// run the loop
while( have_posts() ): the_post();
// look into your theme code how the posts are inserted, but you can use your own HTML of course
// do you remember? - my example is adapted for Twenty Seventeen theme
get_template_part('template-parts/content', 'single');
endwhile;
endif;
die; // here we exit the script and even no wp_reset_query() required!
}
/**
* Filtering
*/
add_action('wp_ajax_mishafilter', 'misha_filter_function');
add_action('wp_ajax_nopriv_mishafilter', 'misha_filter_function');
function misha_filter_function(){
$params = array(
'post_type' => 'successstories',
'posts_per_page' => $_POST['misha_number_of_results'], // when set to -1, it shows all posts
'orderby' => 'date',
'order' => 'DESC',
'post_status' => 'publish'
);
$relation = 'OR';
if(!empty($_POST['categoryfilter']) && isset( $_POST['topicfilter'] )) {
$relation = 'AND';
}
if( isset( $_POST['categoryfilter'] ) && isset( $_POST['topicfilter'] ) )
$params['tax_query'] = array(
'relation' => $relation,
array(
'taxonomy' => 'success_stories',
'field' => 'slug',
'terms' => $_POST['categoryfilter']
),
array(
'taxonomy' => 'success_stories',
'field' => 'slug',
'terms' => $_POST['topicfilter'],
'operator' => 'AND', //narrows results, use 'IN' to expand
),
);
query_posts( $params );
global $wp_query;
if( have_posts() ) :
ob_start(); // start buffering because we do not need to print the posts now
while( have_posts() ): the_post();
get_template_part('template-parts/content', 'single');
endwhile;
$posts_html = ob_get_contents(); // we pass the posts to variable
ob_end_clean(); // clear the buffer
else:
$posts_html = '<p>Nothing found for your criteria.</p>';
endif;
// no wp_reset_query() required
echo json_encode( array(
'posts' => json_encode( $wp_query->query_vars ),
'max_page' => $wp_query->max_num_pages,
'found_posts' => $wp_query->found_posts,
'content' => $posts_html
) );
die();
}
jQuery(function($){
/*
* Load More
*/
$('#misha_loadmore').click(function(){
$.ajax({
url : misha_loadmore_params.ajaxurl, // AJAX handler
data : {
'action': 'loadmorebutton', // the parameter for admin-ajax.php
'query': misha_loadmore_params.posts, // loop parameters passed by wp_localize_script()
'page' : misha_loadmore_params.current_page // current page
},
type : 'POST',
beforeSend : function ( xhr ) {
$('#misha_loadmore').text('Loading...'); // some type of preloader
},
success : function( posts ){
if( posts ) {
$('#misha_loadmore').text( 'More posts' );
$('#misha_posts_wrap').append( posts ); // insert new posts
misha_loadmore_params.current_page++;
if ( misha_loadmore_params.current_page == misha_loadmore_params.max_page )
$('#misha_loadmore').hide(); // if last page, HIDE the button
} else {
$('#misha_loadmore').hide(); // if no data, HIDE the button as well
}
}
});
return false;
});
/*
* Filter
*/
$('#misha_filters :input:visible').on('input', function (e) {
// $('#misha_filters').submit(function(){
$.ajax({
url : misha_loadmore_params.ajaxurl,
data : $('#misha_filters').serialize(), // form data
dataType : 'json', // this data type allows us to receive objects from the server
type : 'POST',
beforeSend : function(xhr){
$('#misha_filters').find('button').text('Filtering...');
},
success : function( data ){
// when filter applied:
// set the current page to 1
misha_loadmore_params.current_page = 1;
// set the new query parameters
misha_loadmore_params.posts = data.posts;
// set the new max page parameter
misha_loadmore_params.max_page = data.max_page;
// change the button label back
$('#misha_filters').find('button').text('Apply filter');
// insert the posts to the container
$('#misha_posts_wrap').html(data.content);
// hide load more button, if there are not enough posts for the second page
if ( data.max_page < 2 ) {
$('#misha_loadmore').hide();
} else {
$('#misha_loadmore').show();
}
},
error: function(MLHttpRequest, textStatus, errorThrown) {
$status.html(textStatus);
/*console.log(MLHttpRequest);
console.log(textStatus);
console.log(errorThrown);*/
},
});
// do not submit the form
return false;
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment