First I'd recommend you to make sure $meal_type = get_field('meal_type');
returns array of strings - to do this you can simply call var_dumb($meal_type)
after getting this field value. So for example if you've used a Repeater field for meal_type, you'll see array of arrays and not array of strings.
Also It's kind of strange thing with ACF, but when you are in a custom WP_Query loop, and even you've done it well via $meal->the_post()
to setup global $post
object it may sometimes ignore the one you've just set, so here's a more bulletproof way of calling get_field()
<?php if( $meals->have_posts() ) :
$meal_posts = $meals->get_posts();
foreach( $meal_posts as $meal_post) :
$meal_type = get_field('meal_type', $meal_post);
if ( $meal_type && in_array('emergency', $meal_type)): ?>
<div class="text-center p-2 meal-size-posts">
<h4><?php the_field('meal_name', $meal_post); ?></h4>
<img src="<?php echo get_field('meal_icon', $meal_post); ?>" class="meal-icon">
<p class="meal-description"><?php the_field('meal_description', $meal_post); ?></p>
<h4><?php the_field('meal_calories', $meal_post); ?> calories</h4>
</div>
<?php endif; ?>
<?php endforeach; ?>
<?php endif; ?>
To make sure it gets data from right place you can pass in a second argument as $post object which you'd like to use to get ACF data for.
Also in case you want it to make a more general purpose code, working for all meal types.
Change markup of meal types listing to
<div class="col-6 col-md-3">
<a href="#emergency" class="load-meal-by-type">
<img width="75" height="auto" alt="Emergency" id="emergency-icon" data-src="https://blog.unicornpoint.net/wp/wp-content/uploads/2020/02/panic.png" class="meal-icon lazyloaded" src="https://blog.unicornpoint.net/wp/wp-content/uploads/2020/02/panic.png" loading="lazy">
<noscript>
<img src="https://blog.unicornpoint.net/wp/wp-content/uploads/2020/02/panic.png" width="75" height="auto" alt="Emergency" class="meal-icon" id="emergency-icon">
</noscript>
<span class="meal-icon-caption"> Emergency</span>
</a>
</div>
Change JS code to
<script>
jQuery(document).ready(function($){
$('a.load-meal-by-type').click(function(event){
event.preventDefault(); // to prevent browser from trying to navigate via #link
var $btn = $(this); // quick way to get current clicked link inside handler function
var mealType = $btn.attr('href'); // we'll pass meal type as variable to ajax
mealType = mealType.replace('#', ''); // remove # as we don't need it- we keep it in href originally to make link valid and at the same time - if you'd like to have a step further you can make a thing called deeplinking, being able to have shared link which will load exact content as you would click on a link.
$.ajax({
method: 'GET',
url: 'my-url.php',
data: {
mealType: mealType // we pass in our mealType string to php as GET parameter.
}
}).done(function(data){
$("#meal-results").html(data);
});
});
});
</script>
Then in PHP we will get this mealType
variable
$requested_meal_type = sanitize_text_field( isset( $_GET['mealType'] ) ? $_GET['mealType'] : '' );
It's important to sanitize whatever user input you are reading from requests, otherwise there can be a security breach.
So having this variable read we can change condition to if ( $meal_type && in_array($requested_meal_type , $meal_type))
to be able to handle different meal types.
Also you can check for case if mealType
$_GET var is empty and show - no meals found message
like
if ( empty( $requested_meal_type ) ) { echo 'no meals found' } else { // do wp query and other logic as it should be. }
/// UPD
The thing i consider might happen is this, you are calling my-url.php
i've thought it's just example and missed it. In Wordpress when you need to handle something generated via php through ajax, works a bit differently then just creating some file my-url.php
in site's document root.
Wordpress way is of calling ajax is:
call /wp-admin/admin-ajax.php
instead of your custom php file, from js in ajax,
pass in a action
variable in to js, this action name will be an action we define in PHP to handle this type of ajax requests. So ajax part of JS code will turn into.
$.ajax({
method: 'GET',
url: '/wp-admin/admin-ajax.php', // we send all WP ajax requests to this file, it will load all WP's files, plugins. It's WP Ajax approach.
data: {
action: 'load_meals', // you can name it whatever just use the same in PHP binding ajax action.
mealType: mealType // we pass in our mealType string to php as GET parameter.
}
}).done(function(data){
$("#meal-results").html(data);
});
in your theme's functions.php
we'll create php ajax handler which will generate your desired html markup and send it back to js. So part of php code we put into functions.php
will look like this.
// this function will render our html and send it back to js, upon ajax request.
function my_ajax_load_meals() {
$requested_meal_type = sanitize_text_field( isset( $_GET['mealType'] ) ? $_GET['mealType'] : '' );
echo 'You have reached the file.'; ?>
?>
<div class="d-inline-flex flex-wrap text-center p-2">
<?php
$args = array( 'post_type' => 'meal' );
$meals = new WP_Query( $args );
if ( $meals->have_posts() ) :
$meals_posts = $meals->get_posts();
foreach ( $meals_posts as $meal_post ) :
$meal_type = get_field( 'meal_type', $meal_post );
if ( $meal_type && in_array( $requested_meal_type, $meal_type ) ): ?>
<div class="text-center p-2 meal-size-posts">
<h4><?php the_field( 'meal_name', $meal_post ); ?></h4>
<img src="<?php echo get_field( 'meal_icon', $meal_post ); ?>" class="meal-icon">
<p class="meal-description"><?php the_field( 'meal_description', $meal_post ); ?></p>
<h4><?php the_field( 'meal_calories', $meal_post ); ?> calories</h4>
</div>
<?php endif; ?>
<?php endforeach; ?>
<?php endif; ?>
</div>
<?php
exit(); // important to exit to close output and let js know it has loaded everything already.
}
// this is where we bind our function to `load_meals` action name.
// the one with `_nopriv` prefix in wp action name is for not logged in users, and without it for logged in users.
add_action('wp_ajax_load_meals', 'my_ajax_load_meals');
add_action('wp_ajax_nopriv_load_meals', 'my_ajax_load_meals');