I don’t have any link or demo to show cos I’m working locally
I have news posts with different categories.
I want to show the categories as buttons.
When you click a category I want to load those posts using ajax so I don’t have page reload.
The category buttons
<ul>
<?php
$cat_args = array(
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => 1
);
$cats = get_categories($cat_args);
foreach($cats as $cat){
echo '<li><a href="#" data-slug="' . $cat->term_id . '" class="js-category-button">' . $cat->name . '</a></li>';
}
//echo '<pre>'; print_r($cats); echo '</pre>';
?>
</ul>
The jQuery
$('.js-category-button').on('click', function(e){
e.preventDefault();
var catID = $atj(this).data('slug');
var ajaxurl="http://my-site.co.uk <?php bloginfo("wpurl");?>/wp-admin/admin-ajax.php";
$atj.ajax({
type: 'POST',
url: ajaxurl,
dataType: 'jsonp',
crossDomain : true,
data: {"action": "load-filter", cat: catID },
success: function(response) {
$atj(".the-news").html(response);
return false;
}
});
})
The php query in functions.php
add_action( 'wp_ajax_nopriv_load-filter', 'prefix_load_cat_posts' );
add_action( 'wp_ajax_load-filter', 'prefix_load_cat_posts' );
function prefix_load_cat_posts () {
$cat_id = $_POST[ 'cat' ];
$args = array (
'cat' => $cat_id,
'posts_per_page' => 3,
'order' => 'DESC'
);
$posts = get_posts( $args );
ob_start ();
foreach ( $posts as $post ) {
setup_postdata( $post ); ?>
<div id="post-<?php echo $post->ID; ?> <?php post_class(); ?>">
<h1 class="posttitle"><a href="https://wordpress.stackexchange.com/questions/190655/<?php the_permalink(); ?>"><?php the_title(); ?></a></h1>
<div id="post-content">
<?php the_excerpt(); ?>
</div>
</div>
<?php } wp_reset_postdata();
$response = ob_get_contents();
ob_end_clean();
echo $response;
}
The categories appear, when I click them the console gives me 502 Proxy Error ( The host was not found. )
Can anyone see what I’m doing wrong or how to fix this.
Update
I have the code partly working now but i still have problems
My js is currently in a separate js file
The only way I could get it work was using the site url for ajaxurl
$atj('.js-category-button').on('click', function(e){
e.preventDefault();
var catID = $atj(this).data('slug');
var ajaxurl="http://mysite.co.uk/wp-admin/admin-ajax.php";
$atj.ajax({
type: 'POST',
url: ajaxurl,
crossDomain : true,
//dataType: 'jsonp',
//contentType: "text/html",
dataType: 'html',
data: {"action": "load-filter", cat: catID },
success: function(response) {
$atj(".the-news").append(response);
return false;
}
});
})
My php script is in functions.php
I think there should only be one tag in functions.php so I didn’t want to break out of the php in the function to create the html markup. Thats why I’m trying to add it all to the $response variable that then gets echoed.
add_action( 'wp_ajax_nopriv_load-filter', 'prefix_load_cat_posts' );
add_action( 'wp_ajax_load-filter', 'prefix_load_cat_posts' );
function prefix_load_cat_posts () {
global $post;
$cat_id = $_POST[ 'cat' ];
$args = array (
'cat' => $cat_id,
'posts_per_page' => 3,
'order' => 'ASC'
);
$cat_query = new WP_Query($args);
if($cat_query->have_posts()) :
while($cat_query->have_posts()) :
$cat_query->the_post();
$response="<div class="the-post">";
$response .= '<h1 class="the-title">';
$response .= '<a href="#">'. the_title() .'</a>';
$response .= '</h1>';
$response .= '<p>'. the_content().'</p>';
$response .= '</div>';
echo $response;
endwhile;
endif;
wp_reset_postdata();
die(1);
}
This sort of works. I get html output with the title of the post but it’s outside the html and I can’t output the content.
add_action( 'wp_ajax_nopriv_load-filter', 'prefix_load_cat_posts' );
add_action( 'wp_ajax_load-filter', 'prefix_load_cat_posts' );
function prefix_load_cat_posts () {
global $post;
$cat_id = $_POST[ 'cat' ];
$args = array (
'cat' => $cat_id,
'posts_per_page' => 3,
'order' => 'ASC'
);
$cat_query = new WP_Query($args);
if($cat_query->have_posts()) :
while($cat_query->have_posts()) :
$cat_query->the_post();
$response="<div class="the-post">";
$response .= '<h1 class="the-title">';
$response .= '<a href="#">'. the_title() .'</a>';
$response .= '</h1>';
$response .= '<p>'. the_content().'</p>';
$response .= '</div>';
echo $response;
endwhile;
endif;
wp_reset_postdata();
die(1);
}
Any help getting this to work would be greatly appreciated.
1 Answer
The error says it all, you are sending the request to a invalid host.
Change this:
var ajaxurl="http://my-site.co.uk <?php bloginfo("wpurl");?>/wp-admin/admin-ajax.php";
To:
var ajaxurl = "<?php echo esc_js( admin_url( 'admin-ajax.php' ) ) ?>";
Note: from your code and description I’m assuming you are generating the jQuery code within PHP and it is not in a js file.
Additionally, you must die/exit the program after after the ajax response is sent out (this is not done automatically and the request could be open forever, see documentation):
echo $response;
// Terminate
exit;
And more wrong things I see in your code: you are saying to jQuery to work with JSONP data but your ajax response is a HTML string. You should remove this line or change it to the correct data type:
dataType: 'jsonp',
After the edition of the question, you have introduced a new problem. You are trying to asign the_content()
to the value of $response
but the_content()
prints the post content, it doesn’t return any value. If you want to get the value of the post content you should use get_the_content() instead and to get the same result as the_content
you should apply the_content
filters. Change this:
$response .= '<p>'. the_content().'</p>';
To:
// <p> are not need because the the_content filters include wpautop()
$response .= apply_filters( 'the_content', get_the_content() );