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.
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"> </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://placehold.co/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"> </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://placehold.co/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>