<link media="all" rel="stylesheet" href="/assets/themes/default/css/blog-listing.css?cb=">

<div class="blog-listing" data-module="blogListing" data-page-size="2" data-endpoint="/components/preview/blog-listing-api-result" data-search-on-change="false">
    <div class="blog-listing__filter-wrapper">
        <div class="grid_container blog-filter">
            <h2 class="blog-filter__title">Search for a news article</h2>
            <form id="filterForm" name="filterForm">
                <div class="grid-x">
                    <div class="cell">
                        <label for="search-term" class="textfield__label textfield__label--hidden">Term</label>
                        <input type="text" id="search-term" class="textfield__input" placeholder="hint" name="searchTerm" />
                    </div>
                </div>
                <div class="grid-x">
                    <div class="cell">
                        <h3 class="blog-filter__sub-title">Select a category:</h3>
                    </div>
                </div>
                <div class="grid-x">
                    <div class="blog-filter__radio-container">

                        <input id="category-all" type="radio" name="category" value="" checked>
                        <label for="category-all">All categories</label>

                    </div>
                    <div class="blog-filter__radio-container">

                        <input id="category-press-releases" type="radio" name="category" value="Press releases">
                        <label for="category-press-releases">Press releases</label>

                    </div>
                    <div class="blog-filter__radio-container">

                        <input id="category-newsletters" type="radio" name="category" value="Newsletter">
                        <label for="category-newsletters">Newsletter</label>

                    </div>
                    <div class="blog-filter__radio-container">

                        <input id="category-blog" type="radio" name="category" value="Blog">
                        <label for="category-blog">Blog</label>

                    </div>
                </div>
                <div class="grid-x">
                    <div class="cell">

                        <label for="years">Select a year:</label>
                        <select id="years" name="years">
                            <option value="2018">2018</option>
                            <option value="2019">2019</option>
                        </select>
                    </div>
                </div>
                <div class="grid-x">
                    <div class="cell">
                        <button class="primary-cta apply-filter-btn js-apply-filter-button">Search</button>
                    </div>
                </div>
            </form>
        </div>
    </div>
    <div class="blog-listing__featured-wrapper">
        <link media="all" rel="stylesheet" href="/assets/themes/default/css/blog-featured-card.css?cb=">

        <div class="blog-featured">
            <div class="grid-x">
                <div class="blog-featured__image lazy-load-image" data-module="imageLazyLoad">
                    <picture>
                        <source media="(max-width: 840px)" type="image/jpeg" srcset="http://hwr.org.uk/wp-content/uploads/2016/11/placeholder-dark-600-400-729dad18518ecd2cd47afb63f9e6eb09.jpg" />
                        <source media="(min-width: 841px)" type="image/jpeg" srcset="http://hwr.org.uk/wp-content/uploads/2016/11/placeholder-dark-600-400-729dad18518ecd2cd47afb63f9e6eb09.jpg" />
                        <img src="http://hwr.org.uk/wp-content/uploads/2016/11/placeholder-dark-600-400-729dad18518ecd2cd47afb63f9e6eb09.jpg" loading="lazy" alt="">
                    </picture>
                </div>

                <div class="blog-featured__details">
                    <p class="blog-featured__title">
                        Lorem Ipsum
                    </p>

                    <p class="blog-featured__date">
                        20/02/2019
                    </p>

                    <p class="blog-featured__subline">
                        Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum
                    </p>
                    <a href="#" data-module="cta" class="cta blog-featured__cta">
                        Click here
                    </a>
                </div>
            </div>
        </div>
    </div>
    <div class="grid-x align-center blog-listing__section-header">
        <link media="all" rel="stylesheet" href="/assets/themes/default/css/section-header.css?cb=">

        <div class="section-header">
            <h2 class="section-header__title">Section Header</h2>

            <p class="section-header__subline">Section Header subline text lorem ipsum si descomado ipvarat</p>
        </div>
    </div>
    <div class="grid-x grid-padding-x blog-listing__results js-results">
    </div>
    <div class="grid-x blog-listing__load-more-button-container">
        <link media="all" rel="stylesheet" href="/assets/themes/default/css/cta.css?cb=">

        <a href="#" data-module="cta" class="cta secondary-cta blog-listing__load-more-button js-load-more-button" role="button">
            Load more
        </a>
    </div>
