Last active
March 13, 2023 18:53
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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(); ?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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