Im trying to build out the second part of this tutorial https://joeyfarruggio.com/wordpress/skeleton-loader/. First part is working well, however now i try and add the second part for a load more button, im starting to get a few errors that im trying to fix.
on page load im seeings
cdn.min.js:5 Uncaught ReferenceError: category is not defined at [Alpine] category == 835 ? 'active' : '' (eval at (cdn.min.js:5:665), :3:33) at cdn.min.js:5:1068 at fr (cdn.min.js:1:6642) at cdn.min.js:5:31317 at r (cdn.min.js:5:16370) at Object.Zr [as effect] (cdn.min.js:5:16158) at N (cdn.min.js:1:398) at cdn.min.js:1:511 at Function.xn (cdn.min.js:5:31311) at r (cdn.min.js:5:2273)
and on category click, im getting
Alpine Expression Error: filterPosts is not defined
Expression: "filterPosts(835)"
<a hreff @click="filterPosts(835)" class="active">cat b te @ cdn.min.js:1 (anonymous) @ cdn.min.js:5 Promise.catch (async) (anonymous) @ cdn.min.js:5 fr @ cdn.min.js:1 (anonymous) @ cdn.min.js:5 o @ cdn.min.js:5 (anonymous) @ cdn.min.js:5 (anonymous) @ cdn.min.js:5
This is the code i have tried, I cant see why category is not defined and filterPost not defind. Ive been at this hours any help is much appreciated.
<?php /* Template Name: test */
?>
<html>
<head>
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js"></script>
<script>
document.addEventListener('alpine:init', () => {
Alpine.data("filterPosts", (adminURL) => ({
posts: null,
category: null,
showDefault: true,
showFiltered: false,
loading: false,
offset: 0,
loadingNew: false, // <--- defaults to false
loadingMore: false, // <--- defaults to false
filterPosts(id) {
this.loadingNew = true;
this.showFiltered = true;
this.category = id;
this.offset = 0; // <-- reset offset to zero
this.fetchPosts();
},
loadMore() {
this.loadingMore = true;
this.offset += 10;
this.showFiltered = true;
this.fetchPosts(true);
},
// append defaults to false
fetchPosts(append = false) {
var formData = new FormData();
formData.append("action", "ajaxPosts");
formData.append("offset", this.offset); // <-- Add new data to the form
...
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();
}
}));
})
</script>
</head>
<body>
<div x-data="filterPosts('<?php echo admin_url('admin-ajax.php'); ?>')">
<section <?php theme_section_attr_id() ?> <?php theme_section_attr_class('main-section js-posts') ?>>
<div class="container">
<div class="heading mx-0">
<?php $before_title = get_sub_field('before_title');
if ($before_title) : ?>
<strong class="sub-title"><?php echo $before_title ?></strong>
<?php endif ?>
<?php $title = get_sub_field('title');
if ($title) : ?>
<h2><?php echo $title ?></h2>
<?php endif ?>
</div>
<div class="head js-posts-search-text">
<?php if ($search_value) : ?>
<h2 class="h5 fw-semibold"><?php printf(__('Showing results for “%s”', 'base'), $search_value) ?></h2>
<?php endif ?>
</div>
<!--alipne js dynamic post start-->
<div class="has-filter row flex-md-row-reverse">
<div class="col-md-8 col-lg-9 js-posts-holder">
<!-- Posts Column -->
<div x-show.important="showDefault" class="row cards-area js-posts-items">
<!-- Default posts query -->
<?php get_template_part( 'template-parts/posts-filter/default-query' ); ?>
</div>
<!-- Load More Posts -->
<!-- Load More Posts -->
<div @click="loadMore()" x-show="total > (limit + offset)" class="text-center mt-12">
<button class="border border-solid border-slate-700 text-slate-100 hover:bg-slate-800 px-4 py-2">
Load More
</button>
</div>
<!-- Filtered posts -->
<div x-show.important="showFiltered" x-html="posts" class="row cards-area js-posts-items">
<!-- Default posts query -->
</div>
<template x-if="loadingNew || loadingMore">
<div class="grid grid-cols-2 gap-6">
<template x-for="i in 4">
<div>
<div class="h-52 w-full bg-slate-200 rounded-lg"></div>
<div class="h-8 w-1/2 bg-slate-200 rounded-lg mt-4"></div>
</div>
</template>
</div>
</template>
</div>
<!-- Filtered posts -->
<div class="col-md-4 col-lg-3">
<aside class="sidebar">
<div class="widget widget-filter">
<button class="widget-title">Explore Topics</button>
<svg class="separator" viewBox="0 0 238 11" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
<line opacity="0.3" y1="0.5" x2="101.942" y2="0.5" stroke="#3CD5AF"></line>
<line opacity="0.3" y1="10.5" x2="237.5" y2="10.5" stroke="#3CD5AF"></line>
</svg>
<?php
$categories = get_categories();
if ( ! empty( $categories ) ) :
?>
<ul class="filter-list">
<?php foreach ( $categories as $category ) :
// Skip "Uncategorized" category
if ($category->name == 'Uncategorized') continue; ?>
<li :class=" category == <?php echo $category->term_id; ?> ? 'active' : ''">
<a hreff="" @click="filterPosts(<?= $category->term_id; ?>)"><?= esc_html( $category->name ); ?></button>
</li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</div>
</aside>
<!-- Filtered end -->
</div>
</div>
</div>
<!--alipne js dynamic post end-->
</section>
</div>
</body>
</html>