</div>
{{#if firstInstance}}
<link media="all" rel="stylesheet" href="/assets/themes/{{theme}}/css/blog-listing.css?cb={{cacheBuster}}">
{{/if}}

<div class="blog-listing" data-module="blogListing" data-page-size="{{pageSize}}" data-endpoint="{{endpoint}}" data-search-on-change="{{filter.searchOnChange}}">
    <div class="blog-listing__filter-wrapper">
        {{> @blog-filter filter }}
    </div>
    {{#if featured}}
    <div class="blog-listing__featured-wrapper">
        {{> @blog-featured-card featured }}
    </div>
    {{/if}}
    {{#if sectionHeader}}
    <div class="grid-x align-center blog-listing__section-header">
        {{> @section-header sectionHeader }}
    </div>
    {{/if}}
    <div class="grid-x grid-padding-x blog-listing__results js-results">
    </div>
    <div class="grid-x blog-listing__load-more-button-container">
        {{> @cta modifier='blog-listing__load-more-button js-load-more-button' isSecondary=true text=loadMoreText url='#' }}
    </div>
</div>
{
  "theme": "default",
  "firstInstance": true,
  "filter": {
    "title": "Search for a news article",
    "searchTermTextField": {
      "id": "search-term",
      "name": "searchTerm",
      "placeholder": "hint",
      "label": "Term",
      "hideLabel": true
    },
    "categoryHeading": "Select a category:",
    "categoryRadioButtons": [
      {
        "id": "category-all",
        "name": "category",
        "label": "All categories",
        "value": ""
      },
      {
        "id": "category-press-releases",
        "name": "category",
        "label": "Press releases",
        "value": "Press releases"
      },
      {
        "id": "category-newsletters",
        "name": "category",
        "label": "Newsletter",
        "value": "Newsletter"
      },
      {
        "id": "category-blog",
        "name": "category",
        "label": "Blog",
        "value": "Blog"
      }
    ],
    "yearsDropDown": {
      "id": "years",
      "name": "years",
      "label": "Select a year:",
      "options": [
        {
          "text": "2018",
          "value": "2018"
        },
        {
          "text": "2019",
          "value": "2019"
        }
      ]
    },
    "text": "Search",
    "searchOnChange": false
  },
  "featured": {
    "firstInstance": true,
    "theme": "default",
    "image": {
      "placeholderImageUrl": "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA",
      "fallbackImageUrl": "http://hwr.org.uk/wp-content/uploads/2016/11/placeholder-dark-600-400-729dad18518ecd2cd47afb63f9e6eb09.jpg",
      "sources": [
        {
          "type": "image/jpeg",
          "desktopImageUrl": "http://hwr.org.uk/wp-content/uploads/2016/11/placeholder-dark-600-400-729dad18518ecd2cd47afb63f9e6eb09.jpg"
        }
      ]
    },
    "category": "Category",
    "date": "20/02/2019",
    "title": "Lorem Ipsum",
    "subline": "Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum",
    "cta": {
      "url": "#",
      "text": "Click here"
    }
  },
  "sectionHeader": {
    "firstInstance": true,
    "theme": "default",
    "title": "Section Header",
    "subline": "Section Header subline text lorem ipsum si descomado ipvarat"
  },
  "endpoint": "/components/preview/blog-listing-api-result",
  "pageSize": "2",
  "loadMoreText": "Load more"
}
  • Content:
    .blog-filter {
        @extend %spacer-medium;
    
        &__title {
            @extend %heading02;
        }
    
        &__sub-title {
            @extend %heading03;
        }
    
        &__radio-container {
            width: 50%;
            @include breakpoint(medium) {
                width: 25%;
            }
        }
    }
    
  • URL: /components/raw/blog-listing/_blog-filter.scss
  • Filesystem Path: source/patterns/03-components/listings/blog-listing/_blog-filter.scss
  • Size: 273 Bytes
  • Content:
    import LazyLoader from '../../../../js/utils/lazy-loader';
    import { getQueryStringParameter, setQueryParams } from '../../../../js/utils/routing';
    
    export class BlogListing {
        constructor(container) {
            this.container = container;
            this.loadMoreButton = this.container.querySelector('.js-load-more-button');
            this.resultsContainer = this.container.querySelector('.js-results');
            this.lazyLoader = new LazyLoader(
                this.container.dataset.endpoint,
                this.container.dataset.pageSize,
                this.loadMoreButton,
                this.resultsContainer,
                null,
                'get',
            );
    
            this.categoryQueryStringParameter = 'category';
            this.searchTermQueryStringParameter = 'searchTerm';
            this.yearQueryStringParameter = 'year';
    
            this.categoryRadioButtons = this.container.querySelectorAll('input[type="radio"]');
            this.yearDropDown = this.container.querySelector('select');
            this.searchTermTextField = this.container.querySelector('input[type="text"]');
            this.init();
        }
    
        init() {
            this.parseQueryParams();
            this.loadData();
    
            if (this.container.dataset.searchOnChange === 'true') {
                let searchTimer;
                this.searchTermTextField.addEventListener('keyup', () => {
                    clearTimeout(searchTimer);
                    searchTimer = setTimeout(() => {
                        this.loadData();
                        setQueryParams(this.searchTermQueryStringParameter, this.searchTermTextField.value);
                    }, 500);
                });
                this.yearDropDown.addEventListener('change', () => {
                    this.loadData();
                    setQueryParams(this.yearQueryStringParameter, this.yearDropDown.value);
                });
                this.categoryRadioButtons.forEach((radio) => {
                    radio.addEventListener('change', () => {
                        this.loadData();
                        setQueryParams(this.categoryQueryStringParameter, radio.value);
                    });
                });
            } else {
                const applyFilterbBtn = this.container.querySelector('.js-apply-filter-button');
                applyFilterbBtn.addEventListener('click', (event) => {
                    event.preventDefault();
                    this.loadData();
                });
            }
    
        }
    
        parseQueryParams() {
            const category = getQueryStringParameter(this.categoryQueryStringParameter);
            const searchTerm = getQueryStringParameter(this.searchTermQueryStringParameter);
            const year = getQueryStringParameter(this.yearQueryStringParameter);
            if (category) {
                this.categoryRadioButtons.forEach((radio) => {
                    const r = radio;
                    r.checked = radio.value === category;
                });
            }
    
            if (searchTerm) {
                this.searchTermTextField.value = searchTerm;
            }
    
            if (year) {
                this.yearDropDown.value = year;
            }
        }
    
        loadData() {
            this.lazyLoader.reset();
            this.lazyLoader.load(BlogListing.getFormData());
        }
    
        static getFormData() {
            const filterForm = document.getElementById('filterForm');
            const formData = new FormData(filterForm);
            return formData;
        }
    }
    
    export default (module) => new BlogListing(module);
    
  • URL: /components/raw/blog-listing/blog-listing.js
  • Filesystem Path: source/patterns/03-components/listings/blog-listing/blog-listing.js
  • Size: 3.4 KB
  • Content:
    @import 'source/scss/01-settings/_import';
    @import 'source/scss/02-tools/_import';
    @import './_blog-filter';
    
    .blog-listing {
        @extend %spacer-large;
        display: flex;
        flex-direction: column;
    
        &__card-wrapper {
            @extend %spacer-large;
    
            @include breakpoint(medium) {
                padding-left: rem(15);
                padding-right: rem(15);
                width: 33.33333%;
            }
        }
    
        &__filter-wrapper {
            @extend %spacer-large;
            width: 100%;
        }
    
        &__featured-wrapper {
            @extend %spacer-large;
            width: 100%;
        }
    
        &__section-header {
            @extend %spacer-large;
            width: 100%;
        }
    
        &__results {
            &.loading {
                @extend %lazy-loader;
            }
        }
    
        &__load-more-button-container {
            justify-content: center;
        }
    }
    
  • URL: /components/raw/blog-listing/blog-listing.scss
  • Filesystem Path: source/patterns/03-components/listings/blog-listing/blog-listing.scss
  • Size: 827 Bytes

No notes defined.