<section class="panel theme--white
panel--no-padding-top h-margin-top-2">
<div class="panel__inner">
<div class="filters js-filters js-loader-overlay-holder" aria-controls="filter-documents-list">
<div class="h-margin-bottom-2">
<div class="row h-margin-bottom-1 js-dropdowns-holder h-margin-top-2">
<div class="col col--span-12 col--span-xs-6 col--span-m-3">
<div class="form-item form-item--select ">
<select id="office" class="select__select js-filter" name="office" aria-controls="filter-persons-cards-grid" data-type="select">
<option class="select__option" value="" disabled selected>Office</option>
<option class="select__option" value="a-working-lab-goteborg">A Working Lab, Göteborg</option>
<option class="select__option" value="assemblin-uppsala">Assemblin, Uppsala</option>
</select>
</div>
</div>
<div class="col col--span-12 col--span-xs-6 col--span-m-3">
<div class="form-item form-item--select ">
<select id="productArea" class="select__select js-filter" name="productArea" aria-controls="filter-persons-cards-grid" data-type="select">
<option class="select__option" value="" disabled selected>Product area</option>
<option class="select__option" value="2">Option 2</option>
<option class="select__option" value="3">Option 3</option>
</select>
</div>
</div>
<div class="col col--span-12 col--span-xs-6 col--span-m-3">
<div class="form-item form-item--select ">
<select id="role" class="select__select js-filter" name="role" aria-controls="filter-persons-cards-grid" data-type="select">
<option class="select__option" value="" disabled selected>Role</option>
<option class="select__option" value="2">Option 2</option>
<option class="select__option" value="3">Option 3</option>
</select>
</div>
</div>
</div>
<div class="js-clear-filters-holder h-hidden-from-view row h-margin-top-1 h-margin-bottom-1 h-margin-top-2">
<div class="col">
<a href="#" class="js-clear-filters">Clear filters</a>
</div>
</div>
</div>
<div class="h-margin-top-3">
<div class="row row--justify-between row--align-center">
<div class="col col--auto-width">
<p class="search-result-count"></p>
</div>
<div class="col col--auto-width">
</div>
</div>
</div>
<div class="row" id="">
</div>
<script type="text/template" id="card-data-tmpl">
<% forEach(results, function(result) { %>
<div class="col col--bottom-gutter col--span-12 col--span-s-6 col--span-xl-3">
<div class="card card--fluid-layout">
<a href="<%= result.url %>" class="card__cta">
<figure class="card__figure">
<img src="<%= result.imageSrc %>" alt="<%= result.imageAlt %>" class="card__image">
</figure>
<div class="card__body">
<span class="card__follow-link">
<svg class="icon " focusable="false">
<use xlink:href="#icon-chevron-right"></use>
</svg>
</span>
<h4 class="card__title"><%= result.title %></h4>
<p class="card__date"><%= result.date %></p>
<p class="card__description"><%= result.description %></p>
</div>
</a>
</div>
</div>
<% }); %>
</script>
<div class="row filters-result-container" id="filter-persons-cards-grid">
<div class="row h-margin-top-3">
<div class="row row--justify-around h-text-align-center-m">
<div class="col col--span-12 col--span-s-8 h-text-align-center">No results message</div>
</div>
</div>
</div>
<script type="text/template" id="person-card-data-tmpl">
<% forEach(results, function(result) { %>
<div class="col col--bottom-gutter col--span-12 col--span-s-6 col--span-xl-3">
<div class="contact-card contact-card--person">
<div class="contact-card__body">
<div class="contact-card__top-img">
<% if (result.image.src != null) { %>
<img src="<%= result.image.src %>" alt="<%= result.image.alt %>" class="contact-card__icon">
<% } %>
</div>
<strong class="contact-card__label"><%= result.label %></strong>
<div class="contact-card__bottom-body">
<div class="contact-card__role"><%= result.role %></div>
<div class="js-options-limiter" data-option-selector=".js-option" data-option-limit="3">
<% forEach(result.productAreas , function(productArea) { %>
<div class="js-option"><%= productArea %></div>
<% }); %>
<div class="button-wrapper">
<button type="button" class="show-more-filters">Show More</button>
</div>
</div>
</div>
</div>
<div class="show-info js-show-info">
<div class="show-info__wrapper js-show-info-wrapper" style="max-height: 0px;">
<div class="show-info__content">
<ul class="contact-list">
<% forEach(result.contactLinks, function(link) { %>
<li class="contact-list__item">
<% if (link.tag === 'a') { %>
<a
href="<%= link.href %>"
<%= Object.entries(link.attributes || {}).map(function(item) {
return item[0] + "='" + item[1] + "'"
}).join(" ") %>
>
<svg class="icon contact-list__icon" focusable="false">
<use xlink:href="#icon-<%= link.icon %>"></use>
</svg>
<%= link.description %>
</a>
<% } else { %>
<span>
<svg class="icon contact-list__icon" focusable="false">
<use xlink:href="#icon-<%= link.icon %>"></use>
</svg>
<%= link.description %>
</span>
<% } %>
</li>
<% }); %>
</ul>
</div>
</div>
<div class="show-info__btn-holder js-show-info-btn-holder">
<button class="show-info__btn js-show-info-btn">
<span class="show-info__btn-opened-text">
More info
</span>
<span class="show-info__btn-closed-text" style="display: none;">
Hide info
</span>
<svg class="icon show-info__btn-icon" focusable="false">
<use xlink:href="#icon-close"></use>
</svg>
</button>
</div>
</div>
</div>
</div>
<% }); %>
</script>
<div class="h-text-align-center">
<a class="button js-load-more h-hidden-from-view " href="/mocks/api/personCards.json" aria-controls="filter-persons-cards-grid" data-template-id="person-card-data-tmpl">
<span class="button__label">Ladda fler</span>
</a>
</div>
</div>
</div>
</section>
<script type="text/template" id="no-results-data-tmpl"></script>
{{#> @panel theme=panel.theme modifiers=panel.modifiers }}
<div class="filters js-filters js-loader-overlay-holder" {{{getattributes filtersAttributes}}}>
{{#if filtersTitle}}
<div class="row">
<div class="col h-margin-top-4 h-margin-bottom-1">
<div class="headline-5">{{filtersTitle}}</div>
</div>
</div>
{{/if}}
<div class="h-margin-bottom-2">
{{#if displayDropdowns}}
<div class="row h-margin-bottom-1 js-dropdowns-holder {{additionalClasses}}">
{{#each filters.dropdowns}}
<div class="col col--span-12 col--span-xs-6 col--span-m-3">
{{#if multi}}
{{render "@select-multiple" this merge=true}}
{{else}}
{{render "@select--default" this merge=true}}
{{/if}}
</div>
{{/each}}
</div>
{{/if}}
{{#each filters.checkboxes}}
{{#if label}}
<div class="row">
<div class="col">
<div class="headline-7">{{label}}</div>
</div>
</div>
{{/if}}
<div class="row row--justify-between h-margin-bottom-1">
<div class="col col--auto-width">
{{#each items}}
<div class="h-display-inline-block h-margin-right-3 h-margin-bottom-2">
{{render "@checkbox--default" this merge=true}}
</div>
{{/each}}
</div>
<div class="col col--auto-width">
{{#each switchers}}
{{render "@switch" this merge=true}}
{{/each}}
</div>
</div>
{{/each}}
{{#if displaySearch}}
<div class="row h-margin-top-3 h-margin-bottom-1 js-search-field-holder">
<div class="col col--span-12 col--span-l-7 col--span-xl-5">
{{render "@search" searchField}}
</div>
</div>
{{/if}}
{{#if resetButton}}
<div class="js-clear-filters-holder h-hidden-from-view row h-margin-top-1 h-margin-bottom-1 {{additionalClasses}}">
<div class="col">
<a href="#" class="js-clear-filters">Clear filters</a>
</div>
</div>
{{/if}}
</div>
<div class="h-margin-top-3">
<div class="row row--justify-between row--align-center">
<div class="col col--auto-width">
{{>@search-result-count searchResultCount}}
</div>
<div class="col col--auto-width">
{{#if displaySort}}
{{render "@select--ghost" filters.sort merge=true}}
{{/if}}
</div>
</div>
</div>
{{#if cards}}
<div class="row" id="{{cards.id}}">
{{#each cards.items}}
<div class="col col--bottom-gutter col--span-12 col--span-s-6 col--span-xl-3">
{{>@card this}}
</div>
{{/each}}
</div>
{{render "@card-data-tmpl"}}
{{/if}}
{{#if officeCards}}
<div class="row" id="{{officeCards.id}}">
{{#each officeCards.items}}
<div class="col col--bottom-gutter col--span-12 col--span-s-6 col--span-xl-3">
{{>@contact-card this}}
</div>
{{/each}}
</div>
{{render "@office-card-data-tmpl"}}
{{#> @modal messageSelectorModal modifiers="form"}}
<div class="h-padding-bottom-4">
<h2>New message</h2>
<div id="form_40600">
<script>
document.addEventListener('DOMContentLoaded', function () {
hbspt.forms.create({
css: '',
portalId: "3433011",
formId: "cee49fbd-acb1-4054-9a44-74ea6ec39adc",
target: "#form_40600",
onFormSubmit: function ($form) {
dataLayer.push({
'event': 'hubspot form submitted',
'hubspot form name': 'Technical support',
'hubspot form id': $form[0].id,
});
},
onFormReady: function ($form) {
let event;
try {
event = new CustomEvent('onDynamicContentAdded');
} catch (e) {
event = document.createEvent('Event');
event.initEvent('onDynamicContentAdded', true, true);
};
window.dispatchEvent(event);
}
});
});
</script>
</div>
</div>
{{/@modal}}
{{/if}}
{{#if personCards}}
<div class="row filters-result-container" id="{{personCards.id}}">
{{#each personCards.items}}
<div class="col col--bottom-gutter col--span-12 col--span-s-6 col--span-xl-3">
{{>@contact-card this}}
</div>
{{/each}}
<div class="row h-margin-top-3">
{{render "@no-results"}}
</div>
</div>
{{render "@person-card-data-tmpl"}}
{{/if}}
{{#if partnerCards}}
<div class="row filters-result-container" id="{{partnerCards.id}}">
{{#each partnerCards.items}}
<div class="col col--bottom-gutter col--span-12 col--span-s-6 col--span-xl-3">
{{>@contact-card this}}
</div>
{{/each}}
</div>
{{render "@partner-card-data-tmpl"}}
{{/if}}
{{#if table}}
{{#> @horizontal-scroller showScrollIcon="true" contentContainer="filter-documents"}}
<table id="{{table.id}}" class="table table--inverted-zebra {{ tableAdditionalClasses }}">
{{#with ../table}}
<thead>
{{#each headerRows}}
<tr>
{{#each cols}}
<td>{{{ this }}}</td>
{{/each}}
</tr>
{{/each}}
</thead>
<tbody id="filter-documents-list">
{{#each rows}}
<tr
data-extension="{{this.extension}}"
data-filename="{{this.fileName}}"
data-document-category="{{this.type}}"
class="js-document-tracking-row"
>
{{#each cols}}
<td>{{{this}}}</td>
{{/each}}
</tr>
{{/each}}
</tbody>
{{/with}}
</table>
{{/@horizontal-scroller}}
{{render "@document-data-tmpl"}}
{{/if}}
<div class="h-text-align-center">
{{#if searchResultCount}}
{{> @search-result-count}}
{{/if}}
{{#if loadMore}}
{{#if loadMore.visuallyHidden}}
{{> @button loadMore additionalClasses="js-load-more h-hidden-from-view"}}
{{else}}
{{> @button loadMore additionalClasses="js-load-more"}}
{{/if}}
{{/if}}
</div>
</div>
{{/@panel}}
{{render "@no-results-data-tmpl"}}
{
"panel": {
"theme": "white",
"modifiers": "no-padding-top"
},
"filtersTitle": false,
"filtersAttributes": {
"aria-controls": "filter-documents-list"
},
"displayDropdowns": true,
"displaySearch": false,
"resetButton": true,
"displaySort": false,
"searchField": {
"name": "Search",
"value": "",
"type": "text",
"placeholder": "text",
"disabled": false,
"additionalClasses": "js-filter",
"attr": {
"aria-controls": "filter-documents-list",
"data-type": "search"
}
},
"searchResultCount": null,
"filters": {
"checkboxes": [],
"dropdowns": [
{
"name": "office",
"label": "",
"id": "office",
"additionalClasses": "js-filter",
"options": [
{
"name": "Office",
"value": "",
"disabled": true,
"selected": true
},
{
"name": "A Working Lab, Göteborg",
"value": "a-working-lab-goteborg"
},
{
"name": "Assemblin, Uppsala",
"value": "assemblin-uppsala"
}
],
"attr": {
"aria-controls": "filter-persons-cards-grid",
"data-type": "select"
}
},
{
"name": "productArea",
"label": "",
"id": "productArea",
"additionalClasses": "js-filter",
"options": [
{
"name": "Product area",
"value": "",
"disabled": true,
"selected": true
},
{
"name": "Option 2",
"value": 2
},
{
"name": "Option 3",
"value": 3
}
],
"attr": {
"aria-controls": "filter-persons-cards-grid",
"data-type": "select"
}
},
{
"name": "role",
"label": "",
"id": "role",
"additionalClasses": "js-filter",
"options": [
{
"name": "Role",
"value": "",
"disabled": true,
"selected": true
},
{
"name": "Option 2",
"value": 2
},
{
"name": "Option 3",
"value": 3
}
],
"attr": {
"aria-controls": "filter-persons-cards-grid",
"data-type": "select"
}
}
],
"sort": {
"name": "Sort",
"label": "Sortera:",
"modifiers": "horizontal",
"id": "categorySelectSort",
"additionalClasses": "js-filter select__select--ghost",
"options": [
{
"name": "Senaste",
"value": "",
"selected": true
},
{
"name": "A-Z",
"value": "a-z"
},
{
"name": "Z-A",
"value": "z-a"
}
],
"attr": {
"aria-controls": "filter-documents-list",
"data-type": "select"
}
},
"switchers": []
},
"table": [],
"loadMore": {
"tag": "a",
"label": "Ladda fler",
"href": "/mocks/api/personCards.json",
"attributes": {
"aria-controls": "filter-persons-cards-grid",
"data-template-id": "person-card-data-tmpl"
},
"additionalClasses": "js-load-more",
"visuallyHidden": true
},
"additionalClasses": "h-margin-top-2",
"cards": {},
"personCards": {
"id": "filter-persons-cards-grid",
"items": []
},
"showUseFiltersMessage": true
}
import getEvent from '../../functions/getEvent';
import ShowInfo from '../show-info/ShowInfo';
import OptionsLimiter from '../options-limiter/OptionsLimiter';
import Modal from '../modal/Modal';
import { debounce } from 'lodash';
class Filters {
constructor(el) {
this.el = el;
this.filterDropdownsSelector = '.js-filter[data-type="select"]';
this.searchFieldSelector = '.js-filter[data-type="search"]';
this.filterDropdownsMultipleSelector = '.js-filter[data-type="select-multiple"]';
this.notFilterDropdownsSelector = '.js-filter:not([data-type="select"]):not([data-type="search"]):not([data-type="checkbox"])';
this.filterCheckboxSelector = '.js-filter[data-type="checkbox"]';
this.filterRangeSlider = '.js-filter[data-type="range-slider"]';
this.filters = el.querySelectorAll('.js-filter');
this.dropdownsMultiple = el.querySelectorAll(this.filterDropdownsMultipleSelector);
this.dropdownsHolder = el.querySelector('.js-dropdowns-holder');
this.sortableCells = el.querySelectorAll('.js-sortable-cell');
this.loadMoreBtn = el.querySelector('.js-load-more');
this.clearFiltersBtn = el.querySelector('.js-clear-filters');
this.searchField = el.querySelector(this.searchFieldSelector);
this.searchButton = this.searchField ? this.searchField.nextElementSibling : null;
this.updateFilters = this.updateFilters.bind(this);
this.triggerUpdate = this.triggerUpdate.bind(this);
const savedFiltersArray = sessionStorage.getItem('filters array');
const savedFiltersDictionary = sessionStorage.getItem('filters dictionary');
this.filtersArray = savedFiltersArray ? JSON.parse(savedFiltersArray) : [];
this.filtersDictionary = savedFiltersDictionary ? JSON.parse(savedFiltersDictionary) : {};
this.sortOrder = '';
this.sortBy = '';
this.init();
}
init() {
this.attachListeners(true);
}
attachListeners() {
const self = this;
if (this.clearFiltersBtn) {
this.clearFiltersBtn.addEventListener('click', (e) => {
e.preventDefault();
this.clearFilters();
});
};
this.el.addEventListener('change', function (e) {
const target = e.target;
if (target.matches
? target.matches(self.filterDropdownsSelector)
: target.msMatchesSelector(self.filterDropdownsSelector)
) {
self.updateFilter(target, true);
}
}, false);
this.el.addEventListener('change', function (e) {
const target = e.target;
const shouldUpdateFromData = target.dataset.shouldUpdateFilters;
const shouldUpdate = typeof shouldUpdateFromData !== 'undefined' ? shouldUpdateFromData === 'true' : true;
if (target.matches
? target.matches(self.filterCheckboxSelector)
: target.msMatchesSelector(self.filterCheckboxSelector)
) {
self.updateFilter(target, shouldUpdate);
}
}, false);
this.el.addEventListener('change', function (e) {
const target = e.target.closest(self.filterRangeSlider);
if (target) {
const shouldUpdateFromData = target.dataset.shouldUpdateFilters;
const shouldUpdate = typeof shouldUpdateFromData !== 'undefined' ? shouldUpdateFromData === 'true' : true;
self.updateFilter(target, shouldUpdate);
}
}, false);
this.el.addEventListener('click', function (e) {
const target = e.target;
if (target.matches
? target.matches(self.notFilterDropdownsSelector)
: target.msMatchesSelector(self.notFilterDropdownsSelector)
) {
self.updateFilter(target, true);
}
}, false);
for (let i = 0; this.dropdownsMultiple.length > i; i++) {
this.dropdownsMultiple[i].addEventListener('change', (e) => {
const target = e.target;
if (target.matches
? target.matches(this.filterDropdownsMultipleSelector)
: target.msMatchesSelector(this.filterDropdownsMultipleSelector)
) {
this.updateFilter(target, true);
}
});
}
for (let i = 0; i < this.sortableCells.length; i++) {
const cell = this.sortableCells[i];
cell.addEventListener('click', e => this.sortTable(e, cell));
}
if (this.searchField) {
this.searchField.addEventListener('input', (e) => {
const target = e.target;
this.updateFilterDebounced(target, true);
});
}
if (this.searchButton) {
this.searchButton.addEventListener('click', (e) => {
this.updateFilter(this.searchField, true);
});
}
window.addEventListener('loadMoreUpdate', (e) => {
if (e && e.data) {
const showInfoEls = this.el.querySelectorAll('.js-show-info');
// Re-initialize modals
const els = document.querySelectorAll('.modal');
for (let el of els) {
new Modal(el);
}
// Re-initialize showInfo component
for (let el of showInfoEls) {
ShowInfo(el);
}
// Re-initialize Options limiter component
const optionsLimiter = this.el.querySelectorAll('.js-options-limiter');
for (let el of optionsLimiter) {
new OptionsLimiter(el);
}
}
});
// Listener if Filter history is enabled
window.addEventListener('popstate', this.applyFiltersFromUrl.bind(this));
this.loadMoreBtn && this.loadMoreBtn.addEventListener('updateFilterDropdowns', this.updateFilters);
}
sortTable(e, cell) {
const newSortBy = cell.id;
if (newSortBy === this.sortBy) {
if (this.sortOrder === 'asc') {
this.sortOrder = 'desc';
} else {
this.sortOrder = 'asc';
}
} else {
this.sortOrder = 'asc';
}
this.sortBy = newSortBy;
this.triggerUpdateDebounced(cell.getAttribute('aria-controls'));
e.preventDefault();
}
groupFilters(filters) {
let a = [];
for (let filter of filters) {
const existingIndex = a.findIndex((obj) => obj.name === filter.name);
if (existingIndex > -1) {
a[existingIndex].value = a[existingIndex].value.concat(filter.value);
} else {
filter.value = [filter.value];
a.push(filter);
}
}
return a;
}
updateFilters(e) {
const { subcategoriesMarkup } = e.data;
if (this.dropdownsHolder) {
this.dropdownsHolder.innerHTML = subcategoriesMarkup;
}
}
triggerUpdate(ariaControls) {
const event = getEvent('filterApplied');
const data = {
ariaControls,
filtersArray: this.groupFilters(this.filtersArray),
filtersDictionary: this.filtersDictionary,
sortData: {}
};
if (this.sortBy) {
data.sortData.sortOrder = this.sortOrder;
data.sortData.sortBy = this.sortBy;
}
event['data'] = data;
if (this.loadMoreBtn) {
this.loadMoreBtn.dispatchEvent(event);
}
}
triggerUpdateDebounced = debounce(this.triggerUpdate, 100, false);
clearFilters() {
const filters = this.el.querySelectorAll('.js-filter');
let ariaControls = '';
for (let i = 0; i < filters.length; i++) {
const filter = filters[i];
const filterType = filter.getAttribute('data-type-variant') || filter.getAttribute('data-type');
switch (filterType) {
case 'switch':
filter.checked = false;
break;
case 'select-multiple': {
const checked = filter.querySelectorAll('option:checked');
[...checked].forEach(option => { option.selected = false; });
filter.value = '';
filter.dispatchEvent(new Event('change'));
break;
}
case 'select-with-relation':
filter.value = '';
break;
case 'select':
filter.value = '';
break;
case 'checkbox':
filter.checked = false;
filter.dispatchEvent(new Event('change'));
break;
case 'search':
filter.value = '';
break;
case 'range-slider':
filter.dispatchEvent(new Event('reset'));
filter.dispatchEvent(new Event('change'));
break;
default:
break;
}
ariaControls = filter.getAttribute('aria-controls');
}
this.updateFilter(null, false);
sessionStorage.removeItem('filters array');
sessionStorage.removeItem('filters dictionary');
this.triggerUpdateDebounced(ariaControls);
}
updateUrlWithQueryParams(filtersArray, filtersDictionary) {
// Generate query parameters from filtersArray and filtersDictionary
const queryParams = new URLSearchParams();
// Add matched filters for filtersArray to the URL parameters
const groupedFilters = {};
filtersArray.forEach(filter => {
if (filter.name && filter.value) {
const values = Array.isArray(filter.value) ? filter.value : [filter.value]; // Supports both array or string.
// Concat filter type name if it exists - or create new key.
if (groupedFilters[filter.name]) {
groupedFilters[filter.name] = groupedFilters[filter.name].concat(values);
} else {
groupedFilters[filter.name] = values;
}
}
});
// Add matched filters for filtersDictionary to the URL parameters
for (const [key, value] of Object.entries(filtersDictionary)) {
if (value) {
queryParams.append(key, value);
}
}
// Add filters to queryParams
for (const [key, values] of Object.entries(groupedFilters)) {
queryParams.append(key, values.join('|'));
}
const newUrl = `${window.location.pathname}?${queryParams.toString()}`;
// Update URL with new queryparams
window.history.pushState(null, '', newUrl);
}
applyFiltersFromUrl() {
const urlParams = new URLSearchParams(window.location.search);
// Update filters state from URL and queryparams.
this.el.querySelectorAll('.js-filter').forEach(filter => {
const filterName = filter.getAttribute('name');
const filterType = filter.getAttribute('data-type-variant') || filter.getAttribute('data-type');
const paramValue = urlParams.get(filterName);
if (paramValue) {
switch (filterType) {
case 'checkbox':
filter.checked = paramValue.split('|').includes(filter.value);
break;
case 'select-multiple':
[...filter.options].forEach(option => {
const value = option.value;
const selectedValues = paramValue.split('|');
const dropdownOption = option.parentNode.parentNode.querySelector('.select-multiple__options a[data-value="' + value + '"]');
const button = option.parentNode.parentNode.querySelector('.select-multiple__wrapper a[data-value="' + value + '"]');
option.selected = selectedValues.includes(option.value);
if (dropdownOption) {
selectedValues.includes(option.value)
? dropdownOption.setAttribute('data-checked', true)
: dropdownOption.removeAttribute('data-checked');
}
if (button) {
button.style.display = selectedValues.includes(option.value) ? 'block' : 'none';
}
});
break;
case 'select':
case 'search':
filter.value = paramValue;
break;
default:
break;
}
this.updateFilter(filter, false);
} else {
// Reset filters if no match with queryParams.
if (filter.type === 'checkbox') {
filter.checked = false;
} else {
filter.value = '';
}
this.updateFilter(filter, false);
}
});
// Update filter result
this.triggerUpdateDebounced(this.el.getAttribute('aria-controls'));
}
updateFilter(filter, shouldUpdate) {
this.filtersArray = [];
this.filtersDictionary = {};
const filters = this.el.querySelectorAll('.js-filter');
const dropdownFilters = this.el.querySelectorAll('.js-filter[data-type="select"]');
const changedDropdownIndex = Array.prototype.indexOf.call(dropdownFilters, filter);
const isFilterHistoryEnabled = filter && filter.getAttribute('data-enable-history') === 'true';
let currentDropdownIndex = 0;
for (let i = 0; i < filters.length; i++) {
const filter = filters[i];
const filterType = filter.getAttribute('data-type-variant') || filter.getAttribute('data-type');
switch (filterType) {
case 'switch':
this.filtersDictionary[filter.value] = filter.checked;
break;
case 'select-multiple': {
const checked = filter.querySelectorAll('option:checked');
const checkedValues = [...checked].map(option => option.value);
if (checkedValues.length) {
this.filtersDictionary[filter.name] = checkedValues.join('|');
}
break;
}
case 'select-with-relation':
if (currentDropdownIndex > changedDropdownIndex && changedDropdownIndex > -1) {
break;
}
this.filtersDictionary[filter.name] = filter.value;
currentDropdownIndex++;
break;
case 'select':
this.filtersDictionary[filter.name] = filter.value;
break;
case 'checkbox':
let newFilters = [];
if (filter.checked) {
newFilters = [...this.filtersArray, { 'name': filter.name, 'value': filter.value }];
} else {
newFilters = this.filtersArray.filter(item => item !== filter.value);
}
this.filtersArray = newFilters;
break;
case 'search':
this.filtersDictionary[filter.name] = filter.value;
break;
case 'range-slider':
const input = filter.querySelector('.input');
const paramName = filter && filter.querySelector('input:checked') && filter.querySelector('input:checked').value;
if (input.getAttribute('isDirty') === 'false') {
break;
}
let value = input.dataset.realValue;
this.filtersDictionary[paramName] = value;
break;
default:
break;
}
}
if (shouldUpdate) {
sessionStorage.setItem('filters array', JSON.stringify(this.filtersArray));
sessionStorage.setItem('filters dictionary', JSON.stringify(this.filtersDictionary));
// Update URL with query params.
if (isFilterHistoryEnabled) {
this.updateUrlWithQueryParams(this.filtersArray, this.filtersDictionary);
}
this.triggerUpdateDebounced(filter.getAttribute('aria-controls'));
}
}
updateFilterDebounced = debounce(this.updateFilter, 500, false);
}
export default Filters;
.filters {
th, td {
&:last-child {
text-align: center;
}
@include breakpoint-down($l) {
min-width: 0;
&:first-child {
min-width: size(25);
}
}
}
}
.js-clear-filters {
color: $color-black;
}
import Filters from './Filters';
const els = document.querySelectorAll('.js-filters');
for (let el of els) {
new Filters(el);
}
No notes defined.