@total_onion/onion-library 2.0.264 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/components/block-carousel-multi-layout-v3/carousel-multi-layout-v3.js +13 -1
  2. package/components/component-responsive-image-v3/responsive-image-v3.scss +1 -0
  3. package/onion-utils.mjs +0 -49
  4. package/package.json +10 -18
  5. package/components/block-post-type-filter-grid-v3/group_64690c62487bc.json +0 -4389
  6. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/better-reviews-widget.vue +0 -15
  7. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/buy-now-widget.vue +0 -72
  8. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/divider-widget.vue +0 -11
  9. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/global-image-widget.vue +0 -23
  10. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/media-widget.vue +0 -23
  11. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/post-author-widget.vue +0 -15
  12. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/post-category-widget.vue +0 -20
  13. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/post-component.vue +0 -73
  14. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/post-headline-widget.vue +0 -16
  15. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/post-image-widget.vue +0 -60
  16. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/post-info-description.vue +0 -15
  17. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/post-info-subtitle.vue +0 -15
  18. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/post-link-widget.vue +0 -47
  19. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/post-publish-widget.vue +0 -44
  20. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/post-tags-widget.vue +0 -19
  21. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/post-text-alternative-style.vue +0 -18
  22. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/post-title-widget.vue +0 -20
  23. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/pre-render-posts-html.twig +0 -17
  24. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/ptfg-posts.twig +0 -474
  25. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/ptfg-utils.vue +0 -41
  26. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/shopify-add-to-cart.vue +0 -25
  27. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/spacer-widget.vue +0 -13
  28. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/text-search.vue +0 -10
  29. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3.js +0 -14
  30. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3.php +0 -17
  31. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3.scss +0 -762
  32. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3.twig +0 -139
  33. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3.vue +0 -811
