import Choices from "choices.js"; import { Sidebar } from './js/sidebar'; import './scss/app.scss' export interface choiceMap { [details: string]: Choices; } let choiceObjects: choiceMap = {}; document.addEventListener('DOMContentLoaded', function() { initSearch(); initSidebar(); initToggle(); replaceStrings(); initChoices(); initBoatActions(); selectBoatChange(); addRelationMagic(document.querySelector('body')); }); function selectBoatChange() { const boatSelect = document.querySelector('#boat_id'); if(boatSelect) { boatSelect.addEventListener('change', function() { const selectedElement = boatSelect as HTMLSelectElement; const opt = selectedElement.options[selectedElement.selectedIndex]; const selectedValue = (opt).dataset.amount_seats; const rowers = Number(selectedValue) - 1; choiceObjects['newrower'].config.maxItemCount = rowers; choiceObjects['newrower'].removeActiveItems(rowers); (rowers === 0 ? choiceObjects['newrower'].disable() : choiceObjects['newrower'].enable()) }); } } function initBoatActions() { const boatSelects = document.querySelectorAll('.boats-js[data-onclick="true"]'); if(boatSelects) { Array.prototype.forEach.call(boatSelects, (select: HTMLInputElement) => { select.addEventListener('click', function() { if(select.dataset.seats) { const rowers = Number(select.dataset.seats) - 1; choiceObjects['newrower'].config.maxItemCount = rowers; choiceObjects['newrower'].removeActiveItems(rowers); let boatSelect = document.querySelector('#boat_id'); if(boatSelect && select.dataset.id) { boatSelect.value = select.dataset.id; } (rowers === 0 ? choiceObjects['newrower'].disable() : choiceObjects['newrower'].enable()); } }); }); } } function initChoices() { const selects = document.querySelectorAll('select[data-init="true"]'); if(selects) { Array.prototype.forEach.call(selects, (select: HTMLInputElement) => { initNewChoice(select); }); } } function initNewChoice(select: HTMLInputElement) { const choice = new Choices(select, { removeItemButton: true, loadingText: 'Wird geladen...', noResultsText: 'Keine Ergebnisse gefunden', noChoicesText: 'Keine Ergebnisse gefunden', itemSelectText: 'Zum Auswählen klicken', placeholderValue: 'Ruderer auswählen', maxItemCount: Number(select.dataset.seats) - 1, maxItemText: (maxItemCount) => { return `Nur ${maxItemCount} Ruderer können hinzugefügt werden`; }, }); choiceObjects[select.id] = choice; } function initToggle() { // get filter btns & set object sessionStorage const btns = >document.querySelectorAll('.filter-trips-js'); let filterObject = new Map(); if(btns) { Array.prototype.forEach.call(btns, (btn: HTMLButtonElement) => { filterObject.set(btn.dataset.action, btn.ariaPressed); btn.addEventListener('click', () => { let filter = sessionStorage.getItem('tripsFilter'); if(filter) { let filterMap = new Map(JSON.parse(filter)); for (let entry of filterMap.entries()) { if(entry[0] === btn.dataset.action && entry[1] !== 'true') { filterMap.set(entry[0],'true'); } else { filterMap.set(entry[0],'false'); } } sessionStorage.setItem('tripsFilter', JSON.stringify( Array.from(filterMap.entries()))); } resetFilteredElements(); if(btn.getAttribute('aria-pressed') === 'false'){ Array.prototype.forEach.call(btns, (b: HTMLButtonElement) => { b.setAttribute('aria-pressed', 'false'); }); triggerFilterAction(btn.dataset.action); } else { btn.setAttribute('aria-pressed', 'false'); } }); }); } let filter = sessionStorage.getItem('tripsFilter'); if(filter) { let filterMap = new Map(JSON.parse(filter)); for (let entry of filterMap.entries()) { if(entry[1] === 'true') { triggerFilterAction(entry[0]); } } } else { sessionStorage.setItem('tripsFilter', JSON.stringify( Array.from(filterObject.entries()))); } } function resetFilteredElements() { const hiddenElements = document.querySelectorAll('.reset-js.hidden'); if(hiddenElements) { Array.prototype.forEach.call(hiddenElements, (hiddenElement: HTMLButtonElement) => { hiddenElement.classList.remove('hidden'); }); } } function triggerFilterAction(activeFilter: any) { const activeBtn = document.querySelector('button[data-action="' + activeFilter + '"]'); if(activeBtn) { activeBtn.setAttribute('aria-pressed', 'true'); filterAction(activeFilter); } } function filterAction(activeFilter: string) { switch(activeFilter) { case 'filter-days': { filterDays(); break; } case 'filter-coxs': { filterCoxs(); break; } case 'filter-months': { filterMonths(activeFilter) break; } } } function filterDays() { const daysNoTrips = document.querySelectorAll('div[data-trips="0"]'); Array.prototype.forEach.call(daysNoTrips, (day: HTMLElement) => { day.classList.toggle('hidden'); }); } function filterCoxs() { const noCoxNeeded = document.querySelectorAll('div[data-coxneeded="false"]'); Array.prototype.forEach.call(noCoxNeeded, (notNeeded: HTMLElement) => { notNeeded.classList.toggle('hidden'); }); } function filterMonths(action: string) { const months = ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12']; const monthToggle = document.querySelector('button[data-action="' + action + '"]'); if(monthToggle) { const currentMonth = monthToggle.dataset.month; if(currentMonth) { const index = months.indexOf(currentMonth); if (index > -1) { // only splice array when item is found months.splice(index, 1); // 2nd parameter means remove one item only } Array.prototype.forEach.call(months, (month: HTMLElement) => { const notThisMonth = document.querySelectorAll('div[data-month="' + month + '"]'); Array.prototype.forEach.call(notThisMonth, (notThisMonth: HTMLElement) => { notThisMonth.classList.toggle('hidden'); }); }); } } } function initSearch() { const input = document.querySelector('#filter-js'); if(input) { filterElements(input.value); input.addEventListener('input', () => { filterElements(input.value); }); } } function filterElements(input: string) { const elements = document.querySelectorAll('form[data-filterable="true"]'); let resultWrapper = document.querySelector('#filter-result-js'), amountShownElements = 0; Array.prototype.forEach.call(elements, (element: HTMLElement) => { // set both strings (input & dataset filter) to lowercase to not be case sensitive let filterString = element.dataset.filter?.toLocaleLowerCase(); // bulk hide all elements element.style.display = 'none'; // show if input matches if(filterString?.includes(input.toLocaleLowerCase())) { element.style.display = 'flex'; amountShownElements ++; } }); if(resultWrapper) { resultWrapper.innerHTML = (amountShownElements === 0 ? 'Kein Ergebnis gefunden' : '' + amountShownElements + '' + (amountShownElements > 1 ? ' Ergebnisse' : ' Ergebnis') + ' gefunden'); } } function initSidebar() { const sidebarTrigger = >document.querySelectorAll('[data-trigger]'); if(sidebarTrigger) { Array.prototype.forEach.call(sidebarTrigger, (triggerElement: HTMLElement) => { if(triggerElement.dataset.trigger) { const sidebar = new Sidebar(triggerElement.dataset.trigger); triggerElement.addEventListener('click', (e) => { e.preventDefault(); if(triggerElement.dataset.trigger === 'sidebar') { initTripSidebar(triggerElement); } sidebar.toggle(); }); } }); } } function initTripSidebar(triggerElement: HTMLElement) { const sidebarElement = document.querySelector('#sidebar'); if(sidebarElement && triggerElement.dataset.body && triggerElement.dataset.header) { let body = document.querySelector(triggerElement.dataset.body); let bodyElement = body.cloneNode(true); let bodyContainerElement = sidebarElement.querySelector('.body-js'); const selects = bodyElement.querySelectorAll('select[multiple]'); if(selects) { Array.prototype.forEach.call(selects, (select: HTMLInputElement) => { initNewChoice(select); }); } /* Quickfix duplicate ids checkboxes */ const checkboxes = >bodyElement.querySelectorAll('input[type="checkbox"]'); Array.prototype.forEach.call(checkboxes, (checkbox: HTMLElement) => { if(checkbox) { checkbox.parentElement?.setAttribute('for', checkbox.id + 'js'); checkbox.id += 'js'; } }); const prefixedContent = >bodyElement.querySelectorAll('.change-id-js'); Array.prototype.forEach.call(prefixedContent, (content: HTMLElement) => { if(content) { content.id += 'js'; if(content.dataset.relation){ content.dataset.relation += 'js'; } } }); if(bodyContainerElement) { bodyContainerElement.innerHTML = ''; bodyContainerElement.append(bodyElement); addRelationMagic(bodyElement); } if(triggerElement.dataset.day) { let hiddenElement = bodyElement.querySelector('.day-js'); if(hiddenElement) { hiddenElement.value = triggerElement.dataset.day; } } let headerElement = sidebarElement.querySelector('.header-js'); if(headerElement) { headerElement.innerHTML = triggerElement.dataset.header; } } } function addRelationMagic(bodyElement: HTMLElement) { const fields = bodyElement.querySelectorAll('.set-distance-js'); if(fields) { Array.prototype.forEach.call(fields, (field: HTMLInputElement) => { if(field.dataset.relation){ const relatedField = bodyElement.querySelector('#' + field.dataset.relation); if(relatedField) { field.addEventListener('input', (e) => { e.preventDefault(); const dataList = document.querySelector('#destinations'); if(dataList) { var option = Array.prototype.find.call(dataList.options, function(option) { return option.value === field.value; }); // Get distance const distance = option.getAttribute('distance'); if(distance) relatedField.value = distance; } }); } } }); } } function replaceStrings() { const weekdays = document.querySelectorAll('.weekday-js'); Array.prototype.forEach.call(weekdays, (weekday: HTMLElement) => { weekday.innerHTML = weekday.innerHTML.replace('Freitag', 'Markttag'); }); }