So I have select element with 3 options: men, women, unisex. Whenever a user selects a new option, the posts should reload. I now have this as ajax function:
$(document).ready(function () {
$('#select-gender').change(function(){
$.ajax({
url: ajaxurl + "/woocommerce/archive-content.php",
type: "post",
data: {option: $(this).find("option:selected").val()},
success: function(data){
//adds the echoed response to our container
$("#topdog").html(data);
}
});
});
});
And this is the archive-content.php file:
<?php
function details($opt) {
echo 'option: ' . $opt;
}
details($_POST['option']);
$selected = $_POST['option'];
// The Query
$the_query = new WP_Query( $args );
$args=array(
'gender' => $selected,
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => -1
);
$my_query = null;
$my_query = new WP_Query($args);
if( $my_query->have_posts() ) {
echo 'List of manly product';
while ($my_query->have_posts()) : $my_query->the_post(); ?>
<p><?php the_title(); ?></p>
<?php
endwhile;
}
wp_reset_query(); // Restore global post data stomped by the_post().
?>
I realise now that just changing the $selected variable does not reload my posts. Should I load my posts in the 'data' part of the ajax function? How would I do that?
Thanks!
Related
I have been searching for a couple days now for a solution but all threads related to a 400 bad request using AJAX seem to not be relevant to my issue or perhaps I am just missing it.
I made a page that lists the subcategories of a master category. This part works great. When a user clicks on a category, I need to use AJAX to retrieve all of the products associated with the category that the user just clicked.
page_template.php
<script type="text/javascript">
jQuery(function($) {
$('.seamBuilder_trigger').click(function() {
var catID = $(this).attr('id');
console.log(catID);
$.ajax({
type: 'POST',
url: '<?php echo admin_url('admin-ajax.php');?>',
dataType: "html", // add data type
data: {
action : 'get_products'
},
success: function(response) {
console.log(response);
$('.posts-area').html(response);
}
});
return false;
});
});
</script>
<section id="content" class="site-content">
<div id="seam-builder-wrap" class="container">
<?php
$masterCat = 39; // Master category 'Seam Builder' ID is 39)
$taxonomyName = "product_cat";
$termchildren = get_term_children($masterCat, $taxonomyName);
foreach ($termchildren as $child) {
$subCat = get_term_by('id', $child, $taxonomyName); //assigns $subCat to the current subcategory in the loop
$subCat_title = $subCat->name; //gets the name of the subcategory
$cat_id = $subCat->term_id; //gets the ID of the subcategory on its own
$thumbnail_id = get_term_meta($child, 'thumbnail_id', true); //gets the thumbnail of the subcategory
$image = wp_get_attachment_url($thumbnail_id); //gets the URL of the thumbnail
?>
<a id="<?php echo $cat_id ?>" class="seamBuilder_trigger" href="#">
<img src="<?php echo $image ?>" />
<span><?php echo $subCat_title ?></span>
</a>
<?php } //ends for foreach loop above ?>
</div>
<div class="posts-area">
</div>
</section>
functions.php
<?php
function get_products() {
$cat_id = (isset($_POST['cat'])) ? $_POST['cat'] : '';
echo 'hello there' . $cat_id;
// Query Arguments
$args = array(
'cat' => $cat_id,
'post_type' => array('products'),
'post_status' => array('publish'),
'posts_per_page' => -1,
);
// The Query
$ajaxposts = new WP_Query($args);
$output = '';
if ($ajaxposts -> have_posts()) : while ($ajaxposts -> have_posts()) : $ajaxposts -> the_post();
$output .= 'div class="seamBuilderRow">';
$output .= $cat_id;
$output .= '</div>';
endwhile;
endif;
wp_reset_postdata();
wp_die();
}
// Fire AJAX action for both logged in and non-logged in users
add_action('wp_ajax_get_ajax_posts', 'get_products');
add_action('wp_ajax_nopriv_get_ajax_posts', 'get_products');
?>
I get 400 bad request as soon as I click on one of my categories that should fire AJAX. Any ideas?
Your action hook handler is wp_ajax_get_ajax_posts (and wp_ajax_nopriv_get_ajax_posts), hence the action parameter should be get_ajax_posts as well. Since it's not, WordPress responds to your AJAX call with a 400 Bad Request status.
This should work:
$.ajax({
type: 'POST',
url: '<?php echo admin_url('admin-ajax.php');?>',
dataType: "html", // add data type
data: {
action : 'get_ajax_posts'
},
success: function(response) {
console.log(response);
$('.posts-area').html(response);
}
});
I have a working AJAX post loader, but I can't get it working on the category page. What am I doing wrong? I think I'm not getting categories correctly?
The category.php code:
<div id="ajaxCatPosts" class="cat-post-side left small-12 large-9">
<?php
while ( have_posts() ) : the_post();
include(__DIR__.'/views/cat-post-thumb.php');
endwhile;
?>
<div class="load-button">
<button id="more_cat_posts">Veel uudiseid</button>
</div>
</div>
The functions.php code:
function more_post_ajax(){
$ppp = (isset($_POST["ppp"])) ? $_POST["ppp"] : 16;
$page = (isset($_POST['pageNumber'])) ? $_POST['pageNumber'] : 0;
header("Content-Type: text/html");
$args = array(
'suppress_filters' => true,
'posts_per_page' => $ppp,
'paged' => $page,
);
$loop = new WP_Query($args);
if ($loop -> have_posts()) : while ($loop -> have_posts()) : $loop -> the_post();
include(__DIR__.'/views/cat-post-thumb.php');
endwhile;
endif;
wp_reset_postdata();
die($out);
}
add_action('wp_ajax_nopriv_more_post_ajax', 'more_post_ajax');
add_action('wp_ajax_more_post_ajax', 'more_post_ajax');
And here is loadmore.js:
$(function() {
var ppp = 16; // Post per page
var pageNumber = 1;
function load_posts(){
pageNumber++;
var str = '&pageNumber=' + pageNumber + '&ppp' + ppp + '&action=more_post_ajax';
$.ajax({
type: "POST",
dataType: "html",
url: ajax_posts.ajaxurl,
data: str,
success: function(data){
var $data = $(data);
if($data.length){
$("#ajax-posts").append($data);
$("#more_posts").attr("disabled",false);
} else{
$("#more_posts").attr("disabled",true);
}
},
error : function(jqXHR, textStatus, errorThrown) {
$loader.html(jqXHR + " :: " + textStatus + " :: " + errorThrown);
}
});
return false;
}
$('#more_posts').unbind('click');
$("#more_posts").on("click",function(){ // When btn is pressed.
$("#more_posts").attr("disabled",true); // Disable the button, temp.
load_posts();
});
});
To make it work more dynamically with any taxonomy or combinations of taxonomies so this solutions would work not only in category.php but in any other case. For example JS could pass taxonomy term arguments where to fetch pposts from.
So first in your AJAX call we need to pass in the term where we want to load our posts from, lets say category is named milk. (And also lets make POST arguments more readable)
function load_posts(){
pageNumber++;
var str = {
pageNumber: pageNumber,
ppp: ppp,
term: 'milk',
action: 'more_post_ajax'
};
$.ajax({
type: "POST",
dataType: "html",
url: ajax_posts.ajaxurl,
data: str,
success: function(data){
var $data = $(data);
if($data.length){
$("#ajax-posts").append($data);
$("#more_posts").attr("disabled",false);
} else{
$("#more_posts").attr("disabled",true);
}
},
error : function(jqXHR, textStatus, errorThrown) {
$loader.html(jqXHR + " :: " + textStatus + " :: " + errorThrown);
}
});
return false;
}
In your PHP code
function more_post_ajax(){
$ppp = (isset($_POST["ppp"])) ? $_POST["ppp"] : 16;
$page = (isset($_POST['pageNumber'])) ? $_POST['pageNumber'] : 0;
$term = isset($_POST['term']) ? $_POST['term'] : 0;
header("Content-Type: text/html");
$args = array(
'suppress_filters' => true,
'posts_per_page' => $ppp,
'paged' => $page,
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'slug', // Depends whether JS passes you slug or ID of taxonomy term, in our case it is a slug
'terms' => array( $term ),
)
),
);
$loop = new WP_Query($args);
if ($loop -> have_posts()) : while ($loop -> have_posts()) : $loop -> the_post();
include(__DIR__.'/views/cat-post-thumb.php');
endwhile;
endif;
wp_reset_postdata();
die();
}
add_action('wp_ajax_nopriv_more_post_ajax', 'more_post_ajax');
add_action('wp_ajax_more_post_ajax', 'more_post_ajax');
Your WP_Query is now hardcoded to search from category taxonomy where posts have terms that match with the queried ones. You could change it to whatever you want, your not stuck with category taxonomy only if you change tax_query in your arguments. To be more secure you might want to check if that term exists in that taxonomy first.
The answer to your question seems to be in the documentation here.
Specifically, before making the call to WP_Query you need to specify the category you want. You're currently setting up the query here:
$args = array(
'suppress_filters' => true,
'posts_per_page' => $ppp,
'paged' => $page,
);
And you'll need to extend that to this:
$args = array(
'category_name' => $category
'suppress_filters' => true,
'posts_per_page' => $ppp,
'paged' => $page,
);
This means that your AJAX call will need to include the category you want (`$category) in the JSON, or you'll have to extract it from the page url. One way you could do this is:
$args = array(
'suppress_filters' => true,
'posts_per_page' => $ppp,
'paged' => $page,
);
if (isset($_POST["category"]){
$args['category_name'] = $_POST["category"];
}
Correspondingly, you'd need to update your AJAX call to have a category element:
var str = '&pageNumber=' + pageNumber + '&ppp' + ppp + '&action=more_post_ajax' + '&category=milk';
I tried to load more posts using ajax. I see there is lot of plugins and solutions in online and stackoverflow. But none of work for me. Actually I want to do this without plugin. So I can use this in different page archive or different page template where I need this code.
Here is my code that I got from another question in stackoverflow. My score is lower, so I can't comment out there.
Here is my index.php code:
<?php get_header(); ?>
<div class="ajax-posts">
<?php
$postsPerPage = 3;
$args = array(
'post_type' => 'post',
'posts_per_page' => $postsPerPage,
);
$loop = new WP_Query($args);
while ($loop->have_posts()) : $loop->the_post();
?>
<h2><?php the_title(); ?></h2>
<?php
endwhile;
echo '<a id="more_posts" href="#">Load More</a>';
wp_reset_postdata();
?>
</div>
<script type="text/javascript">
var ajaxUrl = "<?php echo admin_url('admin-ajax.php')?>";
var page = 1;.
var ppp = 3;
$("#more_posts").on("click",function(){
$("#more_posts").attr("disabled",true);
$.post(ajaxUrl, {
action:"more_post_ajax",
offset: (page * ppp) + 1,
ppp: ppp
}).success(function(posts){
page++;
$(".ajax-posts").append(posts); // CHANGE THIS!
$("#more_posts").attr("disabled",false);
});
});
</script>
<?php get_footer(); ?>
Here is functions.php code
<?php
function more_post_ajax(){
$offset = $_POST["offset"];
$ppp = $_POST["ppp"];
header("Content-Type: text/html");
$args = array(
'post_type' => 'post',
'posts_per_page' => $ppp,
'offset' => $offset,
);
$loop = new WP_Query($args);
while ($loop->have_posts()) { $loop->the_post();
the_title();
}
exit;
}
add_action('wp_ajax_nopriv_more_post_ajax', 'more_post_ajax');
add_action('wp_ajax_more_post_ajax', 'more_post_ajax');
?>
I don't know why posts not load or not work load more link. I hope someone will be help.
Ref: https://stackoverflow.com/a/31588401/5545813
The better way is to return an array with ur post title. Then display them after the success. If the array length < ppp (there is no more post).
$array_return = array();
$loop = new WP_Query($args);
while ($loop->have_posts()) { $loop->the_post();
$content = "<h1>" . get_the_title() . "</h1>";
$content .= "<div>" . get_the_content() . "</div>";
$content .= "<div>" . get_field("your_field") . "</div>";
$array_return[] = $content;
}
echo json_encode( $array_return );
die();
In your js script,
var posts = JSON.parse(posts);
for( var i = 0; i < posts.length; i++ )
$(".ajax-posts").append(posts[i]);
if( posts.length < ur_ppp )
$("#more_posts").fadeOut();
Something like that
I want to paginate my WordPress posts in a custom loop with Ajax, so when I click on load more button posts will appear.
My code:
<?php
$postsPerPage = 3;
$args = array(
'post_type' => 'post',
'posts_per_page' => $postsPerPage,
'cat' => 1
);
$loop = new WP_Query($args);
while ($loop->have_posts()) : $loop->the_post();
?>
<h1><?php the_title(); ?></h1>
<p>
<?php the_content(); ?>
</p>
<?php
endwhile;
echo 'Load More';
wp_reset_postdata();
?>
This code does not paginate. Is there a better way to do this?
The Load More button needs to send a ajax request to the server and the returned data can be added to the existent content using jQuery or plain javascript. Assuming your using jQuery this would starter code.
Custom Ajax Handler (Client-side)
Load More
Change to:
<a id="more_posts" href="#">Load More</a>
Javascript: - Put this at the bottom of the file.
//</script type="text/javascript">
var ajaxUrl = "<?php echo admin_url('admin-ajax.php')?>";
var page = 1; // What page we are on.
var ppp = 3; // Post per page
$("#more_posts").on("click",function(){ // When btn is pressed.
$("#more_posts").attr("disabled",true); // Disable the button, temp.
$.post(ajaxUrl, {
action:"more_post_ajax",
offset: (page * ppp) + 1,
ppp: ppp
}).success(function(posts){
page++;
$(".name_of_posts_class").append(posts); // CHANGE THIS!
$("#more_posts").attr("disabled",false);
});
});
//</script>
Custom Ajax Handler (Server-side)
PHP - Put this in the functions.php file.
function more_post_ajax(){
$offset = $_POST["offset"];
$ppp = $_POST["ppp"];
header("Content-Type: text/html");
$args = array(
'post_type' => 'post',
'posts_per_page' => $ppp,
'cat' => 1,
'offset' => $offset,
);
$loop = new WP_Query($args);
while ($loop->have_posts()) { $loop->the_post();
the_content();
}
exit;
}
add_action('wp_ajax_nopriv_more_post_ajax', 'more_post_ajax');
add_action('wp_ajax_more_post_ajax', 'more_post_ajax');
I have a custom post type called press.
What I want to achieve is generate a list of the titles (with it's corresponding link to it) of all press custom post types.
I tried with this code with no luck, any ideas?
<?php function all_posts_custom_posts( $query ) {
$post_type = $query->query_vars['post_type'];
if ( 'press' == $post_type ){
$query->query_vars['posts_per_page'] = -1;
return;
}
}
add_action('pre_get_posts', 'all_posts_custom_posts',1); ?>
And also highlight the current post from the list by adding a class to it.
I had a similar issue sometime ago. The following code example will display how I resolved my issue.
<?php
$type = 'products';
$args=array(
'post_type' => $type,
'post_status' => 'publish',
'posts_per_page' => -1,
'caller_get_posts'=> 1
$my_query = null;
$my_query = new WP_Query($args);
if( $my_query->have_posts() ) {
while ($my_query->have_posts()) : $my_query->the_post(); ?>
<p><?php the_title(); ?></p>
<?php
endwhile;
}
wp_reset_query(); // Restore global post data stomped by the_post().
?>