@@ -1,811 +0,0 @@
1
- <template>
2
- <div id="app" :class="`${blockClassName}__main-container ${blockClassName}__main-container ${!showFilters && 'post-type-filter-grid-v3__main-container--hide-filters'
3
- }`" :data-layout="filterLayout">
4
- <TextSearch v-if="enableTextSearch" v-model="textSearchInput" ref="textSearchInput"
5
- :placeholder="textSearchInputPlaceholder" />
6
- <div ref="filterBlock" v-if="showFilters" :class="`${blockClassName}__filter`" :data-layout="filterLayout">
7
- <button :class="`${blockClassName}__open-filter-toggle cmpl-cta-style-${toggleFilterButtonStyle}`">
8
- {{ modalOpen ? closeFilterText : openFilterText }}
9
- </button>
10
- <div :class="`${blockClassName}__filter-container ${modalOpen ? 'post-type-filter-grid-v3__filter-container--open' : ''
11
- }`" :data-layout="filterLayout">
12
- <button v-if="fields.enable_show_all_button"
13
- :class="`${blockClassName}__show-all cmpl-cta-style-${showAllButtonStyle}`"
14
- v-on:click.prevent="clearAllFilters()" :data-layout="filterLayout">
15
- {{ showAllText }}
16
- </button>
17
- <div :class="`${blockClassName}__filter-categories`" :data-layout="filterLayout">
18
- <div v-if="filterLayout == 4" :class="`${blockClassName}__filter-categories-label`">
19
- {{ categoriesTitleText }}
20
- <button @click="modalOpen = !modalOpen"></button>
21
- </div>
22
- <div v-for="(topCategory, index) in computedCategories.topLevelCategories" :class="`${blockClassName}__filter-category ${blockClassName}__cta cmpl-cta-style-${showTopLevelFilters ? topLevelCategoryButtonStyle : 'none'
23
- }`" v-bind:key="index" :data-layout="filterLayout">
24
- <h6 v-if="showTopLevelFilters" :class="`${blockClassName}__filter-top-level-category-name`"
25
- :data-layout="filterLayout">
26
- {{ topCategory.name }}
27
- </h6>
28
- <ul :class="`${blockClassName}__filter-subcategory-list`" :data-layout="filterLayout"
29
- :style="`${subFilterOverflowStyles}`">
30
- <li v-for="(subCategory, index) in computedCategories.subCategories[
31
- topCategory.term_id
32
- ]" :key="index" :data-categoryid="subCategory.term_id"
33
- :class="`${blockClassName}__filter-subcategory-list-item`" :data-layout="filterLayout">
34
- <button :class="`${blockClassName}__filter-subcategory-button ${updateCategoryButtonActiveStatus(
35
- subCategory.term_id
36
- )} ${blockClassName}__cta cmpl-cta-style-${categoryButtonStyle} cmpl-cta-style-${categoryButtonStyle}--${updateActiveCategoryButtonStyle(subCategory.term_id) ? 'selected' : ''
37
- }`" :data-categoryid="subCategory.term_id" @click="addOrRemoveIdFromActiveFilters(subCategory.term_id)"
38
- :disabled="updateDisabledStatus(subCategory.term_id)">
39
- <span v-html="subCategory.name"></span>
40
- <img v-if="enableFilterIcon" :src="ctaIcons.cta_filter_icon"
41
- :class="`${blockClassName}__filter-subcategory-button-icon`" />
42
- </button>
43
- </li>
44
- </ul>
45
- </div>
46
- <div :class="`${blockClassName}__filter-update-button`" v-if="filterLayout == 4">
47
- <button @click="modalOpen = false">{{ updateFilterText }}</button>
48
- </div>
49
- </div>
50
- <div v-if="filterLayout == 3" :class="`${blockClassName}__filter-categories`"
51
- :data-layout="filterLayout">
52
- <div :class="`${blockClassName}__filter-categories-container`">
53
- <ul v-if="showTopLevelFilters" @click="toggleTopLevelContainerStatus" :class="`${blockClassName}__filter-top-level-categories ${blockClassName}__filter-top-level-category-container ${topLevelContainerStatus ? 'open' : ''
54
- }`" :data-layout="filterLayout">
55
- <li :class="`${blockClassName}__filter-top-level-category ${placeholderFilterStatus ? 'currently-selected' : ''
56
- }`" @click="toggleActiveTopLevelCategory('placeholder')" v-if="enablePlaceholderFilter"
57
- data-categoryid="placeholder">
58
- <button :class="`${blockClassName}__cta cmpl-cta-style-${showTopLevelFilters ? topLevelCategoryButtonStyle : 'none'
59
- } `">
60
- <span>{{ placeholderFilterText }}</span><img v-if="enableTopLevelFilterIcon"
61
- :src="ctaIcons.cta_filter_icon"
62
- :class="`${blockClassName}__filter-top-level-category-button-icon style-svg`" />
63
- </button>
64
- </li>
65
- <li v-for="(topCategory, index) in computedCategories?.topLevelCategories"
66
- v-bind:key="index" :class="`${blockClassName}__filter-top-level-category ${topLevelCategoryActiveStatus(topCategory.term_id)
67
- ? 'currently-selected'
68
- : ''
69
- }`" :data-categoryid="topCategory.term_id" :data-layout="filterLayout"
70
- @click="toggleActiveTopLevelCategory(topCategory.term_id)">
71
- <button :class="`${blockClassName}__cta ${topLevelCategoryActiveStatus(topCategory.term_id)
72
- ? blockClassName +
73
- '__cta-style-' +
74
- topLevelCategoryButtonStyle +
75
- '--selected'
76
- : ''
77
- } cmpl-cta-style-${showTopLevelFilters ? topLevelCategoryButtonStyle : 'none'
78
- } `">
79
- <span v-html="topCategory?.name"></span><img v-if="enableTopLevelFilterIcon"
80
- :src="ctaIcons.cta_filter_icon"
81
- :class="`${blockClassName}__filter-top-level-category-button-icon style-svg`" />
82
- </button>
83
- </li>
84
- </ul>
85
- </div>
86
- <div :class="`${blockClassName}__filter-subcategories-container`">
87
- <ul v-for="(topCategory, index) in computedCategories?.topLevelCategories" v-bind:key="index"
88
- @click="toggleSubcategoryListContainer(topCategory?.term_id)" :class="`${blockClassName}__filter-subcategory-list ${topLevelCategoryActiveStatus(topCategory?.term_id)
89
- ? blockClassName + '__filter-subcategory-list--active'
90
- : ''
91
- } ${subCategoryListOpenStatus(topCategory?.term_id) ? 'open' : ''}`" :data-layout="filterLayout"
92
- :data-topcategoryid="topCategory?.term_id" :style="`${subFilterOverflowStyles}`">
93
- <li v-for="(subCategory, index) in computedCategories.subCategories[
94
- topCategory?.term_id
95
- ]" :key="index" :data-categoryid="subCategory.term_id" :class="`${blockClassName}__filter-subcategory-list-item ${updateCategoryButtonActiveStatus(
96
- subCategory.term_id
97
- )}`" :data-layout="filterLayout">
98
- <button :class="`${blockClassName}__filter-subcategory-button ${updateCategoryButtonActiveStatus(
99
- subCategory.term_id
100
- )} ${blockClassName}__cta cmpl-cta-style-${categoryButtonStyle} cmpl-cta-style-${categoryButtonStyle}--${updateActiveCategoryButtonStyle(subCategory.term_id) ? 'selected' : ''
101
- }`" :data-categoryid="subCategory.term_id" @click="addOrRemoveIdFromActiveFilters(subCategory.term_id)"
102
- :disabled="updateDisabledStatus(subCategory.term_id)">
103
- <span v-html="subCategory.name"></span>
104
- <img v-if="enableFilterIcon" :src="ctaIcons.cta_filter_icon"
105
- :class="`${blockClassName}__filter-subcategory-button-icon style-svg`" />
106
- </button>
107
- </li>
108
- </ul>
109
- </div>
110
- </div>
111
- </div>
112
- </div>
113
-
114
- <div :class="`${blockClassName}__grid`">
115
- <TransitionGroup :name="fields.filter_results_transition">
116
- <div :class="`${blockClassName}__post-container`" :style="`
117
- --post-container-background-colour: ${postContainerBackgroundColour(
118
- post
119
- )}; --post-container-grid-gap-mobile: ${fields.post_container_grid_gap_mobile
120
- }; --post-container-grid-gap-portrait: ${fields.post_container_grid_gap_portrait
121
- }; --post-container-grid-gap-desktop: ${fields.post_container_grid_gap_desktop
122
- }; --post-container-grid-auto-rows: ${fields.post_container_grid_auto_rows?.slice(
123
- 2
124
- )}; --post-container-grid-auto-columns: ${fields.post_container_grid_auto_columns?.slice(
125
- 2
126
- )}; --post-container-grid-template-rows: ${fields.post_container_grid_template_rows
127
- }; --post-container-grid-template-columns: ${fields.post_container_grid_template_columns
128
- };`" v-for="post in pagedPosts" :key="post.slug">
129
- <PostComponent :postDataConfig="postDataConfig" :post="post" :fields="fields" :options="options"
130
- :mappedIcons="mappedIcons" :ctaStyles="ctaStyles" :globalImages="globalImages"
131
- :imageSizesAttribute="imageSizesAttribute"
132
- :gradientOverlayColour="postContainerGradientOverlayColour(post)">
133
- </PostComponent>
134
- </div>
135
- </TransitionGroup>
136
- </div>
137
-
138
- <div :class="`${blockClassName}__load-more-container`" ref="loadMore" role="button" tab-index="0"
139
- :aria-label="loadMoreText" :title="loadMoreText" v-if="computedLoadMore && enableLoadMoreButton">
140
- <a :href="`${nextPage}`" ref="loadButton" @click.prevent="
141
- page = page + 1;
142
- incrementLoadMoreStatus(); loadMorePosts();
143
- " :class="`${blockClassName}__load-more-button ${blockClassName}__cta cmpl-cta-style-${loadMoreButtonStyle} cmpl-cta-animation-style-${loadMoreAnimationStyle}`">
144
- <span :class="`cmpl-cta-span ${isLoading ? 'hide-text' : ''}`">{{ loadMoreText }}</span> <span
145
- :class="`loader ${isLoading ? 'show-spinner' : ''}`"></span>
146
- <span :class="`${blockClassName}__cta-icon cmpl-cta-icon`" v-if="enableLoadMoreIcon"
147
- v-html="loadmoreIconImage"></span>
148
- </a>
149
- </div>
150
-
151
- </div>
152
- </template>
153
-
154
- <script setup>
155
- import { ref, reactive, onMounted, useAttrs, computed, watch } from "vue";
156
- import PostComponent from "./post-type-filter-grid-v3/post-component.vue";
157
- import TextSearch from "./post-type-filter-grid-v3/text-search.vue";
158
-
159
- // get content data from window
160
- const attrs = useAttrs();
161
- const ptfgData = window["ptfgData" + attrs.blockid];
162
- // if (!ptfgData) {
163
- // console.log('No ptfgData found');
164
- // return;
165
- // }
166
-
167
- // defining refs
168
- let page = ref(0);
169
- let loadMoreStatus = ref(1);
170
- let topLevelContainerStatus = ref(false);
171
- let activeTopLevelCategories = ref([]);
172
- let placeholderFilterStatus = ref(true);
173
-
174
- let activeFilterCategories = ref([]);
175
- let openSubCategoryListContainers = ref([]);
176
- let enableCategoryDisabledStatus = ref(false);
177
-
178
- // ref dom elements
179
- const textSearchInput = ref(null);
180
- const filterBlock = ref(null);
181
-
182
- // defining constant variables
183
- const blockClassName = "post-type-filter-grid-v3";
184
- const fields = ptfgData.fields;
185
- let modalOpen = ref(false);
186
-
187
- const sortText = "Sort";
188
- const sortByText = fields.sort_by_text;
189
-
190
- const openFilterText = fields.mobile_filter_label
191
- ? fields.mobile_filter_label
192
- : "Open Filter";
193
- const closeFilterText = "Close Filter";
194
- const updateFilterText = fields.mobile_filter_update_label
195
- ? fields.mobile_filter_update_label
196
- : "Update Filter";
197
-
198
- const ajaxUrl = ptfgData.ajaxUrl;
199
- const isLoading = ref(false);
200
- const options = ptfgData.options;
201
- const allPosts = reactive({ items: ptfgData.posts });
202
- const allProducts = ptfgData.allProducts;
203
- const postDataConfig = ptfgData.postDataConfig;
204
- const allCategories = ptfgData.taxonomies;
205
- const featuredPost = ptfgData.featuredPost;
206
- const mappedIcons = ptfgData.mappedIcons;
207
- const ctaStyles = ptfgData.ctaStyles;
208
- const totalPosts = ptfgData.total;
209
-
210
- const ctaIcons = ptfgData.theme_cta_icons;
211
- const globalImages = ptfgData.global_images;
212
- const gridColumnsDesktop = fields.columns_desktop;
213
- const gridColumnsPortrait = fields.columns_tablet_portrait;
214
- const gridColumnsMobile = fields.columns_mobile;
215
- const containerWidth = 100;
216
- const defaultImageSizes = `(min-width: 1440px) ${containerWidth / gridColumnsDesktop}vw, (min-width: 1024px) ${containerWidth / gridColumnsDesktop}vw, (min-width: 768px) ${containerWidth / gridColumnsPortrait}vw, (min-width: 500px) ${containerWidth / gridColumnsMobile}vw, ${containerWidth / gridColumnsMobile}vw`;
217
- const customSizesAttribute = fields.custom_image_sizes;
218
- const imageSizesAttribute = customSizesAttribute ? customSizesAttribute : defaultImageSizes;
219
- const postType = fields.post_type?.replace("__", "");
220
- const sorting = fields.sorting?.replace("__", "");
221
- const filterLayout = fields.filter_layout?.toString().replace("__", "");
222
- const topLevelCategoryButtonStyle = fields.top_level_category_button_style
223
- ?.toString()
224
- .replace("__", "");
225
- const categoryButtonStyle = fields.category_button_style?.toString().replace("__", "");
226
- const loadMoreButtonStyle = fields.load_more_button_style?.toString().replace("__", "");
227
- const loadMoreAnimationStyle =
228
- ctaStyles[parseInt(loadMoreButtonStyle) - 1]?.cta_settings
229
- ?.cta_animation_style;
230
- const toggleFilterButtonStyle = fields.toggle_filter_button_style
231
- ?.toString()
232
- .replace("__", "");
233
- const showAllButtonStyle = fields.show_all_button_style?.toString().replace("__", "");
234
- const enableLoadMoreButton = fields.enable_load_more_button;
235
- const showFilters = fields.show_filters;
236
- const showTopLevelFilters = fields.show_top_level_filters;
237
- const topLevelFiltersActiveOnLoad = fields.top_level_filters_active_on_load;
238
- const singleActiveTopLevelCategory = fields.single_active_top_level_category;
239
- const singleActiveFilter = ref(fields.single_active_filter);
240
- const limitPostsToCategories = fields.limit_posts_to_selected_categories;
241
- const categoriesTitleText = fields.categories_title_text;
242
- const loadMoreText = fields.load_more_button_text;
243
- const showAllText = fields.show_all_button_text;
244
- const showAllPosts = fields.show_all_posts;
245
- const postContainerBackgroundColourStyle = fields.post_container_background_style?.replace(
246
- "__",
247
- ""
248
- );
249
- let loadmoreIconImage = '';
250
- if (mappedIcons['cta_link_icon']) {
251
- loadmoreIconImage = mappedIcons['cta_link_icon']['type'] == 'image/svg+xml' ? mappedIcons['cta_link_icon']['image'] : '<img src="' + mappedIcons['cta_link_icon']['image'] + '">';
252
- }
253
- const enableLoadMoreIcon = ctaStyles[parseInt(loadMoreButtonStyle) - 1]?.cta_settings?.include_cta_icon;
254
- const enableTextSearch = fields.enable_text_search;
255
- const textSearchInputPlaceholder = fields.text_filter_placeholder;
256
- const enableFilterIcon = fields.enable_filter_icon;
257
- const enableTopLevelFilterIcon = fields.enable_top_level_filter_icon;
258
- const enableStartingFilter = fields.enable_starting_filter;
259
- const enablePlaceholderFilter = fields.enable_placeholder_filter;
260
- const placeholderFilterText = fields.placeholder_filter_text;
261
- const initialPostsPerPageDesktop = fields.initial_posts_per_page_desktop;
262
- const initialPostsPerPageTablet = fields.initial_posts_per_page_portrait;
263
- const initialPostsPerPageMobile = fields.initial_posts_per_page_mobile;
264
- const postsPerPageDesktop = showAllPosts ? 999999 : Number(fields.posts_per_page_desktop);
265
- const postsPerPageTablet = showAllPosts ? 999999 : Number(fields.posts_per_page_tablet);
266
- const postsPerPageMobile = showAllPosts ? 999999 : Number(fields.posts_per_page_mobile);
267
- const loadedCategories = [];
268
-
269
- let devicePostsPerPage = postsPerPageDesktop;
270
- let deviceInitialPostsPerPage = initialPostsPerPageDesktop;
271
- if (window.innerWidth < 1024) {
272
- devicePostsPerPage = postsPerPageTablet;
273
- deviceInitialPostsPerPage = initialPostsPerPageTablet;
274
- }
275
- if (window.innerWidth < 768) {
276
- devicePostsPerPage = postsPerPageMobile;
277
- deviceInitialPostsPerPage = initialPostsPerPageMobile;
278
- }
279
- watch(
280
- () => modalOpen.value,
281
- () => {
282
- if (modalOpen.value) {
283
- document.body.classList.add("mobile-menu-active");
284
- } else {
285
- document.body.classList.remove("mobile-menu-active");
286
- }
287
- }
288
- );
289
-
290
-
291
- // computed variables
292
- const computedAllPosts = computed(() => {
293
- if (limitPostsToCategories) {
294
- const allSubcategories = [];
295
- const allParentIds = Object.keys(computedCategories.value.subCategories);
296
- allParentIds.forEach((id) => {
297
- computedCategories.value.subCategories[id].forEach((category) => {
298
- allSubcategories.push(category.term_id);
299
- });
300
- });
301
- return filterPosts(allPosts.items, allSubcategories);
302
- } else {
303
- return allPosts.items;
304
- }
305
- });
306
- const computedFilteredPosts = computed(() => {
307
- let computedPosts = computedAllPosts.value;
308
-
309
- const posts = filterPosts(computedPosts, activeFilterCategories.value);
310
- return sortPosts(posts);
311
- });
312
-
313
- const computedLoadMore = computed(() => {
314
- if (showAllPosts) {
315
- return false;
316
- }
317
- let postsPerPage = devicePostsPerPage;
318
- if (page.value == 1) {
319
- postsPerPage = deviceInitialPostsPerPage;
320
- }
321
- if (activeFilterCategories.value.length) {
322
- if (computedFilteredPosts.value.length <= (page.value * postsPerPage)) {
323
- return false;
324
- }
325
- }
326
- if (
327
- page.value * postsPerPage < totalPosts
328
- ) {
329
- return true;
330
- }
331
- return false;
332
- });
333
-
334
- const nextPage = computed(() => {
335
- const path = `https://${window.location.host}${window.location.pathname}`;
336
- return `${path}?pages=${page.value + 1}`;
337
- });
338
-
339
- const resetPage = () => {
340
- const path = `https://${window.location.host}${window.location.pathname}${window.location.search}`;
341
- page.value = 1;
342
- window.history.pushState({}, "", path);
343
- };
344
-
345
-
346
- const computedProducts = computed(() => {
347
- // const updatedProducts = [];
348
- // allProducts.forEach((product) => {
349
- // product.slug = product["post_name"];
350
- // product.name = product["post_title"];
351
- // product.taxonomy = "products";
352
- // updatedProducts.push(product);
353
- // });
354
- // return updatedProducts;
355
- });
356
-
357
- const pagedPosts = computed(() => {
358
- if (showAllPosts) {
359
- return computedFilteredPosts.value;
360
- } else {
361
- return computedFilteredPosts.value.slice(
362
- 0,
363
- page.value == 1
364
- ? Number(deviceInitialPostsPerPage)
365
- : Number(deviceInitialPostsPerPage) +
366
- Number(page.value - 1) * Number(devicePostsPerPage)
367
- );
368
- }
369
- });
370
-
371
- const computedCategories = computed(() => {
372
- let topLevelCategories = [];
373
- const subCategories = {};
374
- allCategories.forEach((taxonomy) => {
375
- if (taxonomy.parent === 0) {
376
- topLevelCategories.push(taxonomy);
377
- } else {
378
- if (subCategories[taxonomy.parent]) {
379
- subCategories[taxonomy.parent].push(taxonomy);
380
- } else {
381
- subCategories[taxonomy.parent] = [];
382
- subCategories[taxonomy.parent].push(taxonomy);
383
- }
384
- }
385
- });
386
- return {
387
- topLevelCategories: topLevelCategories,
388
- subCategories: subCategories,
389
- };
390
- });
391
-
392
- // functions
393
-
394
- const addOrRemoveIdFromActiveFilters = async (categoryId) => {
395
- if (singleActiveFilter.value) {
396
- activeFilterCategories.value = [];
397
- activeFilterCategories.value.push(categoryId);
398
-
399
- return;
400
- }
401
- if (!activeFilterCategories.value.find((element) => Number(element) === Number(categoryId))
402
- ) {
403
- activeFilterCategories.value.push(categoryId);
404
- } else {
405
- activeFilterCategories.value = activeFilterCategories.value.filter(
406
- (element) => element !== categoryId
407
- );
408
- }
409
- };
410
-
411
- const filterPosts = (posts, filterCategoryIds = activeFilterCategories.value) => {
412
- let filteredPosts = [];
413
- if (filterCategoryIds.length === 0) {
414
- filteredPosts = posts;
415
- } else {
416
- filteredPosts = posts.filter((post) => {
417
- const postSubCategories = post.categories.filter(
418
- (category) => category.parent != 0
419
- );
420
- let categoryMatch = false;
421
- filterCategoryIds.forEach((categoryId) => {
422
- if (
423
- postSubCategories.find(
424
- (subCategory) => Number(subCategory.term_id) == Number(categoryId)
425
- )
426
- ) {
427
- categoryMatch = true;
428
- return;
429
- }
430
- });
431
- return categoryMatch;
432
- });
433
- }
434
-
435
- //filter by text
436
-
437
- //Split the search term by , to get 'or' functionality then trim the spaces and filter empty search terms
438
- let searchTerm = textSearchInput.value ? textSearchInput.value : null;
439
- if (searchTerm) {
440
- const searchTerm = searchTerm
441
- .toLowerCase()
442
- .split(",")
443
- .map((term) => term.trim())
444
- .filter((term) => term != "");
445
-
446
- //Filter drinks based on the search terms
447
- const textFilteredPosts = filteredPosts.filter((post) => {
448
- return searchTerm.some((item) =>
449
- post.post_data.post_title.toLowerCase().includes(item)
450
- );
451
- });
452
- }
453
- filteredPosts = searchTerm == null ? filteredPosts : textFilteredPosts;
454
-
455
- return filteredPosts;
456
- };
457
-
458
- const sortPosts = (posts) => {
459
- switch (fields.sorting?.replace("__", "")) {
460
- case "menu-order":
461
- return posts.sort((a, b) => a.menu_order - b.menu_order); // Sort by menu order (ascending)
462
- case "date-desc":
463
- return posts.sort((a, b) => new Date(b.post_data.post_date) - new Date(a.post_data.post_date)); // Newest first
464
- case "date-asc":
465
- return posts.sort((a, b) => new Date(a.post_data.post_date) - new Date(b.post_data.post_date)); // Oldest first
466
- case "postorder":
467
- return posts; // Respect post type order plugin
468
- default:
469
- return posts;
470
- }
471
- };
472
-
473
- const incrementLoadMoreStatus = () => {
474
- const url = new URL(window.location);
475
- loadMoreStatus.value = Number(loadMoreStatus.value) + 1;
476
- url.searchParams.set("pages", loadMoreStatus.value);
477
-
478
- if (!isWpAdmin()) {
479
- window.history.pushState({}, "", url);
480
- }
481
- };
482
-
483
- const postContainerBackgroundColour = (post) => {
484
- switch (postContainerBackgroundColourStyle) {
485
- case "none":
486
- return "none";
487
- break;
488
-
489
- case "colour-palette":
490
- return fields.post_container_background_colour;
491
- break;
492
-
493
- case "post-colour":
494
- return post.post_data.post_colour;
495
- break;
496
- case "post-colour-secondary":
497
- return post.post_data.post_colour_secondary;
498
- break;
499
-
500
- default:
501
- break;
502
- }
503
- };
504
-
505
- const postContainerGradientOverlayColour = (post) => {
506
- switch (fields.gradient_overlay_colour_type?.slice(2)) {
507
- case "colour-palette":
508
- return fields.gradient_overlay_colour;
509
- break;
510
-
511
- case "post-colour":
512
- return post.post_data.post_colour;
513
- break;
514
- case "post-colour-secondary":
515
- return post.post_data.post_colour_secondary;
516
- break;
517
-
518
- default:
519
- break;
520
- }
521
- };
522
-
523
- const getLoadMoreStatusParam = async () => {
524
- const urlParams = new URLSearchParams(window.location.search);
525
- const loadMore = urlParams.get("pages");
526
- if (loadMore) {
527
- loadMoreStatus.value = Number(loadMore);
528
- page.value += loadMoreStatus.value;
529
-
530
- let demandedPosts = Number(initialPostsPerPageDesktop) + (Number(page.value - 1) * Number(postsPerPageDesktop));
531
- let actualMaxPages = Math.ceil(Number((Number(totalPosts.value) - Number(initialPostsPerPageDesktop)) / Number(postsPerPageDesktop)));
532
- let retrievedPosts = Number(initialPostsPerPageDesktop);
533
-
534
- for (let i = 2; i <= loadMore; i++) {
535
- if (retrievedPosts <= totalPosts.value) {
536
- retrievedPosts += Number(postsPerPageDesktop);
537
- page.value = i;
538
- }
539
- }
540
-
541
- if (demandedPosts > totalPosts.value) {
542
- page.value = actualMaxPages;
543
- window.history.pushState({}, "?pages=" + page.value);
544
- }
545
- loadMoreStatus.value = loadMore;
546
- } else {
547
- resetPage();
548
- }
549
- };
550
-
551
- const setupFilterLayout = () => {
552
- if (!showFilters) {
553
- return;
554
- }
555
- if (filterLayout == 1 || filterLayout == 2 || filterLayout == 4 || filterLayout == 5) {
556
- const topLevelCategories = filterBlock.value.querySelectorAll(
557
- ".post-type-filter-grid-v3__filter-category"
558
- );
559
- const primaryCategoryNames = filterBlock.value.querySelectorAll(
560
- ".post-type-filter-grid-v3__filter-top-level-category-name"
561
- );
562
- if (topLevelFiltersActiveOnLoad) {
563
- if (singleActiveTopLevelCategory) {
564
- topLevelCategories[0].classList.add("active");
565
- } else {
566
- topLevelCategories.forEach((topLevelCategory) =>
567
- topLevelCategory.classList.add("active")
568
- );
569
- }
570
- }
571
- primaryCategoryNames.forEach((name) => {
572
- name.addEventListener("click", () => {
573
- name.parentElement.classList.toggle("active");
574
- });
575
- });
576
- if (enableStartingFilter) {
577
- let categoryObject;
578
-
579
- switch (postType) {
580
- case "product":
581
- categoryObject = fields.starting_product_filter_category;
582
- break;
583
- case "person":
584
- categoryObject = fields.starting_person_filter_category;
585
- break;
586
-
587
- default:
588
- break;
589
- }
590
- activeTopLevelCategories.value.push(categoryObject.parent);
591
- activeFilterCategories.value.push(categoryObject.term_id);
592
- }
593
- }
594
- if (filterLayout == 3) {
595
- if (topLevelFiltersActiveOnLoad) {
596
- if (singleActiveTopLevelCategory) {
597
- toggleActiveTopLevelCategory(
598
- computedCategories.value.topLevelCategories[0].term_id
599
- );
600
- } else {
601
- computedCategories.value.topLevelCategories.forEach((topLevelCategory) =>
602
- toggleActiveTopLevelCategory(topLevelCategory.term_id)
603
- );
604
- }
605
- }
606
- }
607
-
608
- if (showFilters) {
609
- filterBlock.value
610
- .querySelector(".post-type-filter-grid-v3__open-filter-toggle")
611
- .addEventListener("click", () => {
612
- modalOpen.value = !modalOpen.value;
613
- });
614
- }
615
- };
616
-
617
- const toggleTopLevelContainerStatus = () => {
618
- topLevelContainerStatus.value = !topLevelContainerStatus.value;
619
- };
620
-
621
- const topLevelCategoryActiveStatus = (id) => {
622
- return activeTopLevelCategories.value.find((catId) => catId == id);
623
- };
624
- const placeholderFilterActiveStatus = () => {
625
- return placeholderFilterStatus.value ? true : false;
626
- };
627
-
628
- const toggleSubcategoryListContainer = (id) => {
629
- if (id == "placeholder") {
630
- activeTopLevelCategories.value = [];
631
- activeFilterCategories.value = [];
632
- return;
633
- }
634
- if (openSubCategoryListContainers.value.find((categoryId) => categoryId == id)) {
635
- openSubCategoryListContainers.value = openSubCategoryListContainers.value.filter(
636
- (categoryId) => categoryId != id
637
- );
638
- } else {
639
- openSubCategoryListContainers.value.push(id);
640
- }
641
- };
642
-
643
- const subCategoryListOpenStatus = (id) => {
644
- return openSubCategoryListContainers.value.find((catId) => catId == id);
645
- };
646
- const updateCategoryButtonActiveStatus = (categoryId) => {
647
- if (
648
- activeFilterCategories.value.find(
649
- (filterCategory) => Number(filterCategory) === Number(categoryId)
650
- )
651
- ) {
652
- return "active";
653
- } else {
654
- return "";
655
- }
656
- };
657
-
658
- const updateActiveCategoryButtonStyle = (categoryId) => {
659
- if (
660
- activeFilterCategories.value.find(
661
- (filterCategory) => Number(filterCategory) === Number(categoryId)
662
- )
663
- ) {
664
- return true;
665
- } else {
666
- return false;
667
- }
668
- };
669
-
670
- const updateDisabledStatus = (categoryId) => {
671
- if (!enableCategoryDisabledStatus.value) {
672
- return false;
673
- }
674
- if (activeFilterCategories.value.length === 0) {
675
- return false;
676
- }
677
- if (
678
- activeFilterCategories.value.find(
679
- (filterCategory) => Number(filterCategory) === Number(categoryId)
680
- )
681
- ) {
682
- return false;
683
- }
684
- const testCategories = [...activeFilterCategories.value];
685
- testCategories.push(categoryId);
686
- const testFilterPosts = filterPosts(allPosts.items, testCategories);
687
- if (testFilterPosts.length <= computedFilteredPosts.value.length) {
688
- return true;
689
- }
690
- };
691
- const getPostSubcategories = (post) => {
692
- return post.categories.filter((category) => category.parent != 0);
693
- };
694
- const clearAllFilters = () => {
695
- activeFilterCategories.value = [];
696
- };
697
- const getCategoryIds = () => {
698
- let allCategoryIds = [];
699
- allCategories.forEach((cat) => {
700
- allCategoryIds.push(cat.term_id);
701
- });
702
- // return JSON.stringify(all_cats);
703
- return allCategoryIds;
704
- };
705
-
706
- const loadMorePosts = async (currentCategoryId = null, { replace = false } = {}) => {
707
-
708
- if (currentCategoryId && loadedCategories.includes(currentCategoryId)) {
709
- console.log('category already loaded');
710
- return;
711
- }
712
-
713
- isLoading.value = true;
714
- let form_data = new FormData();
715
- form_data.append("action", "ptfg_next_page");
716
- form_data.append("pageNum", page.value);
717
- form_data.append("postType", postType);
718
- form_data.append("sorting", sorting);
719
- form_data.append("initialPostsPerPage", initialPostsPerPageDesktop);
720
- form_data.append("desktopPostsPerPage", postsPerPageDesktop);
721
- form_data.append("includeReviews", ptfgData.includeReviews);
722
- form_data.append("reviewDisplayOptions", ptfgData.reviewDisplayOptions);
723
- form_data.append("limitPostsToSelectedCategories", fields.limit_posts_to_selected_categories);
724
- form_data.append("currentMarket", ptfgData.currentMarket);
725
-
726
- form_data.append(
727
- "categoryIds",
728
- activeFilterCategories.value.length > 0 ? activeFilterCategories.value : getCategoryIds()
729
- );
730
-
731
-
732
- form_data.append("initialPostsPerPage", 99999);
733
- if (currentCategoryId && !loadedCategories.includes(currentCategoryId)) {
734
- console.log('category was not yet loaded... getting posts now');
735
- form_data.append("categoryIds", currentCategoryId);
736
- loadedCategories.push(currentCategoryId);
737
- console.log(currentCategoryId, '... added to loaded categories');
738
- }
739
- try {
740
- const response = await fetch(ajaxUrl, {
741
- method: "POST",
742
- body: form_data,
743
- credentials: "same-origin",
744
- });
745
-
746
- if (response.ok) {
747
- const markup = await response.text();
748
- const postData = JSON.parse(markup);
749
- if (replace) {
750
- allPosts.items = sortPosts(postData.posts); // Replace all posts
751
- } else {
752
- const mergedArray = [
753
- ...allPosts.items,
754
- ...postData.posts.filter(item2 => !allPosts.items.some(item1 => item1.id === item2.id)),
755
- ];
756
- allPosts.items = sortPosts(mergedArray); // Merge as usual
757
- }
758
-
759
- isLoading.value = false;
760
- }
761
- } catch (e) {
762
- console.error("Get listing error:", e);
763
- }
764
- };
765
-
766
- const toggleActiveTopLevelCategory = async (id) => {
767
- if (id == "placeholder") {
768
- placeholderFilterStatus.value = true;
769
- activeTopLevelCategories.value = [];
770
- activeFilterCategories.value = [];
771
- return;
772
- }
773
- if (filterLayout == 3) {
774
- if (activeTopLevelCategories.value.find((categoryId) => categoryId == id)) {
775
- activeTopLevelCategories.value = activeTopLevelCategories.value.filter(
776
- (categoryId) => categoryId != id
777
- );
778
- } else {
779
- if (singleActiveTopLevelCategory == 1) {
780
- scrollBackToStart();
781
- activeTopLevelCategories.value = [];
782
- activeTopLevelCategories.value.push(id);
783
- } else {
784
- activeTopLevelCategories.value.push(id);
785
- }
786
- }
787
- }
788
- if (filterLayout == 4 && topLevelContainerStatus.value) {
789
- placeholderFilterStatus.value = false;
790
- activeTopLevelCategories.value = [];
791
- activeTopLevelCategories.value.push(id);
792
- activeFilterCategories.value = [];
793
- activeFilterCategories.value.push(computedCategories.value.subCategories[id][0].term_id);
794
- }
795
- };
796
-
797
- const scrollBackToStart = () => {
798
- const subCategoriesContainer = filterBlock.value.querySelector(
799
- ".post-type-filter-grid-v3__filter-subcategories-container"
800
- );
801
- if (subCategoriesContainer) {
802
- subCategoriesContainer.scrollTo({ left: 0 })
803
- }
804
- }
805
-
806
- onMounted(() => {
807
- getLoadMoreStatusParam();
808
- setupFilterLayout();
809
- loadMorePosts();
810
- });
811
- </script>