So I’ve been working on this for hours now. About 6 of them with no breaks and I cannot understand why this isn’t working.
So I have this form:
<div id="wp-ajax-filter-search" class="full"> <form action="" method="get"> <div class="flex filters-grid"> <div id="#sortBy" class="flex filters-dropdown"> <p class="filters-title"> Sort By </p> <div class="filters-options"> <input class="wp-drop-filter-item" type="radio" id="alphabetically" value="title" name="sort_filter"> <label for="alphabetically"> Alphabetically </label> <input class="wp-drop-filter-item" type="radio" id="datenew2old" value="ASC" name="sort_filter"> <label for="datenew2old"> Date Added (New to Old) </label> <input class="wp-drop-filter-item" type="radio" id="dateold2new" value="DESC" name="sort_filter"> <label for="dateold2new"> Date Added (Old to New) </label> </div> </div> <div id="#countries" class="flex filters-dropdown"> <p class="filters-title"> Country </p> <?php // set up a new query for each category, pulling in related posts. $destinations = new WP_Query( array( 'showposts' => -1, 'post_type' => 'destinations', 'post_status' => 'publish', 'order_by' => 'title', 'order' => 'ASC' ) ); if ($destinations->have_posts()): ?> <div class="filters-options"> <input class="wp-drop-filter-item <?php echo $country_slug ?>" type="radio" id="any" value="any" name="country_filter"> <label for="any"> Any </label> <?php while ($destinations->have_posts()) : $destinations->the_post(); global $post; $post_slug = $post->post_name;?> <input class="wp-drop-filter-item country-option" type="radio" id="<?php echo $post_slug ?>" value="<?php echo $post->ID ?>" name="country_filter" > <label for="<?php echo $post_slug; ?>"> <?php echo get_the_title(); ?> </label> <?php endwhile; ?> <?php // Reset things, for good measure $destinations = null; wp_reset_postdata(); ?> </div> <?php endif; ?> </div> <div id="#regions" class="flex filters-dropdown"> <p class="filters-title"> Region <span class="extra">(Choose Country First)</span> </p> <?php // set up a new query for each category, pulling in related posts. $regions = new WP_Query( array( 'showposts' => -1, 'post_type' => 'regions', 'post_status' => 'publish', 'order_by' => 'title', 'order' => 'ASC' ) ); if ($regions->have_posts()): ?> <div class="filters-options"> <input class="wp-drop-filter-item" type="radio" id="any-region" value="any" name="region_filter"> <label class="region-option" for="any-region"> Any </label> <?php while ($regions->have_posts()) : $regions->the_post(); global $post; $post_slug = $post->post_name; $country = get_field( "country", $post ); $country_slug = get_post_field( 'post_name', $country ); ?> <input class="wp-drop-filter-item" type="radio" id="<?php echo $post_slug ?>" value="<?php echo $post->ID ?>" name="region_filter"> <label class="region-option <?php echo $country_slug ?>" for="<?php echo $post_slug; ?>"> <?php echo get_the_title(); ?> </label> <?php endwhile; ?> <?php // Reset things, for good measure $regions = null; wp_reset_postdata(); ?> </div> <?php endif; ?> </div> </div> </form> <ul id="ajax_filter_search_results" class="destinations grid"></ul> </div>
Whenever you change one of the radio buttons, AJAX is triggered using this JS code:
var wpmafs = $("#wp-ajax-filter-search"); var wpmafsForm = wpmafs.find("form"); $(".wp-drop-filter-item").on("change",function(e){ e.preventDefault(); var sort_filter = $("input[name='sort_filter']:checked").val(); var country_filter = $("input[name='country_filter']:checked").val(); var region_filter = $("input[name='region_filter']:checked").val(); var data = { action : "wp_ajax_filter_search", sort_filter : sort_filter, country_filter : country_filter, region_filter : region_filter }; console.log(data); $.ajax({ url : ajax_url, data : data, success : function(response) { grid = $( "#ajax_filter_search_results" ); wpmafs.find(grid).empty(); if(response) { for(var i = 0 ; i < response.length ; i++) { var html = '<a class="grid-item destination" href="' + response[i].permalink + '">'; html += '<p class="grid-item-title">' + response[i].title + '</p>'; html += '<ul class="features">'; var features = response[i].features; for(var k = 0 ; k < features.length ; k++){ if(k > 3) break; html += '<li> <img width="8" height="8" src="/wp-content/uploads/2022/03/golf-escapes-sussex-uk-packages-benefits-copy.svg" class="attachment-medium size-medium">' + features[k]['point'] + '</li>'; } html += '</ul>'; html += '<div class="bg-img">'; html += '<img src="' + response[i].image_url + '">'; html += '</div>'; html += '</a>'; wpmafs.find(grid).append(html); } } else { var html = "<li class='no-result'>No matches found. Try a different filter.</li>"; wpmafs.find(grid).append(html); } }, error: function() { grid = $( "#ajax_filter_search_results" ); wpmafs.find(grid).empty(); var html = "<li class='no-result'>It appears we're having some technical difficulties. Please try again shortly or call us.</li>"; wpmafs.find(grid).append(html); } }); });
And here’s the AJAX function:
function wp_ajax_filter_search_callback() { header("Content-Type: application/json"); if(isset($GET['sort_filter'])) { $sortval = $GET['sort_filter']; if($sortval == 'title'){ $orderby = $sortval; $order = 'ASC'; } elseif ($sortval == 'ASC' || $sortval == 'DESC'){ $orderby = 'date'; $order = $sortval; } else { $orderby = 'title'; $order = 'ASC'; } }; if(isset($_GET['country_filter'])) { $location = $_GET['country_filter']; if ($location != 'any'){ $loc_query[] = array( 'key' => 'country', 'value' => $location, 'compare' => "IN", ); } }; if(isset($_GET['region_filter'])) { $region = $_GET['region_filter']; if ($region != 'any'){ $region_query[] = array( 'key' => 'region', 'value' => $region, 'compare' => "IN", ); } }; $meta_query = array( 'relation' => 'AND', $loc_query, $region_query, ); $args = array( 'post_type' => 'hotels', 'post_status' => 'publish', 'posts_per_page' => -1, 'orderby' => $orderby, 'order' => $order, 'meta_query' => $meta_query ); $search_query = new WP_Query( $args ); if ( $search_query->have_posts() ) { $result = array(); while ( $search_query->have_posts() ) { $search_query->the_post(); $result[] = array( "id" => get_the_ID(), "title" => get_the_title(), "permalink" => get_permalink(), "image_url" => get_the_post_thumbnail_url('', 'medium-large'), "features" => get_field('featured_offer') ); } wp_reset_query(); echo json_encode($result); } else { } wp_die(); }
I have used this code before on another website, so I know that it can work, but it’s not working in this instance.
The country_filter and region_filter radio buttons are working. When you change them the AJAX call runs, and the wp_query is actually filtered.
The problem, however, is that the sort_filter radio button won’t work for some reason.
So, to test I’ve been putting print_r("some random bit of text")
and checking the network tab in my browsers inspector to see if that text appears in the Request. Under if(isset($_GET['country_filter']))
and if(isset($_GET['region_filter']))
, the text displays. But, if I put it under if(isset($_GET['sort_filter']))
it doesn’t display.
So, clearly, the AJAX code is getting to the if(isset($_GET['sort_filter']))
line and saying “Nope, it’s not set”. But it is.
And if I use console.log() in the JS code to log the data that is being sent to the AJAX call, I can clearly see that the value of the selected sort_filter radio button is being sent:
{action: 'wp_ajax_filter_search', sort_filter: 'title', country_filter: undefined, region_filter: undefined}
The request URL in the Network tab also has that information in it, for example:
https://my.staging.url/wp-admin/admin-ajax.php?action=wp_ajax_filter_search&sort_filter=title
Despite all that, I can’t get the AJAX code to $GET the sort_filter radio button value and use it in the WP_Query.
Any help is totally appreciated. I’m going to get some shut-eye for a bit as I’ve completely burnt myself out on this but I look forward to seeing what help anyone can offer because this really is driving me up the wall and the deadline is fast approaching.
Enormous thanks in advance!
Advertisement
Answer
In your ajax callback function you have
if(isset($GET['sort_filter'])) { $sortval = $GET['sort_filter'];
and it should be
if(isset($_GET['sort_filter'])) { $sortval = $_GET['sort_filter'];
ie you are missing the _ out of both calls to $_GET