FILTERABLE-LIST-PEOPLE (LMU Physik Module )

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

Demo Section

Each variation will be presented in the following section.

Default

Zeige

  Ergebnisse zum Forschen


Readme

filterableListPeople (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-people


Fields

filterable-list-people.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.filterableListPeopleClasses String '' Modifier classes for component
settings.filterableListPeopleContextClass String 'default' Context class of component

Content

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

SASS

Variables

There are multiple variables which you can change:

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

Modifier Classes

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

Modifier Description
is-modifier Please add a description!

Templates

filterable-list-people.hbs

<div class="c-filterable-list-people{{#if settings.filterableListPeopleContextClass}}--{{settings.filterableListPeopleContextClass}}{{else}}--default{{/if}}{{#if settings.filterableListPeopleClasses}} {{settings.filterableListPeopleClasses}}{{/if}}"
     data-css="c-filterable-list-people"
     data-js-module="filterable-list-people">


     			{{#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-people__results-info" data-js-item="js-filterable-list-people-results-info">
                         	<p><strong><span data-js-item="js-filterable-list-people__total-item-count">&nbsp;</span> {{{settings.formContent.i18n.resultsText}}}</strong></p>
                         </div>

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

     					<!-- Template for Results -->
     					<ul class="filterable-list-people__results-template">
     						<li class="filterable-list-people__results-item" data-js-item="js-filterable-list-people-results-template">
                             	<div class="filterable-list-people__results-item-image">
                             		<picture class="c-picture--default lazyloaded" data-css="c-picture">
                                     	<img src="https://via.placeholder.com/300x300" class="picture__image lazyautosizes lazyloaded" alt="">
                                     </picture>
                             	</div>
                             	<div class="filterable-list-people__results-item-text-wrapper">
									<h6 class="filterable-list-people__personname"></h6>
									<p class="filterable-list-people__organization-unit"></p>
									<p class="filterable-list-people__function"></p>
									<p class="filterable-list-people__job-description"></p>
									<p><a href="" class="filterable-list-people__link is-mail filterable-list-people__mail"></a></p>
									<p><a href="" class="filterable-list-people__link is-phone filterable-list-people__phone"></a></p>
									<p><a href="" target="_blank" class="filterable-list-people__link is-external filterable-list-people__website"></a></p>
     							</div>
     							<p class="filterable-list-people__more">
                                	<a href="" class="filterable-list-people__link is-external filterable-list-people__further-info">Weitere Informationen</a>
                                </p>
                             </li>
     					</ul>

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

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

     				</form>

     			{{/with}}


</div>

Data File

filterable-list-people.hjson

{
	"variations": {
		"default": {
			"docs": {
				"variationName": "Default"
			},
			"settings": {
				"filterableListContextClass": "default",
				"filterableListClasses": ""
			},

			"content": {

				"filterForm": {
					"settings": {
						"formClasses": "c-filterable-list-people--form",
						"formContextClass": "filterable-list",
						"formJsOptions": {
							"classes": {
								"loading": "is-loading"
							},
							"submitOnChange": true
						},
						"formJsItem": "js-filterable-list-people-filter-form",
						"formAction": "//localhost:3000/api/connector/get",
						"formActionQA": "//localhost:3000/mocks/connector/getFilterableListPeople.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-people__total-item-tag-name\"></span> Forschen",
								"showAll": "Alle anzeigen"
							}
						},
						"resultTemplateContent": {
							"personname": "Prof. Dr. Elisabeth Haimeranhausen-Vollindertat",
							"organization": "Einrichtung",
							"function": "Funktion",
							"job-description": "Aufgabengebiet (kann auch eine längere Beschreibung sein und deswegen mehrspaltig.)",
							"mail": "Email schreiben",
							"phone": "+49(0)8933298657",
							"website": "Persönliche Website",
							"info": "Weitere Informationen",


							"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-people.scss

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

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

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


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

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

		margin-bottom: 50px;
	}

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

		&.is-loading {

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

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

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

		&.is-success {

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

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

			.filterable-list-people__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% !important;
			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-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-people__total-item-count {
		display: inline-block;
	}

	.filterable-list-people__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-people__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-people__results-item {
		@include clearfix();

		display: flex;
		flex-flow: row nowrap;
		position: relative;
		width: 100%;
		flex-direction: row;
		flex-wrap: wrap;
		margin:0 0 4% 0;
		padding-bottom: 0;
		padding-left: 0;
		border: 1px solid $color-gray-light;
		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-people__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-people__results-item-dates {
				background-color: $color-white;
				border: 1px solid $color-green;
			}

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

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

					&::before {
						opacity: 0;
					}

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

		&:focus {
			outline: none;
		}

		/*
		MODIFIERS
		----------------------- */
		&:last-of-type {

		}

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

	.filterable-list-people__results-item-image {
		@include grid-column(1);
		display: none;
		max-width: 266px;

		@include bp($bp-tablet-p) {

			@include grid-column(5);
			display: inline-block;
			margin-bottom: 0;
		}
	}

	.filterable-list-people__results-item-text-wrapper {
		display: block;
		position: relative;
		flex: 1 1;
		padding: 18px 30px 0 30px;
		margin-bottom: 60px;
	}

	.filterable-list-people__personname {
		font-size: 2rem;
		line-height: (28/20);
		letter-spacing: .3px;
		font-family: $font-bold;
		font-weight: 700;
		margin-bottom: 10px;
		margin-left: 0;
	}

	.filterable-list-people__organization-unit {
		font-family: $font-bold;
		font-weight: 700;
		margin-bottom: 10px;

		a {
			color: $color-green;
			text-decoration: none;
			transition: color 2 * $animation-duration-std $animation-easing-std;

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

	.filterable-list-people__function {
		color: $color-gray;
		margin-bottom: 10px;

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

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

	.filterable-list-people__job-description {
		color: $color-gray;
		margin-bottom: 10px;
		font-size: 1.3rem;
		line-height: (17/13);
		max-width: 650px;
	}

	.filterable-list-people__link {
		font-family: $font-bold;
		font-weight: 700;
		font-size: 1.5rem;
		color: $color-green;
		text-decoration: none;
		transition: color $animation-duration-std/2 $animation-easing-std;
		margin-bottom: 8px;

		@include bp($bp-desktop-m) {
			font-size: 1.6rem;
		}

		&: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: relative;
			display: inline-block;
			top: 1px;
			margin-right: 10px !important;
			vertical-align: unset;
			transition: transform $animation-duration-std $animation-easing-std;
		}

		/*
		MODIFIERS
		----------------------- */
		&.a11y-focus-key {
			@include a11y-focus-key();
		}

		&.is-internal {

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

			&.a11y-focus-key {
				@include a11y-focus-key();
			}
		}

		&.is-mail,
		&[href*="mailto:"] {
			color: $color-green;
			transition: color $animation-duration-std/3 $animation-easing-std;
			display: inline-block;

			&:focus {
				outline: none;
			}

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

				&::before {
					@include sprites-icon-mail-grey();
				}
			}

			&.a11y-focus-key {
				@include a11y-focus-key();
			}

			&::before {
				@include pseudo();
				@include sprites-icon-mail-green();

				position: relative;
				display: inline-block;
				top: 1px;
				margin-right: 10px;
				vertical-align: unset;
			}
		}

		&.is-phone {
			color: $color-dark;
			transition: color $animation-duration-std/3 $animation-easing-std;
			display: inline-block;

			&:focus {
				outline: none;
			}

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

				&::before {
					@include sprites-icon-phone-green();
				}
			}

			&.a11y-focus-key {
				@include a11y-focus-key();
			}

			&::before {
				@include pseudo();

				@include sprites-icon-phone-grey();

				position: relative;
				display: inline-block;
				top: 3px;
				margin-right: 10px;
				vertical-align: unset;
			}
		}
	}

	.filterable-list-people__phone {

		font-family: $font-bold;
		font-weight: 700;
		display: inline-block;
		margin-bottom: 8px;

		&::before {
			@include pseudo();

			@include sprites-icon-phone-grey();

			position: relative;
			display: inline-block;
			top: 3px;
			margin-right: 10px;
			vertical-align: unset;
		}
	}

	.filterable-list-people__more {
		position: absolute;
		bottom: 0px;
		right: 0px;
		padding: 10px 8px 10px 10px;
	}

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

	.filterable-list-people__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-people__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-people__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-people__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-people__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-people__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-people__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-people__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-people.js

/**
 * Description of FilterableListPeople.
 * Class properties and decorators are supported.
 *
 * @module FilterableListPeople
 * @version v1.0.0
 *
 * @author Ognjen Jukanovic
 */

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

class FilterableListPeople 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-people-filter-form"]',
				resultTemplate: '[data-js-item="js-filterable-list-people-results-template"]',
				resultsList: '[data-js-item="js-filterable-list-people-results"]',
				totalResults: '[data-js-item="js-filterable-list-people__total-item-count"]',
				tagName: '[data-js-item="js-filterable-list-people__total-item-tag-name"]',
				btnLoadMore: '[data-js-item="js-filterable-list-people-load-more-btn"]',
				resultsLoader: '[data-js-item="js-filterable-list-people-results-loader"]',
				loadMoreLoader: '.filterable-list-people__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 FilterableListPeople will mount!');
	}

	didMount() {
		console.log('Component FilterableListPeople 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-people__results-template');
			result.classList.add(this.options.classes.isLoading);

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

			const name = (item.academiTitle ? item.academiTitle + ' ' : '') + (item.firstName ? item.firstName + ' ' : '') + (item.lastName ? item.lastName : '') + (item.aditionalAcademiTitle ? (', ' + item.aditionalAcademiTitle) + ' ' : '');
			const organization = (item.workingGroup ? (item.workingGroup + ' | ') + ' ' : '') + (item.faculty.href ? `<a href="${item.faculty.href}" target="_blank">${item.faculty.text}</a>`  : '');

			result.querySelector('.filterable-list-people__personname').innerHTML = this.arrayToString(name);
			result.querySelector('.filterable-list-people__organization-unit').innerHTML = this.arrayToString(organization);

			result.querySelector('.filterable-list-people__function').innerHTML = this.arrayToString(item.function ? item.function + ' ' : '');

			result.querySelector('.filterable-list-people__job-description').innerHTML = this.arrayToString(item.areaOfResponsibility ? item.areaOfResponsibility + ' ' : '');

			if (item.contactInfo.email.text && item.contactInfo.email.text.length) {
				result.querySelector('.filterable-list-people__mail').innerHTML = this.arrayToString(item.contactInfo.email.text);
				result.querySelector('.filterable-list-people__mail').setAttribute('href', 'mailto:' + item.contactInfo.email.href);
			} else {
				result.querySelector('.filterable-list-people__mail').style.display = 'none';
			}

			if (item.contactInfo.phone && item.contactInfo.phone.length) {
				result.querySelector('.filterable-list-people__phone').innerHTML = this.arrayToString(item.contactInfo.phone);
				result.querySelector('.filterable-list-people__phone').setAttribute('href', 'tel:' + item.contactInfo.phone);
			} else {
				result.querySelector('.filterable-list-people__phone').style.display = 'none';
			}

			if (item.contactInfo.web.href && item.contactInfo.web.href.length) {
				result.querySelector('.filterable-list-people__website').innerHTML = this.arrayToString(item.contactInfo.web.text);
				result.querySelector('.filterable-list-people__website').setAttribute('href', item.contactInfo.web.href);
			} else {
				result.querySelector('.filterable-list-people__website').style.display = 'none';
			}

			result.querySelector('.filterable-list-people__further-info').setAttribute('href', item.link ? item.link + ' ' : '');

			if (item.category && result.querySelector('.filterable-list-people__results-item-meta-category')) {
				result.querySelector('.filterable-list-people__results-item-meta-category').innerHTML = this.arrayToString(item.category);
			}

			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 FilterableListPeople;

HTML Output

Default

<div class="c-filterable-list-people--default" data-css="c-filterable-list-people" data-js-module="filterable-list-people">
	<form class="c-filterable-list-people--form is-loading" action="//localhost:3000/mocks/connector/getFilterableListPeople.json" method="GET" data-js-item="js-filterable-list-people-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-people__results-info" data-js-item="js-filterable-list-people-results-info">
			<p><strong><span data-js-item="js-filterable-list-people__total-item-count">&nbsp;</span> Ergebnisse zum <span data-js-item="js-filterable-list-people__total-item-tag-name"></span> Forschen</strong></p>
		</div>
		<!-- Loader -->
		<div class="filterable-list-people__results-loader" data-js-item="js-filterable-list-people-results-loader">
			<span class="filterable-list-people__results-loader-box is-one"></span>
			<span class="filterable-list-people__results-loader-box is-two"></span>
			<span class="filterable-list-people__results-loader-box is-three"></span>
		</div>
		<!-- Template for Results -->
		<ul class="filterable-list-people__results-template">
			<li class="filterable-list-people__results-item" data-js-item="js-filterable-list-people-results-template">
				<div class="filterable-list-people__results-item-image">
					<picture class="c-picture--default lazyloaded" data-css="c-picture">
						<img src="https://via.placeholder.com/300x300" class="picture__image lazyautosizes lazyloaded" alt="">
					</picture>
				</div>
				<div class="filterable-list-people__results-item-text-wrapper">
					<h6 class="filterable-list-people__personname"></h6>
					<p class="filterable-list-people__organization-unit"></p>
					<p class="filterable-list-people__function"></p>
					<p class="filterable-list-people__job-description"></p>
					<p><a href="" class="filterable-list-people__link is-mail filterable-list-people__mail"></a></p>
					<p><a href="" class="filterable-list-people__link is-phone filterable-list-people__phone"></a></p>
					<p><a href="" target="_blank" class="filterable-list-people__link is-external filterable-list-people__website"></a></p>
				</div>
				<p class="filterable-list-people__more">
					<a href="" class="filterable-list-people__link is-external filterable-list-people__further-info">Weitere Informationen</a>
				</p>
			</li>
		</ul>
		<!-- Results -->
		<ul class="filterable-list-people__results" data-js-item="js-filterable-list-people-results">
		</ul>
		<!-- Load More Button -->
		<div class="filterable-list-people__load-more-wrapper is-loading">
			<button type="submit" class="filterable-list-people__load-more" data-js-item="js-filterable-list-people-load-more-btn">
				<span class="filterable-list-people__load-more-loader">
					<span class="filterable-list-people__load-more-loader-box is-one"></span>
					<span class="filterable-list-people__load-more-loader-box is-two"></span>
					<span class="filterable-list-people__load-more-loader-box is-three"></span>
				</span>
				<span class="filterable-list-people__load-more-text">Show More</span></button>
		</div>
	</form>
</div>

Wonach suchst du?