I have a ajax post loading program, I can load more post on click of a button.
The problem that I’m having is getting the button to hide or show less when no more post.
I can query out the post count in PHP as I have with my side bar bellow.
<?php
foreach ($my_categories as $term_id) {
$category = get_term_by('id', $term_id, 'category');
if ($category->slug != "all-articles") {
if ($category->parent != 0) { // If this is a subcategory
$args = array(
'numberposts' => -1,
'category' => $category->term_id,
'post_type' => $new_string,
);
$count_posts = get_posts($args);
$total_posts_child = count($count_posts);
?>
<li :class="category == <?php echo $category->term_id; ?> ? 'child' : ''" ;>
<a class="child" @click="filterPosts(<?= $category->term_id; ?>)"><?= esc_html($category->name);
echo " "."(".$total_posts_child.")"; ?></a>
</li> <?php
} else {
$args = array(
'numberposts' => -1,
'category' => $category->term_id,
'post_type' => $new_string,
);
$count_posts = get_posts($args);
$total_posts_parent = count($count_posts);
?>
<li :class="category == <?php echo $category->term_id; ?> ? 'parent' : ''" ;>
<a class="parent" @click="filterPosts(<?= $category->term_id; ?>)"><?= esc_html($category->name);
echo " "."(".$total_posts_parent.")" ?></a>
</li> <?php
}
}
}
The problem I’m getting is trying to get that post count into JavaScript so I can hide my button if post count is reached.
<div @click="loadMore()" x-show="total > (limit + offset)" class="text-center pt-4">
<button class="border border-solid border-slate-700 text-slate-100 hover:bg-slate-800 px-4 py-2"> Load More </button>
</div>
Here is my JavaScript
Alpine.data("filterPosts", (adminURL) => ({
posts: "",
limit: 6,
category: null,
post_type_js: post_id,
showDefault: true,
showFiltered: false,
offset: 0,
total:null,
filterPosts(id) {
this.showDefault = false;
this.showFiltered = true;
this.category = id;
this.offset = 0; // <-- reset offset to zero
this.total = 8;
this.fetchPosts();
},
loadMore() {
this.loadingMore = true;
this.total = 8;
this.offset += 6;
this.showFiltered = true;
this.fetchPosts(true);
},
fetchPosts(append = false) {
var formData = new FormData();
formData.append("action", "filterPosts");
formData.append("limit", this.limit);
formData.append("post_type_js", this.post_type_js);
formData.append("offset", this.offset);
if (this.category) {
formData.append("category", this.category);
formData.append("total", this.total);
}
fetch(adminURL, {
method: "POST",
body: formData,
})
.then((res) => res.json())
.then((res) => {
if (append) {
// Appends posts to the end of existing posts data
this.posts = this.posts.concat(res.posts);
} else {
// Resets the posts data with new data
this.posts = res.posts;
}
this.loading = false;
});
},
getTotal() {
var formData = new FormData();
formData.append("action", "filterPosts");
fetch(adminURL, {
method: "POST",
body: formData,
})
.then((res) => res.json())
.then((res) => {
this.total = res.total;
});
},
init() {
this.getTotal();
}
}));
})
I have thought about scraping my HTML and getting the number, but honestly been thinking all day, I cant find a way to get the total post count for the category and post type clicked in the side bar
2
Answers
I usually do this by requesting one more row than I need and checking how many are returned.
So – if you want 6 more rows, set the limit to 7.
Now if you get less than 7 rows back, you know that there are no more rows after this set, so hide the ‘More’ button.
If you get 7 back, discard the last row and show the ‘More’ button, because you know that there is at least one more row after the current six.
Ive never worked with wordpress, but if what you want is to get it in to javascript why not make an ajax request where php returns json, that includes the count? i suppose another way would be to give the button an attribute like name = $total_posts_parent and then get that attribute in js.