<link media="all" rel="stylesheet" href="/assets/themes/default/css/listing.css?cb=">
<div class="category-listing category-listing--4-columns grid-container" data-module="categoryListing" data-page-size="2" data-endpoint="/components/preview/listing-list-view-api-results?category={0}" data-initial-category="">
<div class="grid-x align-center category-listing__section-header">
<div class="section-header">
<p class="section-header__eyebrow">Section Eyebrow text</p>
<h2 class="section-header__title">Section Header</h2>
</div>
</div>
<div class="grid-x category-listing__filters">
<div class="cell">
<div class="grid_container listing-filter listing-filter--4-buttons">
<div class="listing-filter__button">
<button class="listing-filter__cta js-apply-filter-btn selected" data-category=default>Standard</button>
</div>
<div class="listing-filter__button">
<button class="listing-filter__cta js-apply-filter-btn " data-category=merchants>Merchants</button>
</div>
<div class="listing-filter__button">
<button class="listing-filter__cta js-apply-filter-btn " data-category=blogs>Blogs</button>
</div>
<div class="listing-filter__button">
<button class="listing-filter__cta js-apply-filter-btn " data-category=events>Events</button>
</div>
</div>
</div>
</div>
<div class="grid-x grid-padding-x category-listing__results">
</div>
<div class="grid-x align-center">
<button class="category-listing__load-more-button">Load more</button>
</div>
</div>
{{#if firstInstance}}
<link media="all" rel="stylesheet" href="/assets/themes/{{theme}}/css/listing.css?cb={{cacheBuster}}">
{{/if}}
<div class="category-listing category-listing--{{numberOfColumns}}-columns grid-container" data-module="categoryListing" data-page-size="{{pageSize}}" data-endpoint="{{endpoint}}" data-initial-category="{{initialCategory}}" >
{{#if sectionHeader}}
<div class="grid-x align-center category-listing__section-header">
{{> @section-header sectionHeader }}
</div>
{{/if}}
<div class="grid-x category-listing__filters">
<div class="cell">
{{> @listing-filter filter}}
</div>
</div>
<div class="grid-x grid-padding-x category-listing__results">
</div>
<div class="grid-x align-center">
<button class="category-listing__load-more-button">{{loadMoreText}}</button>
</div>
</div>
{
"theme": "default",
"firstInstance": true,
"filter": {
"listingFilterButtons": [
{
"category": "default",
"text": "Standard"
},
{
"category": "merchants",
"text": "Merchants"
},
{
"category": "blogs",
"text": "Blogs"
},
{
"category": "events",
"text": "Events"
}
]
},
"sectionHeader": {
"title": "Section Header",
"eyebrow": "Section Eyebrow text"
},
"numberOfColumns": 4,
"endpoint": "/components/preview/listing-list-view-api-results?category={0}",
"pageSize": "2",
"loadMoreText": "Load more"
}
.listing-filter {
display: flex;
justify-content: center;
width: 100%;
&--0-buttons,
&--1-buttons {
display: none;
}
&__button {
padding: 0 rem(10);
}
&__cta {
@extend %primary-cta;
&.selected {
@extend %secondary-cta;
pointer-events: none;
}
}
}
import LazyLoader from '../../../../js/utils/lazy-loader';
import format from '../../../../js/utils/string';
import { getQueryStringParameter, setQueryParams } from '../../../../js/utils/routing';
export class CategoryListing {
constructor(container) {
this.container = container;
this.loadMoreButton = this.container.querySelector('.category-listing__load-more-button');
this.resultsContainer = this.container.querySelector('.category-listing__results');
this.filterButtons = this.container.querySelectorAll('.js-apply-filter-btn');
this.categoryQueryStringParameterName = 'category';
this.init();
}
init() {
this.parseQueryParams();
this.setUpLazyLoader();
this.addEventListener();
}
parseQueryParams() {
const category = getQueryStringParameter(this.categoryQueryStringParameterName);
if (category) {
const filterButton = this.container.querySelector(`.js-apply-filter-btn[data-category='${category}']`);
if (filterButton) {
this.resetButtons();
filterButton.classList.add('selected');
}
}
}
setUpLazyLoader() {
this.lazyLoader = new LazyLoader(
this.container.dataset.endpoint,
this.container.dataset.pageSize,
this.loadMoreButton,
this.resultsContainer,
null,
'get',
);
const { endpoint } = this.container.dataset;
const { category } = this.container.querySelector('.js-apply-filter-btn.selected').dataset;
this.endpoint = endpoint;
this.updatedEndPoint = format(this.endpoint, category);
this.lazyLoader.setEndPoint(this.updatedEndPoint);
this.lazyLoader.load();
}
addEventListener() {
this.filterButtons.forEach((btn) => {
btn.addEventListener('click', (event) => {
event.preventDefault();
const button = event.target;
this.resetButtons();
button.classList.add('selected');
const { category } = button.dataset;
this.updatedEndPoint = format(this.endpoint, category);
this.lazyLoader.reset();
this.lazyLoader.setEndPoint(this.updatedEndPoint);
this.lazyLoader.load();
setQueryParams(this.categoryQueryStringParameterName, category);
});
});
}
resetButtons() {
this.filterButtons.forEach((btn) => {
btn.classList.remove('selected');
});
}
}
export default (module) => new CategoryListing(module);
@import 'source/scss/01-settings/_import';
@import 'source/scss/02-tools/_import';
@import './_listing-filter';
.category-listing {
&__section-header {
margin: rem(50) 0;
}
&__filters {
margin-bottom: rem(20);
}
&__no-results {
@extend %p--body;
margin: rem(20) 0;
text-align: center;
width: 100%;
}
&__card-wrapper {
@extend %spacer-large;
width: 100%;
@include breakpoint(medium) {
width: calc(100% / 3);
.category-listing--4-columns & {
width: calc(100% / 4);
}
}
}
&__results {
&.loading {
@extend %lazy-loader;
}
}
&__load-more-button {
@extend %primary-cta;
}
}
No notes defined.