1import { initAccordion } from '@triebwerk/filmapi-accordion'; 2import { initLegendDialog } from '@triebwerk/filmapi-legend-dialog'; 3import { filmlistModalLinkHandler } from './filmList.js'; 4import { initPerformancePagination } from './film-performance-pagination.js'; 5 6initAccordion(); 7initLegendDialog(); 8 9/** 10 * Convert hash to query parameter when clicking on film detail links 11 * Uses event delegation to handle dynamically loaded links 12 * Only applies to links with class "detaillink" 13 */ 14function convertHashToQueryParam() { 15 // Use event delegation on the document to handle all film detail links 16 // This works for both existing and dynamically loaded links 17 document.addEventListener('click', (e) => { 18 const link = e.target.closest('a.detaillink'); 19 20 if (link) { 21 22 const scriptTag = document.querySelector('script[data-module="filmListJs"]'); 23 const pid = scriptTag.dataset.pid; 24 25 const url = new URL(link.href, window.location.origin); 26 27 //get value from hidden field tx_filmapi_list[offset] 28 const filmoffset = document.getElementById('filmsOffset').value; 29 const filmlimit = document.getElementById('filmsLimit').value; 30 31 if(pid) { 32 url.searchParams.set('p', pid); 33 } 34 35 if (scriptTag.dataset.backlinkPlugin) { 36 url.searchParams.set('pl', scriptTag.dataset.backlinkPlugin); 37 } 38 39 if (filmoffset && !isNaN(filmoffset) && filmlimit != filmoffset) { 40 // Convert hash to query parameter 41 url.searchParams.set('o', filmoffset); 42 } 43 44 // Update link href 45 link.href = url.toString(); 46 47 } 48 }, true); // Use capture phase to catch the event early 49} 50 51/** 52 * Add list backlink parameters to direct booking links. 53 * This keeps the return position intact for films loaded by the JS pager. 54 */ 55function addBacklinkParamsToBookingLinks() { 56 document.addEventListener('click', (e) => { 57 const link = e.target.closest('a.performance-link[href*="closeurl="]'); 58 59 if (!link) { 60 return; 61 } 62 63 const filmoffset = document.getElementById('filmsOffset')?.value; 64 const filmlimit = document.getElementById('filmsLimit')?.value; 65 const bookingUrl = new URL(link.href, window.location.origin); 66 const closeUrlValue = bookingUrl.searchParams.get('closeurl'); 67 68 if (!closeUrlValue) { 69 return; 70 } 71 72 const closeUrl = new URL(closeUrlValue, window.location.origin); 73 74 if (filmoffset && !isNaN(filmoffset) && filmlimit != filmoffset) { 75 closeUrl.pathname = closeUrl.pathname.replace(/\/o\/\d+\/?$/, ''); 76 closeUrl.pathname = `${closeUrl.pathname.replace(/\/$/, '')}/o/${filmoffset}/`; 77 } 78 79 bookingUrl.searchParams.set('closeurl', closeUrl.toString()); 80 link.href = bookingUrl.toString(); 81 }, true); 82} 83 84// Initialize hash to query parameter conversion 85convertHashToQueryParam(); 86addBacklinkParamsToBookingLinks(); 87 88/** 89 * loadMore films 90 */ 91if (document.getElementById('loadMoreFilms')) { 92 const maxLocations = parseInt(document.getElementById('allFilms').value); 93 const listContainer = document.querySelector('ul.filmapi-container__list--inner');
94 const loadMoreForm = document.getElementById('loadMoreFilms'); 95 96 let isLoading = false; 97 98 const observer = new IntersectionObserver((entries, observer) => { 99 entries.forEach(entry => { 100 if (entry.isIntersecting && !isLoading && loadmoreRequest !== 0) { 101 loadMoreForm.requestSubmit(); 102 observer.unobserve(loadMoreForm); 103 } 104 }); 105 }, { 106 root: null, 107 threshold: 0.1 108 }); 109 110 loadMoreForm.addEventListener('submit', event => { 111 event.preventDefault(); 112 if (isLoading) return; 113 114 isLoading = true; 115 116 const loaderWrapDefault = document.querySelector('.loader-loadmore'); 117 if (loaderWrapDefault) loaderWrapDefault.classList.remove("hidden"); 118 119 const limit = parseInt(document.getElementById('filmsLimit').value); 120 const offset = parseInt(document.getElementById('filmsOffset').value) + limit; 121 const formData = new FormData(loadMoreForm); 122 123 fetch(loadMoreForm.action, { 124 method: 'POST', 125 body: formData, 126 }) 127 .then(response => response.json()) 128 .then(result => { 129 if (result.content && result.content.trim() !== '') { 130 listContainer.insertAdjacentHTML("beforeend", result.content); 131 } 132 133 if (loaderWrapDefault) loaderWrapDefault.classList.add("hidden"); 134 135 document.getElementById('filmsOffset').value = offset; 136 137 if (offset >= maxLocations) { 138 loadMoreForm.classList.add('hidden'); 139 } else { 140 observer.observe(loadMoreForm); 141 } 142 143 initAccordion(); 144 initLegendDialog(); 145 filmlistModalLinkHandler(); 146 initPerformancePagination(); 147 }) 148 .catch(error => { 149 console.error(error); 150 }) 151 .finally(() => { 152 isLoading = false; 153 }); 154 }); 155 156 // initially observe the load more form 157 window.addEventListener('load', () => { 158 observer.observe(loadMoreForm); 159 }); 160 161} else { 162 console.warn('[Films] Load more form not found'); 163}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.