FILTERABLE-LIST-BLUEPRINT (LMU Physik Module )

src/app/shared/components/filterable-list-blueprint/templates

Demo Section

Each variation will be presented in the following section.

Default

Zeige

  Ergebnisse zum Forschen

  • News 2020-05-21 Title Leuchtende Chamäleons

    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam...


Readme

filterableListBlueprint (component)

Description

This blueprint is based on the blueprint of Veams.


Requirements

  • Veams#5.0.0

Installation

Installation with Veams from local machine

veams install bp absolute/filepath/to/filterable-list-blueprint


Fields

filterable-list-blueprint.hbs

The partial is a wrapWith partial. This means that you can access all properties and hashes via props. See Mangony Handlebars Helper - wrapWith for detailed instructions.

Settings

Parameter Type Default Description
settings.filterableListBlueprintClasses String '' Modifier classes for component
settings.filterableListBlueprintContextClass String 'default' Context class of component

Content

Parameter Type Description
content.filterableListBlueprintField String Please add a description!

SASS

Variables

There are multiple variables which you can change:

Variable Value Description
$filterable-list-blueprint-my-custom-var 0px Please add a description!

Modifier Classes

There are modifier classes you can add to c-filterable-list-blueprint:

Modifier Description
is-modifier Please add a description!

Templates

filterable-list-blueprint.hbs

