1document.addEventListener('DOMContentLoaded', function() { 2 3 let pulser = document.querySelector('.pdp__pulse') 4 let pulserText = document.querySelector('.pdp__pulse__text') 5 6 const useRandomForTesting = false; 7 8 if (document.querySelector('.stock.in-stock')) { 9 const stockElement = document.querySelector('.stock.in-stock'); 10 11 pulser.style.display = "flex"; 12 pulser.style.color = "#008000"; 13 pulser.classList.add('has-stock') 14 15 if (stockElement.textContent.includes("Op voorraad")) { 16 pulserText.textContent = 'Beperkte voorraad'; 17 } else { 18 pulserText.textContent = stockElement.textContent; 19 } 20 21 } else { 22 const pdpTimeElement = document.querySelector('.pdp__time'); 23 24 if (pdpTimeElement) { 25 const pdpTimeText = pdpTimeElement.textContent.trim(); 26 27 if (pdpTimeText.includes('werkdagen')) { 28 29 const messagesOrange = ctMessagesOrange; 30 const messagesGreen = ctMessagesGreen; 31 32 const allMessages = [...messagesOrange, ...messagesGreen]; 33 const orangeCount = messagesOrange.length; 34 35 let messageIndex; 36 37 if (useRandomForTesting) { 38 messageIndex = Math.floor(Math.random() * allMessages.length); 39 } else { 40 const productId = window.item?.product_id ? parseInt(window.item.product_id) : 0; 41 42 const now = new Date(); 43 const dayOfYear = Math.floor((now - new Date(now.getFullYear(), 0, 0)) / 86400000); 44 const baseSeed = now.getFullYear() + dayOfYear; 45 46 // Combine base seed with product ID 47 const productSeed = baseSeed + productId; 48 49 messageIndex = productSeed % allMessages.length; 50 } 51 52 const message = allMessages[messageIndex]; 53 54 const color = messageIndex < orangeCount ? "#008000" : "#008000"; 55 56 pulser.style.display = "flex"; 57 pulser.style.color = color; 58 pulserText.textContent = message; 59 } 60 } 61 } 62}); 63 64 65let swiperContainers = [...document.querySelectorAll('.swiper-container')] 66 67 68if (swiperContainers.length > 0) { 69 swiperContainers.forEach(container => { 70 let parent = container.closest(".js-swiper-container-parent") 71 let next = parent.querySelector('.swiper-next') 72 let prev = parent.querySelector('.swiper-prev') 73 74 const swiper = new Swiper(container, { 75 // Optional parameters 76 slidesPerView: 'auto', 77 78 // Navigation arrows 79 navigation: { 80 nextEl: next, 81 prevEl: prev, 82 }, 83 84 spaceBetween: 20, 85 }); 86 }) 87} 88 89 90const tooltips = document.querySelectorAll('.js-hotspot'); 91 92if (tooltips.length > 0) { 93 tooltips.forEach((tooltip) => { 94 tooltip.addEventListener('click', (event) => { 95 if (!tooltip.closest('.ct-hotspot').classList.contains('active')) { 96 tooltips.forEach((t) => t.closest('.ct-hotspot').classList.remove('active')); 97 tooltip.closest('.ct-hotspot').classList.add('active'); 98 99 adjustTooltipPosition(tooltip.closest('.ct-hotspot').querySelector('.ct-hotspot-tile')) 100 } else { 101 tooltips.forEach((t) => t.closest('.ct-hotspot').classList.remove('active')); 102 } 103 104 }); 105 }); 106 107 // Add click event listener to the window to remove 'active' class 108 window.addEventListener('click', (e) => { 109 const hotspotElement = e.target.closest('.ct-hotspot'); 110 111 if (hotspotElement) { 112 if (hotspotElement.classList.contains('ct-hotspot')) { 113 return false 114 } 115 } else { 116 tooltips.forEach((t) => t.closest('.ct-hotspot').classList.remove('active')); 117 } 118 }); 119} 120 121function adjustTooltipPosition(tooltip) { 122 const tooltipRect = tooltip.getBoundingClientRect(); 123 const windowWidth = window.innerWidth; 124 const windowHeight = window.innerHeight; 125 126 // Check and adjust the position if the tooltip is going outside the right boundary 127 if (tooltipRect.right > windowWidth) { 128 console.log('1') 129 tooltip.style.transform = 'translate(-90%,0)'; 130 131 // tooltip.style.left = `${windowWidth - tooltipRect.width}px`; 132 } 133 134 // Check and adjust the position if the tooltip is going outside the bottom boundary 135 if (tooltipRect.bottom > windowHeight) { 136 console.log('2') 137 138 // tooltip.style.top = `${windowHeight - tooltipRect.height}px`; 139 } 140 141 // Check and adjust the position if the tooltip is going outside the left boundary 142 if (tooltipRect.left < 0) { 143 console.log('3') 144 145 tooltip.style.transform = 'translate(-15%,0)'; 146 } 147 148 // Check and adjust the position if the tooltip is going outside the top boundary 149 if (tooltipRect.top < 0) { 150 console.log('4') 151 // tooltip.style.top = '0px'; 152 } 153} 154 155 156 157document.addEventListener('DOMContentLoaded', function() { 158 const quicklinksParents = document.querySelectorAll('.product-quicklinks') 159
160 quicklinksParents.forEach(quickLinksParent => { 161 const quickLinks = quickLinksParent.querySelectorAll('.quicklink-btn') 162 quickLinks.forEach(quicklink => { 163 quicklink.addEventListener('click', function(e) { 164 // console.log(quicklink.dataset.target) 165 // console.log(document.querySelector(`[data-section="${quicklink.dataset.target}"]`)) 166 167 e.preventDefault(); 168 const targetSections = document.querySelectorAll(`[data-section="${quicklink.dataset.target}"]`); 169 scrollToSection(targetSections); 170 }) 171 }) 172 }) 173 174 function scrollToSection(targetSections) { 175 if (targetSections) { 176 const headerOffset = 125; // Adjust this value based on your fixed header height 177 var elementPosition 178 if (window.innerWidth <= 849) { 179 const hasJsPDPClass = Array.from(targetSections).some(section => section.classList.contains('js-pdp-section')); 180 181 if (hasJsPDPClass) { 182 elementPosition = targetSections[0].getBoundingClientRect().top; 183 184 } else { 185 186 elementPosition = targetSections[1].getBoundingClientRect().top; 187 } 188 189 } else { 190 elementPosition = targetSections[0].getBoundingClientRect().top; 191 192 } 193 const offsetPosition = elementPosition + window.pageYOffset - headerOffset; 194 195 196 window.scrollTo({ 197 top: offsetPosition, 198 behavior: 'smooth' 199 }); 200 } 201 } 202 203 204 205 206 207 const readmores = document.querySelectorAll('.js-text-read-more') 208 209 if (readmores) { 210 readmores.forEach(readmore => { 211 const btn = readmore.querySelector('.js-text-read-more-btn') 212 213 btn.addEventListener('click', function(e) { 214 e.preventDefault() 215 readmore.classList.add('is-open') 216 }) 217 }) 218 219 var toggleButton = document.getElementById('toggle-attributes'); 220 var hiddenAttributes = document.querySelectorAll('.hidden-attribute'); 221 222 if (toggleButton) { 223 toggleButton.addEventListener('click', function() { 224 // Check if attributes are currently hidden 225 var isHidden = hiddenAttributes[0].style.display === 'none' || hiddenAttributes[0].style.display === ''; 226 227 hiddenAttributes.forEach(function(attribute) { 228 if (isHidden) { 229 attribute.style.display = 'table-row'; // Show hidden attributes 230 toggleButton.textContent = 'Toon minder specificaties'; // Update button text 231 toggleButton.classList.add('active') 232 } else { 233 attribute.style.display = 'none'; // Hide the attributes 234 toggleButton.textContent = 'Toon meer specificaties'; // Reset button text 235 toggleButton.classList.remove('active') 236 } 237 }); 238 }); 239 240 // Ensure attributes are hidden on page load 241 hiddenAttributes.forEach(function(attribute) { 242 attribute.style.display = 'none'; 243 }); 244 } 245 } 246}); 247 248const ctGoogleMapsConfig = { 249 apiKey: 'AIzaSyAoQGtUwcur1anZNTzZA6gxXXiKYiRBSos', 250 lat: 52.0154703, 251 lng: 5.1039262, 252 zoom: 12, 253 markerIcon: '/wp-content/uploads/2026/04/marker.png', 254 mapStyle: [ 255 { 256 "featureType": "all", 257 "elementType": "labels.text", 258 "stylers": [ 259 { 260 "color": "#878787" 261 } 262 ] 263 }, 264 { 265 "featureType": "all", 266 "elementType": "labels.text.stroke", 267 "stylers": [ 268 { 269 "visibility": "off" 270 } 271 ] 272 }, 273 { 274 "featureType": "landscape", 275 "elementType": "all", 276 "stylers": [ 277 { 278 "color": "#f9f5ed" 279 } 280 ] 281 }, 282 { 283 "featureType": "road.highway", 284 "elementType": "all", 285 "stylers": [ 286 { 287 "color": "#f5f5f5" 288 } 289 ] 290 }, 291 { 292 "featureType": "road.highway", 293 "elementType": "geometry.stroke", 294 "stylers": [ 295 { 296 "color": "#c9c9c9" 297 } 298 ] 299 }, 300 { 301 "featureType": "water", 302 "elementType": "all", 303 "stylers": [ 304 { 305 "color": "#aee0f4" 306 } 307 ] 308 } 309 ] 310}; 311 312function initCtGoogleMap() { 313 const mapEl = document.getElementById('ct-google-map'); 314 if (!mapEl) return; 315 316 const position = { lat: ctGoogleMapsConfig.lat, lng: ctGoogleMapsConfig.lng }; 317 318 const map = new google.maps.Map(mapEl, { 319 center: position, 320 zoom: ctGoogleMapsConfig.zoom, 321 styles: ctGoogleMapsConfig.mapStyle, 322 fullscreenControl: false, 323 streetViewControl: false, 324 zoomControl: false, 325 rotateControl: false, 326 scaleControl: false, 327 cameraControl: false, 328 keyboardShortcuts: false, 329 disableDefaultUI: true 330 }); 331 332 const markerOptions = { position: position, map: map }; 333 if (ctGoogleMapsConfig.markerIcon) { 334 markerOptions.icon = { 335 url: ctGoogleMapsConfig.markerIcon, 336 scaledSize: new google.maps.Size(64, 64) 337 }; 338 } 339 340 const marker = new google.maps.Marker(markerOptions); 341 342 marker.addListener('click', function() { 343 const url = 'https://www.google.com/maps/dir/?api=1&destination=' + 344 ctGoogleMapsConfig.lat + ',' + ctGoogleMapsConfig.lng; 345 window.open(url, '_blank'); 346 }); 347} 348 349window.initCtGoogleMap = initCtGoogleMap; 350 351document.addEventListener('DOMContentLoaded', function() { 352 if (!document.getElementById('ct-google-map')) return; 353 354 const script = document.createElement('script');
355 script.src = 'https://maps.googleapis.com/maps/api/js?key=' + ctGoogleMapsConfig.apiKey + '&callback=initCtGoogleMap'; 356 script.async = true; 357 script.defer = true; 358 document.head.appendChild(script); 359}); 360 361document.addEventListener('DOMContentLoaded', function() { 362 const container = document.querySelector('.product-short-description'); 363 if (!container) return; 364 365 const maxChars = 140; // change this to whatever you want 366 const fullHtml = container.innerHTML.trim(); 367 const fullText = container.textContent.trim(); 368 369 // Nothing to do if it's already short 370 if (fullText.length <= maxChars) return; 371 372 const previewText = fullText.slice(0, maxChars); 373 374 // Store original content in data attributes 375 container.dataset.fullHtml = fullHtml; 376 container.dataset.previewText = previewText; 377 container.dataset.expanded = 'false'; 378 379 function renderPreview() { 380 container.innerHTML = 381 '<span class=\"short-description-preview\">' + 382 container.dataset.previewText + 383 '…' + 384 '</span> ' + 385 '<button type=\"button\" class=\"short-description-toggle ct-button--outline fw-700\"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 16 16"><path stroke="#1D1D1B" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.333" d="M14.665 4.668 8 11.335 1.332 4.668"/></svg>Toon meer</button>'; 386 } 387 388 function renderFull() { 389 container.innerHTML = 390 container.dataset.fullHtml + 391 '<button type=\"button\" class=\"short-description-toggle short-description-toggle--less ct-button--outline fw-700\"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 16 16"><path stroke="#1D1D1B" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.333" d="m1.333 11.334 6.666-6.667 6.667 6.667"/></svg>Toon minder</button>'; 392 } 393 394 function renderFullNoButton() { 395 container.innerHTML = container.dataset.fullHtml; 396 } 397 398 function applyState() { 399 if (window.innerWidth < 850) { 400 if (container.dataset.expanded === 'true') { 401 renderFull(); 402 } else { 403 renderPreview(); 404 } 405 } else { 406 renderFullNoButton(); 407 } 408 } 409 410 let wasNarrow = window.innerWidth < 850; 411 applyState(); 412 413 // Toggle on click (event delegation â survives innerHTML changes) 414 container.addEventListener('click', function(event) { 415 const toggle = event.target.closest('.short-description-toggle'); 416 if (!toggle) return; 417 418 const expanded = container.dataset.expanded === 'true'; 419 container.dataset.expanded = expanded ? 'false' : 'true'; 420 applyState(); 421 }); 422 423 // Re-render only when the viewport crosses the 850px boundary 424 window.addEventListener('resize', function() { 425 const isNarrow = window.innerWidth < 850; 426 if (isNarrow === wasNarrow) return; 427 wasNarrow = isNarrow; 428 applyState(); 429 }); 430 431});
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.