1/** 2 * Watkins LDP Call To Action Modal 3 * Handles the slide-out modal for product reservations 4 * Works with modal partial included in PHP templates 5 */ 6 7(function() { 8 function executeFormShortcodeInlineScripts(container) { 9 if (!container) return; 10 11 // Execute inline scripts from the form 12 var scripts = container.querySelectorAll('script'); 13 for (var i = 0; i < scripts.length; i++) { 14 var script = scripts[i]; 15 16 if (!script.src) { 17 var newScript = document.createElement('script'); 18 newScript.type = 'text/javascript'; 19 newScript.text = script.text || script.textContent || ''; 20 21 document.body.appendChild(newScript); 22 } 23 } 24 25 // Reinitialize WPForms for AJAX submission support 26 var wpformsForm = container.querySelector('form.wpforms-form'); 27 if (wpformsForm) { 28 wpformsForm.setAttribute('action', window.location.href.split('#')[0]); 29 30 var initWPForms = function() { 31 if (window.wpforms && typeof window.wpforms.init === 'function') { 32 window.wpforms.init(); 33 } 34 }; 35 36 if (window.wpforms) { 37 initWPForms(); 38 } else { 39 if (document.readyState === 'loading') { 40 document.addEventListener('DOMContentLoaded', initWPForms); 41 } else { 42 setTimeout(initWPForms, 100); 43 } 44 } 45 } 46 } 47 48 function openModal(productName, articleNumber) { 49 const modal = document.getElementById('watkins-ldp-call-to-action-modal'); 50 if (!modal) { 51 console.error('Watkins LDP: Reservation modal not found in DOM. Make sure the modal partial is included.'); 52 return; 53 } 54 55 const formContainer = modal.querySelector('.dsw-call-to-action-form-container'); 56 const spinner = modal.querySelector('.dsw-call-to-action-spinner'); 57 58 // Load form via AJAX with product parameters 59 if (formContainer) { 60 // Show spinner, clear previous form content 61 if (spinner) spinner.classList.remove('dsw-hidden'); 62 formContainer.innerHTML = ''; 63 64 const ajaxUrl = typeof watkinsLDPCallToActionModal !== 'undefined' ? watkinsLDPCallToActionModal.ajaxurl : '/wp-admin/admin-ajax.php'; 65 const params = new URLSearchParams({ 66 action: 'watkins_ldp_get_call_to_action_form', 67 pn: productName || '', 68 an: articleNumber || '' 69 }); 70 71 fetch(ajaxUrl + '?' + params.toString(), { 72 method: 'GET', 73 credentials: 'same-origin', 74 headers: { 75 'X-Requested-With': 'XMLHttpRequest' 76 } 77 }) 78 .then(response => response.json()) 79 .then(formResponse => { 80 if (formResponse.success) { 81 formContainer.innerHTML = formResponse.data.html; 82 executeFormShortcodeInlineScripts(formContainer); 83 } else { 84 formContainer.innerHTML = '<p class="dsw-text-red-600">' + formResponse.data.message + '</p>'; 85 } 86 }) 87 .catch(error => { 88 console.error('Error loading form:', error); 89 90 formContainer.innerHTML = '<p class="dsw-text-red-600">Error loading reservation form. Please try again.</p>'; 91 }) 92 .finally(() => { 93 if (spinner) spinner.classList.add('dsw-hidden'); 94 }); 95 } 96 97 document.body.style.overflow = 'hidden'; 98 99 modal.classList.remove('dsw-hidden'); 100 101 requestAnimationFrame(function() { 102 modal.classList.add('watkins-ldp-modal-active'); 103 }); 104 } 105 106 function closeModal() { 107 const modal = document.getElementById('watkins-ldp-call-to-action-modal'); 108 if (!modal) return; 109 110 modal.classList.remove('watkins-ldp-modal-active'); 111 document.body.style.overflow = ''; 112 113 setTimeout(function() { 114 modal.classList.add('dsw-hidden'); 115 }, 400); 116 } 117 118 function init() { 119 const modal = document.getElementById('watkins-ldp-call-to-action-modal'); 120 if (!modal) { 121 console.warn('Watkins LDP: Reservation modal not found. Make sure the modal partial is included in your template.'); 122 return; 123 } 124 125 document.addEventListener('click', function(e) { 126 const ctaButton = e.target.closest('[data-syndified-cta-button]'); 127 128 if (ctaButton) { 129 e.preventDefault(); 130 131 const productName = ctaButton.getAttribute('data-product-name'); 132 const articleNumber = ctaButton.getAttribute('data-article-number'); 133 134 openModal(productName, articleNumber); 135 } 136 }); 137 138 document.addEventListener('click', function(e) { 139 if (e.target.closest('.watkins-ldp-modal-close')) { 140 closeModal(); 141 } 142 }); 143 144 document.addEventListener('click', function(e) { 145 const modal = document.getElementById('watkins-ldp-call-to-action-modal'); 146 if (e.target === modal) { 147 closeModal(); 148 } 149 }); 150 151 document.addEventListener('keydown', function(e) { 152 if (e.key === 'Escape') { 153 const modal = document.getElementById('watkins-ldp-call-to-action-modal'); 154 if (modal && modal.classList.contains('watkins-ldp-modal-active')) { 155 closeModal(); 156 } 157 } 158 }); 159 } 160 161 if (document.readyState === 'loading') { 162 document.addEventListener('DOMContentLoaded', init); 163 } else { 164 init(); 165 } 166})();
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.