<div class="c-filterable-list-blueprint{{#if settings.filterableListblueprintContextClass}}--{{settings.filterableListblueprintContextClass}}{{else}}--default{{/if}}{{#if settings.filterableListblueprintClasses}} {{settings.filterableListblueprintClasses}}{{/if}}"
     data-css="c-filterable-list-blueprint"
     data-js-module="filterable-list-blueprint">

	{{#wrapWith "grid__container"}}
		{{#wrapWith "grid__row"}}
			{{#with content.filterForm}}

				<form class="{{settings.formClasses}} {{settings.formJsOptions.classes.loading}}"
					action="{{settings.formActionQA}}"
					method="{{settings.formMethod}}"
					data-js-item="{{settings.formJsItem}}">

					{{#each content.fieldsets}}
						{{> form__fieldset}}
					{{/each}}

					<!-- Results Info -->
					<div class="filterable-list-blueprint__results-info" data-js-item="js-filterable-list-blueprint-results-info">
                    	<p><strong><span data-js-item="js-filterable-list-blueprint__total-item-count">&nbsp;</span> {{{settings.formContent.i18n.resultsText}}}</strong></p>
                    </div>

					<!-- Loader -->
					<div class="filterable-list-blueprint__results-loader" data-js-item="js-filterable-list-blueprint-results-loader">
						<span class="filterable-list-blueprint__results-loader-box is-one"></span>
						<span class="filterable-list-blueprint__results-loader-box is-two"></span>
						<span class="filterable-list-blueprint__results-loader-box is-three"></span>
					</div>

					<!-- Template for Results -->
					<ul class="filterable-list-blueprint__results-template">
						<li class="filterable-list-blueprint__results-item" data-js-item="js-filterable-list-blueprint-results-template">
                        	<div class="filterable-list-blueprint__results-item-image">
                        		<picture class="c-picture--default lazyloaded" data-css="c-picture">
                                	<img src="" class="picture__image lazyautosizes lazyloaded" alt="">
                                </picture>
                        	</div>
                        	<div class="filterable-list-blueprint__results-item-text-wrapper">
								<em class="filterable-list-blueprint__results-item-meta">
									<span class="filterable-list-blueprint__results-item-meta-category">{{settings.resultTemplateContent.category}}</span>
									<span class="filterable-list-blueprint__results-item-meta-date">{{settings.resultTemplateContent.date}}</span>
								</em>
								<a href="" class="filterable-list-blueprint__results-item-link">{{settings.resultTemplateContent.title}}</a>
								<p class="filterable-list-blueprint__results-item-description">{{settings.resultTemplateContent.description}}</p>
								<a href="" class="filterable-list-blueprint__a11y-clickarea" aria-hidden="true" tabindex="-1"></a>
							</div>
                        </li>
					</ul>

					<!-- Results -->
					<ul class="filterable-list-blueprint__results" data-js-item="js-filterable-list-blueprint-results">
					</ul>

					<!-- Load More Button -->
					<div class="filterable-list-blueprint__load-more-wrapper is-loading">
                    	<button type="submit" class="filterable-list-blueprint__load-more" data-js-item="js-filterable-list-blueprint-load-more-btn">
							<span class="filterable-list-blueprint__load-more-loader">
								<span class="filterable-list-blueprint__load-more-loader-box is-one"></span>
								<span class="filterable-list-blueprint__load-more-loader-box is-two"></span>
								<span class="filterable-list-blueprint__load-more-loader-box is-three"></span>
							</span>
                    	<span class="filterable-list-blueprint__load-more-text">{{settings.loadMoreLabel}}</span></button>
                    </div>

				</form>

			{{/with}}
		{{/wrapWith}}
	{{/wrapWith}}

</div>

Data File

filterable-list-blueprint.hjson

{
	"variations": {
		"default": {
			"docs": {
				"variationName": "Default"
			},
			"settings": {
				"filterableListContextClass": "default",
				"filterableListClasses": ""
			},
			"content": {
				"filterForm": {
					"settings": {
						"formClasses": "c-filterable-list-blueprint--form",
						"formContextClass": "filterable-list",
						"formJsOptions": {
							"classes": {
								"loading": "is-loading"
							},
							"submitOnChange": true
						},
						"formJsItem": "js-filterable-list-blueprint-filter-form",
						"formAction": "//localhost:3000/api/connector/get",
						"formActionQA": "//localhost:3000/mocks/connector/getFilterableListBlueprint.json",
						"formMethod": "GET",
						"formAjax": true,
						"formContent": {
							"i18n": {
								"loadMore": "Mehr laden",
								"noResultsText": "<strong>Es wurden keine Ergebnisse gefunden</strong>",
								"resultsText": "Ergebnisse zum  <span data-js-item=\"js-filterable-list-blueprint__total-item-tag-name\"></span> Forschen",
								"showAll": "Alle anzeigen"
							}
						},
						"resultTemplateContent": {
							"category": "News",
							"date": "2020-05-21",
							"title": "Title Leuchtende Chamäleons",
							"description": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam...",
							"link": ""
						},
						"loadMoreLabel": "Show More"
					},
					"content": {
						"fieldsets": [
							{
								"settings": {
									"fieldsetClasses": "is-small",
									"legendClasses": "is-col-mobile-p-12 is-hidden"
								},
								"content": {
									"legend": "Radio Buttons",
									"rows": [
										{
											"settings": {
												"rowClasses": ""
											},
											"content": {
												"cols": [
													{
														"settings": {
															"radioClasses": "is-inline-block is-filternav",
															"colClasses": "is-text-align-right",
															"inputClasses": "is-radios",
															"labelWrapperClasses": "",
															"radioWrapperClasses": "",
															"legendClasses": "",
															"id": "category",
															"required": false,
															"typeOf": "radio"
														},
														"content": {
															"label": "Zeige",
															"radios": [
																{
																	"settings": {
																		"wrapperClass": "is-radio-wrapper",
																		"inputClass": "",
																		"required": false,
																		"dataAttr": false,
																		"id": "tag-one",
																		"labelClass": "",
																		"name": "radio-group"
																	},
																	"content": {
																		"label": "Tag One"
																	}
																},
																{
																	"settings": {
																		"wrapperClass": "is-radio-wrapper",
																		"inputClass": "",
																		"required": false,
																		"dataAttr": false,
																		"id": "tag-two",
																		"labelClass": "",
																		"name": "radio-group"
																	},
																	"content": {
																		"label": "Tag Two"
																	}
																},
																{
																	"settings": {
																		"wrapperClass": "is-radio-wrapper",
																		"inputClass": "",
																		"required": false,
																		"dataAttr": false,
																		"id": "tag-three",
																		"labelClass": "",
																		"name": "radio-group"
																	},
																	"content": {
																		"label": "Tag Three"
																	}
																},
																{
																	"settings": {
																		"wrapperClass": "is-radio-wrapper",
																		"inputClass": "",
																		"required": false,
																		"dataAttr": false,
																		"id": "key-all",
																		"labelClass": "",
																		"name": "radio-group"
																	},
																	"content": {
																		"label": "All"
																	}
																}
															]
														}
													}
												]
											}
										}
									]
								}
							}
						]
					}
				}

			}
		}
	}
}

Styles

filterable-list-blueprint.scss

/* ===================================================
component: filterable-list-blueprint
=================================================== */

/* ---------------------------------------------------
Global Styles
--------------------------------------------------- */
[data-css="c-filterable-list-blueprint"] {
}

/* ---------------------------------------------------
Context: Default
--------------------------------------------------- */
.c-filterable-list-blueprint--default {

	h2 {
		@include headline-h2-styles();
	}

	p.title-description {
		@include content-p-styles();

		margin-bottom: 50px;
	}

	.c-filterable-list-blueprint--form {
		position: relative;
		min-height: 400px;

		&.is-loading {

			.filterable-list-blueprint__results-loader {
				opacity: 1;
			}

			.filterable-list-blueprint__results {
				height: 0;
				opacity: 0;
				overflow: hidden;
			}

			.filterable-list-blueprint__result-error {
				height: 0;
				opacity: 0;
			}
		}

		&.is-success {

			.filterable-list-blueprint__results-loader {
				z-index: -1;
				opacity: 0;
			}

			.filterable-list-blueprint__results {
				height: auto;
				opacity: 1;
			}

			.filterable-list-blueprint__result-error {
				height: 0;
				opacity: 0;
			}
		}

		&.is-error {

			.filter-course-finder__results-loader {
				z-index: -1;
				opacity: 0;
			}

			.filter-course-finder__results {
				height: 0;
				opacity: 0;
				overflow: hidden;
			}

			.filter-course-finder__result-error {
				height: auto;
				opacity: 1;
			}
		}
	}

	.form__row {
		border-bottom: 1px solid $color-gray;
		padding-bottom: 2px;
		margin-bottom: 25px;

		.is-inline-block {
			width: 100%;

			@include bp($bp-tablet-p) {
				width: auto;
			}
		}
	}

	.form__radio-input {
		@extend %visuallyhidden;

		@include hcm() {
			border: 1px solid $color-white;
			margin: 6px 0 0;
			clip: auto;
			position: relative;
			float: left;

			& ~ .form__radio-label {
				margin-left: 28px;
				padding-left: 0;
				width: auto;
				display: block;

				&::before {
					display: none !important;
				}
			}
		}

		&:checked {

			& ~ .form__radio-label {

				&::before {
					box-shadow: inset 0 0 0 10px $color-green;
					border: 0;
					width: 28px;
					height: 28px;
				}
			}

			&.a11y-focus-key {

				& ~ .form__radio-label {

					&::before {
						@include pseudo();
						border: 2px dashed #800;
					}
				}
			}
		}
	}

	.form__radio-label {
		position: relative;
		display: inline-block;
		padding: 2px 0 5px 42px;
		font-family: $font-bold;
		color: $color-dark;
		font-size: 1.6rem;
		line-height: (24/16);
		letter-spacing: .3px;

		&:hover {
			cursor: pointer;
		}

		&::before {
			content: "";
			width: 24px;
			height: 24px;
			display: inline-block;
			position: absolute;
			top: 0;
			left: 0;
			background: $color-white;
			border-radius: 50%;
			border: 2px solid $color-green;
		}
	}

	/*
	Labels & Types
	----------------------- */
	.is-filternav {
		// Radio
		.form__radio-wrapper,
		.form__label-wrapper{
			display: block;
			float: left;
			width: 100%;

			@include bp($bp-tablet-p) {
				display: inline;
				width: auto;
			}
		}

		.form__radio-list {
			width: 100%;
			margin-left: 0;
			margin-bottom: 0;
		}

		.form__radio-item {
			display: inline-block;
			margin-left: 0;
			margin-right: 0;
			margin-bottom: 0;
			padding-left: 0;

			&:before {
				content: none;
			}

			&:last-of-type {

				.form__radio-label {
					border-right: none;

					@include bp($bp-tablet-p) {
						padding-right: 0;
					}
				}
			}

			.form__radio-label {
				margin-bottom: 0;
			}
		}

		.form__radio-legend {
			color: $color-dark;
			margin-right: 10px;
			font-size: 1.7rem;
			line-height: (20/17);
			letter-spacing: .25px;
			margin-bottom: 10px;
			display: block;
			text-align: left;

			@include bp($bp-tablet-p) {
				font-size: 1.8rem;
				line-height: (21/18);
				letter-spacing: .27px;
				margin-bottom: 0;
				text-align: right;
			}

			@include bp($bp-desktop-l) {
				font-size: 2rem;
				line-height: (24/20);
				letter-spacing: .3px;
			}
		}

		.form__radio-input {
			@include hcm() {
				@extend %visuallyhidden;
			}

			&:checked {

				& ~ .form__radio-label {
					background-color: $color-green;
					color: $color-white;

					@include bp($bp-tablet-p) {
						background-color: transparent;
						color: $color-dark;
					}

					@include print() {
						text-decoration: underline;
					}

					@include hcm() {
						text-decoration: underline;
					}
				}
			}

			&.a11y-focus-key {

				& ~ .form__radio-label {
					@include a11y-focus-key();

					&::before {
						display: none;
					}
				}
			}
		}

		.form__radio-label {
			background-color: $color-light;
			font-family: $font-bold;
			color: $color-green;
			padding: 6px 12px;
			font-size: 1.7rem;
			line-height: (20/17);
			letter-spacing: .25px;
			margin-bottom: 5px;

			@include bp($bp-tablet-p) {
				background-color: transparent;
				border-right: 1px solid $color-dark;
				font-size: 1.8rem;
				padding: 0 20px;
				line-height: (21/18);
				letter-spacing: .27px;
			}

			@include bp($bp-desktop-l) {
				font-size: 2rem;
				line-height: (24/20);
				letter-spacing: .3px;
			}

			&::before {
				display: none;
			}
		}
	}

	.filterable-list-blueprint__total-item-count {
		display: inline-block;
	}

	.filterable-list-blueprint__results {
		@include grid-column(12);

		@include bp($bp-tablet-l) {
			@include grid-column(10);
			@include grid-push-h(1);
		}

		@include bp($bp-desktop-l) {
			@include grid-column(8);
			@include grid-push-h(2);
		}
	}

	.filterable-list-blueprint__results-info {
		@include headline-h3-styles();

		font-family: $font-regular;
		font-weight: 400;
		padding-bottom: 20px;

		p {
			font-family: $font-regular;
			font-weight: 400;
			display: inline-block;

			strong {
				font-family: $font-bold;
			}
		}
	}

	.filterable-list-blueprint__results-item {
		@include clearfix();

		display: flex;
		width: 100%;
		flex-direction: row;
		flex-wrap: wrap;
		margin-bottom: 30px;
		padding-bottom: 30px;
		padding-left: 0;
		border-bottom: 1px solid $color-gray-border;
		position: relative;
		opacity: 1;
		transform: translate3d(0, 0, 0);
		transition: opacity 2 * $animation-duration-std $animation-easing-std,
		transform 2 * $animation-duration-std $animation-easing-std;

		&::before {
			content: none;
		}

		&:hover {

			.filterable-list-blueprint__results-item-link {
				color: $color-dark;

				&::before {
					@include sprites-icon-arrow-black();

					transform: translateX(5px);
				}

				/*
				MODIFIERS
				----------------------- */
				&.is-publication,
				&.is-download {

					&::before {
						@include sprites-icon-download-black();
					}
				}
			}

			.filterable-list-blueprint__results-item-dates {
				background-color: $color-white;
				border: 1px solid $color-green;
			}

			.filterable-list-blueprint__results-item-date-month,
			.filterable-list-blueprint__results-item-date-day,
			.filterable-list-blueprint__results-item-date-connect {
				color: $color-green;
			}

			.filterable-list-blueprint__results-item-image {
				/*
				MODIFIERS
				----------------------- */
				&.is-publication,
				&.is-gallery,
				&.is-video {

					&::before {
						opacity: 0;
					}

					&::after {
						opacity: 1;
					}
				}
			}
		}

		&:focus {
			outline: none;
		}

		/*
		MODIFIERS
		----------------------- */
		&:last-of-type {
			border-bottom: none;
		}

		&.is-loading {
			opacity: 0;
			transform: translate3d(0, 50%, 0);
		}
	}

	.filterable-list-blueprint__results-item-image {
		display: none;
		position: relative;

		@include bp($bp-tablet-p) {
			display: block;
			width: 110px;
			height: 110px;
			flex: 0 0 110px;
			margin-right: 30px;
		}

		@include bp($bp-tablet-l) {
			width: 148px;
			height: 148px;
			flex: 0 0 148px;
		}

		@include bp($bp-desktop-l) {
			width: 206px;
			height: 206px;
			flex: 0 0 206px;
			margin-right: 40px;
		}

		&::before,
		&::after {
			@include pseudo();

			position: absolute;
			right: 0;
			bottom: 0;
			display: block;
			z-index: 2;
			transition: opacity $animation-duration-std $animation-easing-std;
		}

		&::before {
			opacity: 1;
		}

		&::after {
			opacity: 0;
		}

	}

	.filterable-list-blueprint__results-item-text-wrapper {
		display: block;
		position: relative;
		flex: 1 1;
	}

	.filterable-list-blueprint__results-item-meta {
		display: block;
		color: $color-gray;
		font-size: 1.5rem;
		line-height: (20/15);
		letter-spacing: 1px;
		text-transform: uppercase;
		margin-bottom: 15px;
		font-family: $font-regular;
	}

	.filterable-list-blueprint__results-item-meta-category + .filterable-list-blueprint__results-item-meta-date {

		&::before {
			@include pseudo();

			position: relative;
			display: inline-block;
			vertical-align: middle;
			width: 3px;
			height: 3px;
			background-color: $color-gray;
			border-radius: 50%;
			margin: -3px 7px 0 4px;
		}
	}

	.filterable-list-blueprint__results-item-link {
		color: $color-green;
		font-family: $font-bold;
		font-size: 1.6rem;
		line-height: (24/16);
		letter-spacing: .3px;
		margin-bottom: 12px;
		text-decoration: none;
		display: block;
		transition: color $animation-duration-std/2 $animation-easing-std;
		position: relative;
		padding-left: 25px;

		@include print() {
			padding-left: 0;
		}

		&:focus {
			outline: none;
		}

		&:hover,
		&:focus {
			color: $color-dark;

			&::before {
				@include sprites-icon-arrow-black();

				transform: translateX(5px);
			}
		}

		&::before {
			@include pseudo();
			@include sprites-icon-arrow-green100();

			position: absolute;
			display: inline-block;
			top: 5px;
			left: 0;
			margin-right: 10px;
			vertical-align: unset;
			transition: transform $animation-duration-std $animation-easing-std;

			@include print() {
				display: none;
			}
		}

	}

	.filterable-list-blueprint__results-item-description {
		display: block;
		font-size: 1.6rem;
		line-height: (24/16);
		letter-spacing: .25px;
		color: $color-dark;
		margin-bottom: 0;

		a {
			font-family: $font-bold;
			font-weight: 700;
			color: $color-green;
			text-decoration: none;
			transition: color $animation-duration-std $animation-easing-std;

			&:focus {
				outline: none;
			}

			&:hover,
			&:focus {
				color: $color-dark;
			}
		}

		strong {
			font-family: $font-bold;
		}
	}

	.filterable-list-blueprint__a11y-clickarea {
		@include clickarea();

		z-index: 3;
	}

	.filterable-list-blueprint__tag-template {
		display: none;

		&+label {
			display: none;
		}
	}

	.filterable-list-blueprint__results-template {
		display: none;
	}

	.filterable-list-blueprint__load-more-wrapper {
		width: 100%;
		height: auto;
		display: block;
		text-align: center;
		position: relative;
		clear: both;
		opacity: 1;
		transform: translate3d(0, 0, 0);
		transition: opacity 2 * $animation-duration-std $animation-easing-std,
		transform 2 * $animation-duration-std $animation-easing-std;

		@include print() {
			display: none;
		}

		&::before {
			@include pseudo();
			@include centering(v);

			position: absolute;
			width: 100%;
			height: 1px;
			border-top: 1px solid $color-gray-light;
			margin-top: 1px;
		}

		&.is-loading {
			height: 0;
			overflow: hidden;
			opacity: 0;
			transform: translate3d(0, 50%, 0);
		}
	}

	.filterable-list-blueprint__load-more {
		@include reset-btn();

		padding: 10px 30px;
		min-width: 275px;
		display: inline-block;
		text-align: center;
		background-color: $color-green;
		cursor: pointer;
		position: relative;
		transition: background-color $animation-duration-std
		$animation-easing-std;

		@include bp($bp-desktop-l) {
			padding: 18px 30px;
		}

		&:focus {
			outline: none;
		}

		&:hover,
		&.a11y-focus-key {
			background-color: $color-white;

			.filterable-list-blueprint__load-more-text {
				color: $color-green;

				&::before,
				&::after {
					background-color: $color-green;
				}
			}

			&::before {
				opacity: 1;
			}
		}

		&::before {
			@include pseudo();

			position: absolute;
			width: calc(100% - 2px);
			height: calc(100% - 2px);
			border: 1px solid $color-green;
			display: block;
			z-index: 2;
			top: 0;
			left: 0;
			opacity: 0;
			transition: opacity $animation-duration-std $animation-easing-std;
		}
	}

	.filterable-list-blueprint__load-more-text {
		color: $color-white;
		font-size: 1.6rem;
		line-height: (24/16);
		letter-spacing: .3px;
		font-family: $font-bold;
		display: inline-block;
		transition: color $animation-duration-std $animation-easing-std;
		position: relative;
		padding-left: 25px;

		&::before {
			@include pseudo();

			width: 15px;
			height: 3px;
			display: block;
			background-color: $color-white;
			position: absolute;
			left: 0;
			top: 10px;
			transition: background-color $animation-duration-std
			$animation-easing-std;
		}

		&::after {
			@include pseudo();
			@include centering(v);

			width: 3px;
			height: 15px;
			display: block;
			background-color: $color-white;
			position: absolute;
			top: 11px;
			left: 6px;
			transition: background-color $animation-duration-std
			$animation-easing-std;
		}
	}

	.filterable-list-blueprint__results-loader {
		@include centering(h);

		position: absolute;
		top: 200px;
		display: flex;
		width: 200px;
		flex-direction: row;
		background-color: $color-white;
		height: 60px;
		align-items: center;
		justify-content: center;
		pointer-events: none;
		opacity: 0;
		transition: opacity $animation-duration-std $animation-easing-std;
		z-index: 100;
		border: 1px solid $color-green;
	}

	.filterable-list-blueprint__results-loader-box {
		display: block;
		margin: 10px;
		border: 1em solid $color-green;
		opacity: 0;

		/*
		MODIFIERS
		----------------------- */
		&.is-one {
			animation: boxAppear 2s linear infinite;
		}

		&.is-two {
			animation: boxAppear 2s linear .3s infinite;
		}

		&.is-three {
			animation: boxAppear 2s linear .62s infinite;
		}
	}

	// LOAD MORE LOADER
	.filterable-list-blueprint__load-more-loader {
		@include centering(hv);

		position: absolute;
		display: flex;
		flex-direction: row;
		background-color: $color-green;
		z-index: 2;
		width: calc(100% - 2px);
		height: 100%;
		align-items: center;
		justify-content: center;
		pointer-events: none;
		opacity: 0;
		transition: opacity $animation-duration-std $animation-easing-std;

		&.is-loading {
			opacity: 1;
		}
	}

	.filterable-list-blueprint__load-more-loader-box {
		display: block;
		margin: 10px;
		border: 1em solid $color-white;
		opacity: 0;

		/*
		MODIFIERS
		----------------------- */
		&.is-one {
			animation: boxAppear 2s linear infinite;
		}

		&.is-two {
			animation: boxAppear 2s linear .3s infinite;
		}

		&.is-three {
			animation: boxAppear 2s linear .62s infinite;
		}
	}

}

Scripts

filterable-list-blueprint.js

/**
 * Description of FilterableListBlueprint.
 * Class properties and decorators are supported.
 *
 * @module FilterableListBlueprint
 * @version v1.0.0
 *
 * @author your_name
 */

// Imports
import $ from 'jquery';
import Component from '@veams/component';

class FilterableListBlueprint extends Component {
	/**
	* Class Properties
	*/
	$el = $(this.el);
	$filterForm = $(this.options.selectors.filterForm, this.el);
	$lang = document.getElementsByTagName("HTML")[0].getAttribute("lang") ? document.getElementsByTagName("HTML")[0].getAttribute("lang").toUpperCase() : 'DE';
	$data = '';
	$totalResults = 0;
	$lastResult = 0;
	$resultPerPage = 10;
	$resultPerPageCounter = this.$resultPerPage;
	$counterResults = 1;
	$resultTemplate = document.querySelector(this.options.selectors.resultTemplate);

	/**
	 * Constructor for our class
	 *
	 * @see module.js
	 *
	 * @param {Object} obj - Object which is passed to our class
	 * @param {Object} obj.el - element which will be saved in this.el
	 * @param {Object} obj.options - options which will be passed in as JSON object
	 */
	constructor(obj) {
		let options = {
			selectors: {
				filterForm: '[data-js-item="js-filterable-list-blueprint-filter-form"]',
				resultTemplate: '[data-js-item="js-filterable-list-blueprint-results-template"]',
				resultsList: '[data-js-item="js-filterable-list-blueprint-results"]',
				totalResults: '[data-js-item="js-filterable-list-blueprint__total-item-count"]',
				tagName: '[data-js-item="js-filterable-list-blueprint__total-item-tag-name"]',
				btnLoadMore: '[data-js-item="js-filterable-list-blueprint-load-more-btn"]',
				resultsLoader: '[data-js-item="js-filterable-list-blueprint-results-loader"]',
				loadMoreLoader: '.filterable-list-blueprint__load-more-loader',

				keyAll: 'key-all'
			},
			classes: {
				isSuccess: 'is-success',
				isError: 'is-error',
				isLoading: 'is-loading'
			}
		};

		super(obj, options);
	}

	/**
	* Lifecycle Hooks
	*/
	willMount() {
		console.log('Component FilterableListBlueprint will mount!');
	}

	didMount() {
		console.log('Component FilterableListBlueprint mounted!');
	}

	/**
	 * @desc Debounce a function for a specific time
	 */
	bindEvents() {

		this.options.filterForm = document.querySelector(
			this.options.selectors.filterForm
		);

		this.options.resultsList = this.options.filterForm.querySelector(
			this.options.selectors.resultsList
		);

		this.options.btnLoadMore = this.options.filterForm.querySelector(
			this.options.selectors.btnLoadMore
		);

		this.options.tagName = this.options.filterForm.querySelector(
			this.options.selectors.tagName
		);

		this.getAndFillMyResults();

		// Click on LoadMore Button
		this.options.btnLoadMore.addEventListener('click', (ev) => {
			ev.preventDefault();
			this.options.btnLoadMore.querySelector(this.options.selectors.loadMoreLoader).classList.add(this.options.classes.isLoading);
			setTimeout(() => {
				this.options.btnLoadMore.parentElement.classList.add(this.options.classes.isLoading);
				this.$lastResult += 1;
				this.$resultPerPageCounter = this.$resultPerPageCounter + this.$resultPerPage;
				this.populateResults(false);
				this.options.btnLoadMore.querySelector(this.options.selectors.loadMoreLoader).classList.remove(this.options.classes.isLoading);
			}, 250);
		});
	}

	/**
	 * @desc Get data from JSON and fill in function initializationForm
	 */
	getAndFillMyResults() {
		const uri = this.$filterForm[0].action;

		if (uri) {
			this.getJSON(uri, (data) => {
				const results = data;
				if (typeof results !== 'undefined') this.initializationForm(results);
			});
		}
	}

	/**
	 * @desc Data initialization
	 * @param {String} data - Results from JSON file
	 */
	initializationForm(data) {
		this.$data = data;

		// Print Results List
		this.populateResults(true);
	}

	/**
	 * @desc Checking is the first iteration or not
	 * @param {Boolean} firstIteration - Status of first iteration: yes (true) or no (false)
	 */
	populateResults(firstIteration) {
		// Fill from URL
		const urlOptions = decodeURI(window.location.href.split('?')[1]).split('&');
		let keyFromUrl = '';
		if (urlOptions[0] !== 'undefined') {
			urlOptions.forEach((key) => {
				const option = key.split('=');
				if (option[0] === 'keyIdentifier' && option[1] !== this.options.selectors.keyAll) {
					keyFromUrl = option[1];
				}
				if (this.options.filterForm.querySelector(`input[value="${option[1]}"]`)) {
					this.options.filterForm.querySelector(`input[value="${option[1]}"]`).checked = true;
				}
			});
		}

		this.objectOrArrayToArray(this.$data[this.$lang]).forEach((item, index) => {
			if (keyFromUrl) {
				this.objectOrArrayToArray(item.tags).forEach((key) => {
					if (keyFromUrl === key.identifier) {
						this.createResultItem(item, index, firstIteration);
					}
				});
			} else {
				this.createResultItem(item, index, firstIteration);
			}
		});

		this.options.tagName.innerHTML = this.options.filterForm.querySelector(`label[for="${this.options.selectors.keyAll}"]`).innerHTML;
		this.options.filterForm.querySelector(this.options.selectors.totalResults).innerHTML = this.$totalResults;

		this.clickOnFilterTag();
		this.loadingProcess();
	}

	/**
	 * @desc Creating a single result
	 * @param {String} item - Result
	 * @param {Number} index - Index of item
	 * @param {Boolean} firstIteration - Status of first iteration: yes (true) or no (false)
	 */
	createResultItem(item, index, firstIteration) {
		if (this.$counterResults <= this.$resultPerPageCounter && this.$lastResult <= index) {

			const result = this.$resultTemplate.cloneNode(true);
			const date = new Date(item.date).toLocaleString(`${this.$lang.toLowerCase()}-${this.$lang}`, {
				year: 'numeric',
				month: '2-digit',
				day: '2-digit'
			});

			result.removeAttribute('data-js-item');
			result.classList.remove('filterable-list-blueprint__results-template');
			result.classList.add(this.options.classes.isLoading);

			if (item.category && result.querySelector('.filterable-list-blueprint__results-item-meta-category')) {
				result.querySelector('.filterable-list-blueprint__results-item-meta-category').innerHTML = this.arrayToString(item.category);
			}
			result.querySelector('.filterable-list-blueprint__results-item-meta-date').innerHTML = this.arrayToString(date);
			result.querySelector('.filterable-list-blueprint__results-item-link').innerHTML = this.arrayToString(item.title);
			result.querySelector('.filterable-list-blueprint__results-item-description').innerHTML = this.arrayToString(item.teaserText);

			result.querySelector('.filterable-list-blueprint__results-item-link').setAttribute('href', item.link);
			result.querySelector('.filterable-list-blueprint__a11y-clickarea').setAttribute('href', item.link);

			if (item.teaserImage) {
				result.querySelector('picture img').setAttribute('alt', item.teaserImage.alt);
				result.querySelector('picture img').setAttribute('src', item.teaserImage.src);
				result.querySelector('picture img').setAttribute('title', item.teaserImage.title ? item.teaserImage.title : '');
			}

			this.options.resultsList.appendChild(result);

			this.$lastResult = index;
			this.$counterResults += 1;
		}

		firstIteration ? this.$totalResults += 1 : '';
	}

	/**
	 * @desc Filter Tag click-related processes
	 */
	clickOnFilterTag() {
		this.options.filterLabel = [].slice.call(
			this.options.filterForm.querySelectorAll('label')
		);

		this.options.filterLabel.forEach((label) => {
			label.addEventListener('click', (ev) => {
				this.el.querySelector('form').classList.remove(this.options.classes.isSuccess);
				this.el.querySelector('form').classList.add(this.options.classes.isLoading);
				this.options.btnLoadMore.parentElement.classList.add(this.options.classes.isLoading);

				this.$counterResults = 1;
				this.$totalResults = 0;
				this.$lastResult = 0;
				this.$resultPerPageCounter = this.$resultPerPage;
				this.options.btnLoadMore.parentElement.style.display = 'block';

				// Empty
				this.options.resultsList.innerHTML = '';

				this.objectOrArrayToArray(this.$data[this.$lang]).forEach((item, index) => {
					if (label.parentElement.firstElementChild.value === this.options.selectors.keyAll) {
						this.createResultItem(item, index, true);
					} else {
						this.objectOrArrayToArray(item.tags).forEach((key) => {
							if (label.parentElement.firstElementChild.value === key.identifier) {
								this.createResultItem(item, index, true);
							}
						});
					}
				});

				this.options.tagName.innerHTML = ev.target.innerHTML;

				let output = `keyIdentifier=${label.parentElement.firstElementChild.value}`;
				history.pushState(output, 'Search history', `${window.location.href.split('?')[0]}?${output}`);

				this.options.filterForm.querySelector(this.options.selectors.totalResults).innerHTML = this.$totalResults;

				this.loadingProcess();
			});
		});
	}

	/**
	 * @desc Processes related to data loading
	 */
	loadingProcess() {
		setTimeout(() => {
			const liElements = [].slice.call(this.options.resultsList.querySelectorAll('li'));

			liElements.forEach((item) => {
				item.classList.remove(this.options.classes.isLoading);
			});

			this.el.querySelector('form').classList.remove(this.options.classes.isLoading);
			this.el.querySelector('form').classList.add(this.options.classes.isSuccess);

			this.$totalResults <= this.$resultPerPageCounter ? this.options.btnLoadMore.parentElement.style.display = 'none' : '';
			this.options.btnLoadMore.parentElement.classList.remove(this.options.classes.isLoading);
		}, 250);
	}

	/**
	 * @desc Convert Array to String
	 * @param {Array} item - Array
	 * @return {String} - String
	 *
	 */
	arrayToString = (item) => {
		item = item ? item.toString() : '';
		return item;
	}

	/**
	 * @desc JSON request
	 * @param {Object} url - Link to JSON file
	 * @param {Object} callback - For results
	 * @param {Object} requestHeader - For request with Header like user, pass, type...
	 * @return {callback} - Return callback
	 *
	 */
	getJSON = (url, callback, requestHeader) => {
		const xhr = new XMLHttpRequest();
		xhr.open('GET', url, true);
		if (requestHeader) {
			requestHeader.forEach((element) => {
				xhr.setRequestHeader(element.name, element.value);
			});
		}
		xhr.onload = () => {
			if (xhr.readyState === 4 && xhr.status === 200) {
				const res = xhr.responseText;
				callback(JSON.parse(res));
			} else {
				console.error(xhr.statusText);
			}
		};
		xhr.send(null);
	};

	/**
	 * @desc Convert Object or Array to Array
	 * @param {Object} item - Object or Array
	 * @return {Array} - Array
	 *
	 */
	objectOrArrayToArray = (item) => {
		if (typeof item === 'undefined' || Array.isArray(item)) {
			return item;
		}
		return [item];
	};

	/**
	 * @desc Render class
	 */
	render() {
		return this;
	}
}

export default FilterableListBlueprint;

HTML Output

Default

<div class="c-filterable-list-blueprint--default" data-css="c-filterable-list-blueprint" data-js-module="filterable-list-blueprint">
	<div class="grid__container">
		<div class="grid__row">
			<form class="c-filterable-list-blueprint--form is-loading" action="//localhost:3000/mocks/connector/getFilterableListBlueprint.json" method="GET" data-js-item="js-filterable-list-blueprint-filter-form">
				<fieldset class="form__fieldset is-small">
					<legend class="form__legend is-col-mobile-p-12 is-hidden">
						Radio Buttons </legend>
					<div class="form__row">
						<div class="form__col is-text-align-right">
							<div class="form__radio is-inline-block is-filternav">
								<div class="form__label-wrapper">
									<strong class="form__radio-legend">Zeige</strong>
								</div>
								<div class="form__radio-wrapper">
									<ul class="form__radio-list">
										<li class="form__radio-item">
											<input id="tag-one" name="radio-group" type="radio" value="tag-one" class="form__radio-input" />
											<label role="button" for="tag-one" class="form__radio-label">
												Tag One
											</label>
										</li>
										<li class="form__radio-item">
											<input id="tag-two" name="radio-group" type="radio" value="tag-two" class="form__radio-input" />
											<label role="button" for="tag-two" class="form__radio-label">
												Tag Two
											</label>
										</li>
										<li class="form__radio-item">
											<input id="tag-three" name="radio-group" type="radio" value="tag-three" class="form__radio-input" />
											<label role="button" for="tag-three" class="form__radio-label">
												Tag Three
											</label>
										</li>
										<li class="form__radio-item">
											<input id="key-all" name="radio-group" type="radio" value="key-all" class="form__radio-input" />
											<label role="button" for="key-all" class="form__radio-label">
												All
											</label>
										</li>
									</ul>
								</div>
							</div>
						</div>
					</div>
				</fieldset>
				<!-- Results Info -->
				<div class="filterable-list-blueprint__results-info" data-js-item="js-filterable-list-blueprint-results-info">
					<p><strong><span data-js-item="js-filterable-list-blueprint__total-item-count">&nbsp;</span> Ergebnisse zum <span data-js-item="js-filterable-list-blueprint__total-item-tag-name"></span> Forschen</strong></p>
				</div>
				<!-- Loader -->
				<div class="filterable-list-blueprint__results-loader" data-js-item="js-filterable-list-blueprint-results-loader">
					<span class="filterable-list-blueprint__results-loader-box is-one"></span>
					<span class="filterable-list-blueprint__results-loader-box is-two"></span>
					<span class="filterable-list-blueprint__results-loader-box is-three"></span>
				</div>
				<!-- Template for Results -->
				<ul class="filterable-list-blueprint__results-template">
					<li class="filterable-list-blueprint__results-item" data-js-item="js-filterable-list-blueprint-results-template">
						<div class="filterable-list-blueprint__results-item-image">
							<picture class="c-picture--default lazyloaded" data-css="c-picture">
								<img src="" class="picture__image lazyautosizes lazyloaded" alt="">
							</picture>
						</div>
						<div class="filterable-list-blueprint__results-item-text-wrapper">
							<em class="filterable-list-blueprint__results-item-meta">
								<span class="filterable-list-blueprint__results-item-meta-category">News</span>
								<span class="filterable-list-blueprint__results-item-meta-date">2020-05-21</span>
							</em>
							<a href="" class="filterable-list-blueprint__results-item-link">Title Leuchtende Chamäleons</a>
							<p class="filterable-list-blueprint__results-item-description">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam...</p>
							<a href="" class="filterable-list-blueprint__a11y-clickarea" aria-hidden="true" tabindex="-1"></a>
						</div>
					</li>
				</ul>
				<!-- Results -->
				<ul class="filterable-list-blueprint__results" data-js-item="js-filterable-list-blueprint-results">
				</ul>
				<!-- Load More Button -->
				<div class="filterable-list-blueprint__load-more-wrapper is-loading">
					<button type="submit" class="filterable-list-blueprint__load-more" data-js-item="js-filterable-list-blueprint-load-more-btn">
						<span class="filterable-list-blueprint__load-more-loader">
							<span class="filterable-list-blueprint__load-more-loader-box is-one"></span>
							<span class="filterable-list-blueprint__load-more-loader-box is-two"></span>
							<span class="filterable-list-blueprint__load-more-loader-box is-three"></span>
						</span>
						<span class="filterable-list-blueprint__load-more-text">Show More</span></button>
				</div>
			</form>
		</div>
	</div>
</div>

Wonach suchst du?