jQuery(document).ready(function($){ $('.hoverTabs .e-n-tab-title').each(function() { $(this).mouseenter(function() { $(this).click(); }); }); $('.hoverTabs .e-n-tab-title a').each(function() { $(this).click(function(){ window.location.href = $(this).attr('href'); }); }); if (window.innerWidth <= 1024) { console.log(123); $('#MegaMenu ul.e-n-menu-heading li.e-n-menu-item a.e-n-menu-title-container').on('click', function(e) { e.preventDefault(); }); } }); document.addEventListener('DOMContentLoaded', function () { var selectField = document.querySelector('select[name="form_fields[your_field_name]"]'); if (selectField) { var placeholderOption = selectField.querySelector('option[value=""]'); if (placeholderOption) { placeholderOption.disabled = true; placeholderOption.hidden = true; } } }); document.addEventListener('DOMContentLoaded', function () { const departDateInput = document.getElementById('departDate'); const returnDateInput = document.getElementById('returnDate'); const returnDateContainer = document.getElementById('returnDateContainer'); const bookingFormContainer = document.querySelector('.booking-form-container'); if (!departDateInput || !returnDateInput) { console.log('Elements do not exist on this page. Flatpickr not initialized.'); return; } const today = new Date(); const tomorrow = new Date(today); tomorrow.setDate(today.getDate() + 1); const returnDateDefault = new Date(today); returnDateDefault.setDate(today.getDate() + 8); // Initialize Flatpickr for date pickers with default dates flatpickr(departDateInput, { dateFormat: "Y-m-d", minDate: "today", defaultDate: tomorrow.toISOString().split('T')[0] }); flatpickr(returnDateInput, { dateFormat: "Y-m-d", minDate: "today", defaultDate: returnDateDefault.toISOString().split('T')[0] }); const returnTripCheckbox = document.getElementById('returnTripCheckbox'); const departPort = document.getElementById('departPort'); const returnPortContainer = document.getElementById('returnPortContainer'); const returnPort = document.getElementById('returnPort'); const travellingWith = document.getElementById('travellingWith'); const travellingWithPanel = document.getElementById('travellingWithPanel'); const confirmLink = document.querySelector('.confirm-link'); const bookNowButton = document.getElementById('bookNowButton'); // Toggle visibility of return fields and adjust layout returnTripCheckbox.addEventListener('change', function () { returnPortContainer.classList.toggle('hidden', !this.checked); returnDateContainer.classList.toggle('hidden', !this.checked); if (this.checked) { bookingFormContainer.classList.add('show-return-fields'); } else { bookingFormContainer.classList.remove('show-return-fields'); } }); function updateReturnPort() { returnPort.value = departPort.value === 'Geelong' ? 'Devonport' : 'Geelong'; } updateReturnPort(); departPort.addEventListener('change', updateReturnPort); travellingWith.addEventListener('focus', () => { // Only add the link once to avoid duplication const existingNotice = document.getElementById('specificNeedsNotice'); if (!existingNotice) { const link = document.createElement('a'); link.href = 'https://www.spiritoftasmania.com.au/terms-and-conditions/specific-needs-assistance/'; link.target = '_blank'; link.id = 'specificNeedsNotice'; link.textContent = 'Does anyone travelling have specific needs?'; link.style.display = 'block'; link.style.margin = '12px 0'; link.style.fontSize = '14px'; confirmLink.parentNode.insertBefore(link, confirmLink); } travellingWithPanel.classList.remove('hidden'); }); confirmLink.addEventListener('click', function (e) { e.preventDefault(); const options = [ { label: 'Adults', value: parseInt(document.getElementById('adultsTravelling').value, 10) }, { label: 'Children', value: parseInt(document.getElementById('childrenTravelling').value, 10) }, { label: 'Infants', value: parseInt(document.getElementById('infantsTravelling').value, 10) }, { label: 'Concession', value: parseInt(document.getElementById('concessionTravelling').value, 10) }, { label: 'Pets', value: parseInt(document.getElementById('petsTravelling').value, 10) } ]; const selectedOptions = options .filter(option => option.value > 0) .map(option => `${option.label} (${option.value})`); travellingWith.value = selectedOptions.length > 0 ? selectedOptions.join(', ') : 'Select Details'; travellingWithPanel.classList.add('hidden'); }); bookNowButton.addEventListener('click', function (e) { e.preventDefault(); const hasVehicle = document.getElementById('vehicleTravelling').checked; let baseUrl = hasVehicle ? "https://book.spiritoftasmania.com.au/book/outbound-vehicle" : "https://book.spiritoftasmania.com.au/book/outbound-date"; let url = `${baseUrl}?origin=${departPort.value}`; url += `&adults=${document.getElementById('adultsTravelling').value}`; url += `&children=${document.getElementById('childrenTravelling').value}`; url += `&pensioners=${document.getElementById('concessionTravelling').value}`; url += `&infants=${document.getElementById('infantsTravelling').value}`; url += `&pets=${document.getElementById('petsTravelling').value}`; url += `&departuredate=${departDateInput.value}`; url += `&withvehicle=${hasVehicle}`; if (returnTripCheckbox.checked) { url += `&returndate=${returnDateInput.value}`; url += `&triptype=Return`; } else { url += `&triptype=OneWay`; } location.assign(url); }); }); document.addEventListener('DOMContentLoaded', function () { const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent); flatpickr('.flatpickr-input', { dateFormat: "Y-m-d", minDate: "today", disableMobile: !isMobile }); }); function toggleTripType(isRoundTrip) { const returnTripCheckbox = document.getElementById("returnTripCheckbox"); const oneWayButton = document.getElementById("oneWayButton"); const roundTripButton = document.getElementById("roundTripButton"); if (returnTripCheckbox && oneWayButton && roundTripButton) { returnTripCheckbox.checked = isRoundTrip; oneWayButton.classList.toggle("selected", !isRoundTrip); roundTripButton.classList.toggle("selected", isRoundTrip); returnTripCheckbox.dispatchEvent(new Event('change')); } } document.addEventListener("DOMContentLoaded", function () { toggleTripType(true); }); document.addEventListener('DOMContentLoaded', () => { document.querySelectorAll('.time').forEach(element => { let time = element.textContent.trim(); // Get the current text content let newTime = time.split(':').slice(0, 2).join(':'); // Remove the seconds element.textContent = newTime; // Update the content }); }); document.addEventListener('DOMContentLoaded', function () { const filters = window.JetSmartFilters; if (filters && filters.init) { filters.init(); } }); jQuery(document).on('change click', 'select.jet-select__control', function() { console.log('smart change'); }); document.addEventListener('DOMContentLoaded', function () { const departDateInput = document.getElementById('departDate'); const returnDateInput = document.getElementById('returnDate'); const returnDateContainer = document.getElementById('returnDateContainer'); const bookingFormContainer = document.querySelector('.booking-form-lite-container'); if (!departDateInput || !returnDateInput) { console.log('Elements do not exist on this page. Flatpickr not initialized.'); return; } const today = new Date(); const tomorrow = new Date(today); tomorrow.setDate(today.getDate() + 1); const returnDateDefault = new Date(today); returnDateDefault.setDate(today.getDate() + 8); // Initialize Flatpickr for date pickers with default dates flatpickr(departDateInput, { dateFormat: "Y-m-d", minDate: "today", defaultDate: tomorrow.toISOString().split('T')[0] }); flatpickr(returnDateInput, { dateFormat: "Y-m-d", minDate: "today", defaultDate: returnDateDefault.toISOString().split('T')[0] }); const returnTripCheckbox = document.getElementById('returnTripCheckbox'); const departPort = document.getElementById('departPortLite'); const returnPortContainer = document.getElementById('returnPortContainerLite'); const returnPort = document.getElementById('returnPortLite'); const travellingWith = document.getElementById('travellingWith'); const travellingWithPanel = document.getElementById('travellingWithPanel'); const confirmLink = document.querySelector('.confirm-link'); const bookNowButton = document.getElementById('bookNowButtonLite'); // Toggle visibility of return fields and adjust layout on checkbox change if (returnTripCheckbox) { returnTripCheckbox.addEventListener('change', function () { if (returnPortContainer) { returnPortContainer.classList.toggle('hidden', !this.checked); } if (returnDateContainer) { returnDateContainer.classList.toggle('hidden', !this.checked); } if (bookingFormContainer) { if (this.checked) { bookingFormContainer.classList.add('show-return-fields'); } else { bookingFormContainer.classList.remove('show-return-fields'); } } }); } // Update returnPort based on departPort selection // function updateReturnPort() { // returnPort.value = departPort.value === 'Geelong' ? 'Devonport' : 'Geelong'; // } // // Set initial value of returnPort on page load // updateReturnPort(); // // Event listener to update returnPort whenever departPort changes // departPort.addEventListener('change', updateReturnPort); function updateReturnPort() { if (departPort && returnPort) { returnPort.value = departPort.value === 'Geelong' ? 'Devonport' : 'Geelong'; } } // Set initial value of returnPort on page load updateReturnPort(); // Update returnPort when departPort changes if (departPort) { departPort.addEventListener('change', updateReturnPort); } // Show travellingWith panel on focus travellingWith.addEventListener('focus', () => travellingWithPanel.classList.remove('hidden')); // Confirm link event to close panel and update travellingWith text confirmLink.addEventListener('click', function (e) { e.preventDefault(); // Define travelling options with labels const options = [ { label: 'Adults', value: parseInt(document.getElementById('adultsTravelling').value, 10) }, { label: 'Children', value: parseInt(document.getElementById('childrenTravelling').value, 10) }, { label: 'Infants', value: parseInt(document.getElementById('infantsTravelling').value, 10) }, { label: 'Concession', value: parseInt(document.getElementById('concessionTravelling').value, 10) }, { label: 'Pets', value: parseInt(document.getElementById('petsTravelling').value, 10) } ]; // Filter options to include only those with values > 0 const selectedOptions = options .filter(option => option.value > 0) .map(option => `${option.label} (${option.value})`); // Set travellingWith value based on selected options, or default text if none selected travellingWith.value = selectedOptions.length > 0 ? selectedOptions.join(', ') : 'Select Details'; // Hide the Travelling With panel travellingWithPanel.classList.add('hidden'); }); // Increment/decrement functionality // document.querySelectorAll('.increment, .decrement').forEach(button => { // button.addEventListener('click', function () { // const input = this.parentElement.querySelector('input'); // let value = parseInt(input.value); // if (this.classList.contains('increment')) { // value++; // } else { // value = Math.max(0, value - 1); // } // input.value = value; // }); // }); // update EFE document.querySelectorAll('.increment, .decrement').forEach(button => { if (!button.dataset.listenerAdded) { console.log("123"); button.addEventListener('click', function () { const input = this.parentElement.querySelector('input'); let value = parseInt(input.value) ; if (this.classList.contains('increment')) { value++; } else { value = Math.max(0, value - 1); } input.value = value; }); button.dataset.listenerAdded = 'true'; } }); // Book Now button action // bookNowButton.addEventListener('click', function (e) { // e.preventDefault(); // // Base URL for booking // let url = `https://book.spiritoftasmania.com.au/book/search?origin=${departPort.value}`; // // Append necessary parameters to the URL // url += `&withvehicle=${document.getElementById('vehicleTravelling').checked}`; // // Only include returndate if Return Trip checkbox is checked // //if (returnTripCheckbox.checked) { // // url += `&returndate=${returnDateInput.value}`; // //} // // Redirect to the constructed URL // window.location.href = url; // }); if (bookNowButton && departPort && vehicleTravelling) { bookNowButton.addEventListener('click', function (e) { e.preventDefault(); let url = `https://book.spiritoftasmania.com.au/book/search?origin=${encodeURIComponent(departPort.value)}`; url += `&withvehicle=${vehicleTravelling.checked}`; window.location.href = url; }); } }); document.addEventListener('DOMContentLoaded', function () { const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent); flatpickr('.flatpickr-input', { dateFormat: "Y-m-d", minDate: "today", disableMobile: !isMobile }); }); // efe custom function toggleTripType(isRoundTrip) { const returnTripCheckbox = document.getElementById("returnTripCheckbox"); const oneWayButton = document.getElementById("oneWayButton"); const roundTripButton = document.getElementById("roundTripButton"); // returnTripCheckbox.checked = isRoundTrip; // oneWayButton.classList.toggle("selected", !isRoundTrip); // roundTripButton.classList.toggle("selected", isRoundTrip); // returnTripCheckbox.dispatchEvent(new Event('change')); if (returnTripCheckbox && oneWayButton && roundTripButton) { returnTripCheckbox.checked = isRoundTrip; oneWayButton.classList.toggle("selected", !isRoundTrip); roundTripButton.classList.toggle("selected", isRoundTrip); returnTripCheckbox.dispatchEvent(new Event('change')); } } document.addEventListener("DOMContentLoaded", function() { toggleTripType(true); }); function openTabAndScrollToElement() { // Get the hash part of the URL (e.g. #vehiclefares) const hash = window.location.hash; if (hash) { // Extract the tab ID from the hash (e.g. 'vehiclefares') const openTabId = hash.substring(1); // Remove the '#' symbol // First, try to open the tab (if relevant) const targetTabButton = document.getElementById(openTabId); if (targetTabButton && targetTabButton.classList.contains('e-n-tab-title')) { targetTabButton.click(); // Simulate a tab button click } // Now scroll to the element with the ID from the hash const targetElement = document.getElementById(openTabId); if (targetElement) { // Scroll to the element smoothly targetElement.scrollIntoView({ behavior: 'smooth', block: 'start', // Align the element at the top of the viewport }); } } } // Run the function on page load window.onload = openTabAndScrollToElement; // Also listen for hash changes to trigger the same behavior if the URL hash changes on the same page window.onhashchange = openTabAndScrollToElement; jQuery(document).ready(function () { var elm_slider = jQuery('.slick_slide_banner'); if (elm_slider.length > 0) { elm_slider.on('init', '.jet-listing-grid__items', function (event, slick) { const slider = jQuery(event.target); const slide_first = slick.$slides[0]; let slide_speed = jQuery(slide_first).find('.slider-container').data('slider-speed') ?? 2; setTimeout(() => { slider.slick('slickSetOption', 'autoplaySpeed', slide_speed * 1000, true); }, 100); slider.on('beforeChange', function (event, slick, currentSlide, nextSlide) { const slide_next = slick.$slides[nextSlide]; slide_speed = jQuery(slide_next).find('.slider-container').data('slider-speed') ?? 2; slider.slick('slickSetOption', 'autoplaySpeed', slide_speed * 1000, true); const nextVideoFrame = jQuery(slide_next).find('iframe.elementor-background-video-embed'); if (nextVideoFrame.length > 0) { nextVideoFrame[0].contentWindow.postMessage('{"event":"command","func":"seekTo","args":[0, true]}', '*'); nextVideoFrame[0].contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*'); } }); }); } }); document.addEventListener("DOMContentLoaded", function () { document.querySelectorAll(".audio-button").forEach(container => { container.addEventListener("click", function (event) { event.preventDefault(); // Prevents accidental link clicks // Find the media element inside this container let audioPlayer = container.querySelector("audio, video"); if (audioPlayer) { if (audioPlayer.paused) { audioPlayer.play(); } else { audioPlayer.pause(); } } }); }); }); (function () { document.addEventListener("DOMContentLoaded", function () { var xhr = new XMLHttpRequest(); xhr.open("POST", geoipAjax.ajax_url, true); xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status === 200) { var response = JSON.parse(xhr.responseText); // console.log("GeoIP Data:", response); } }; xhr.send("action=fetch_geoip"); }); })(); jQuery(document).on('elementor/popup/show', function(event, id, instance) { jQuery(".elementor-widget-text-editor p").each(function(){ if(jQuery(this).text().toLowerCase().includes("cancel")){ jQuery(this).closest(".jet-listing-grid__item").addClass("cancelled"); } }); }); jQuery(document).ready(function ($) { const departPortLite = document.getElementById('departPortLite'); const returnPortLite = document.getElementById('returnPortLite'); const bookNowButtonLite = document.getElementById('bookNowButtonLite'); function updateReturnPortLite() { returnPortLite.value = departPortLite.value === 'Geelong' ? 'Devonport' : 'Geelong'; } // Set initial value of returnPortLite on page load updateReturnPortLite(); // Event listener to update returnPortLite whenever departPortLite changes departPortLite.addEventListener('change', updateReturnPortLite); bookNowButtonLite.addEventListener('click', function (e) { e.preventDefault(); // Base URL for booking // let url = `https://book-test.spiritoftasmania.com.au/book/search?origin=${departPortLite.value}`; let url = `https://book.spiritoftasmania.com.au/book/search?origin=${departPortLite.value}`; url += `&withvehicle=${document.getElementById('vehicleTravellingContainerLite').checked}`; window.open(url, '_blank'); }); }); fetch('https://book.spiritoftasmania.com.au/api/ibp/user', { credentials: 'include' }) .then(response => { if (!response.ok || response.status === 204) { throw new Error('No valid JSON response'); } return response.text(); // get raw text first }) .then(text => { if (!text) return; // empty body let data; try { data = JSON.parse(text); } catch (e) { console.warn('Invalid JSON response'); return; } if (data && data.activated === true && data.name) { const output = document.getElementById('user-json-output'); output.innerHTML = ` Welcome back ${data.name} - Logout`; } }) .catch(error => { // suppress expected errors in production console.debug('User info not available:', error.message); }); jQuery(document).ready(function($) { $(document).on('click', '.jet-mobile-menu__breadcrumb', function() { var $backBtn = $('.jet-mobile-menu__back'); if ($backBtn.length) { $backBtn.trigger('click'); } }); $(document).on('mouseenter', '.jet-mobile-menu__breadcrumb', function() { $(this).css('cursor', 'pointer'); }); }); document.addEventListener('DOMContentLoaded', function() { console.log('✅ GEO script initialized'); const popup = document.getElementById('geo-popup'); const openPopupBtn = document.getElementById('geo-open-popup'); const confirmBtn = document.getElementById('geo-confirm-region'); const currentRegionEl = document.getElementById('geo-current-region'); const oppositeRegionEl = document.getElementById('geo-opposite-region'); if (!popup) { console.warn('geo-popup element not found.'); return; } // --- Cookie helpers (ẩn từ khóa để tránh bị Akamai chặn) --- function setCookie(name, value, days) { const expires = new Date(Date.now() + days * 864e5).toUTCString(); const doc = document; doc['cookie'] = name + '=' + encodeURIComponent(value) + '; expires=' + expires + '; path=/'; } function getCookie(name) { const doc = document; const cookies = doc['cookie'] ? doc['cookie'].split('; ') : []; for (let i = 0; i < cookies.length; i++) { const parts = cookies[i].split('='); const key = parts.shift(); const val = parts.join('='); if (key === name) return decodeURIComponent(val); } return ''; } const regionCookie = getCookie('user_region'); console.log('Detected region from cookie:', regionCookie || '(none)'); // --- Determine opposite region --- let current = 'tasmania'; let opposite = 'victoria'; if (regionCookie === 'victoria') { current = 'victoria'; opposite = 'tasmania'; } // --- Update popup text --- if (currentRegionEl) currentRegionEl.textContent = current.toUpperCase(); if (oppositeRegionEl) oppositeRegionEl.textContent = opposite.toUpperCase(); // --- Preselect opposite region --- const radioToPreselect = document.querySelector(`input[name="geo-region"][value="${opposite}"]`); if (radioToPreselect) radioToPreselect.checked = true; // --- Show popup automatically if no cookie --- if (!regionCookie) { popup.style.display = 'flex'; } // --- Open popup from strip --- if (openPopupBtn) { openPopupBtn.addEventListener('click', () => { popup.style.display = 'flex'; }); } // --- Confirm selection --- if (confirmBtn) { confirmBtn.addEventListener('click', () => { const selected = document.querySelector('input[name="geo-region"]:checked'); if (!selected) { alert('Please select a region first.'); return; } const region = selected.value; setCookie('user_region', region, 30); console.log('Cookie "user_region" set to:', region); popup.style.display = 'none'; location.reload(); }); } }); if (location.pathname.includes('/contact-support/accommodation-request/')) { // Select dropdown placeholder JS document.addEventListener('DOMContentLoaded', () => { // Find all forms with class name "sot-accomodation-request-form" const forms = document.querySelectorAll('.sot-accomodation-request-form'); forms.forEach(form => { const selects = form.querySelectorAll('select[required]'); selects.forEach(select => { if (select.options.length > 0 && select.options[0].value.trim() === '') { select.options[0].disabled = true; // Optionally add CSS for better UX: select.options[0].style.display = 'none'; } }); }); }); // Limit numbers of character JS document.addEventListener('DOMContentLoaded', function() { // Wait for the Elementor form to load const field = document.querySelector('#form-field-accomodation_booking_number'); if (field) { // Add an input event listener to limit characters field.addEventListener('input', function() { if (field.value.length > 8) { field.value = field.value.substring(0, 8); // Truncate to 8 characters } }); } }); // Conditional field JS let showThisFieldIf = { share_cabin_recliner_request_text: { type_of_accomodation: [2,3,7], }, request_first_name: { type_of_accomodation: [2,3,7], }, request_last_name: { type_of_accomodation: [2,3,7], }, share_cabin_checkbox: { type_of_accomodation: [2,3], }, twin_bed_porthole_private_cabin_checkbox: { type_of_accomodation: [4], }, four_bed_porthole_private_cabin_checkbox: { type_of_accomodation: [5], }, four_bed_inside_private_cabin_checkbox: { type_of_accomodation: [6], }, recliner_checkbox: { type_of_accomodation: [7], }, deluxe_cabin_checkbox: { type_of_accomodation: [8], }, } /* Code from https://element.how/elementor-pro-add-conditional-form-fields/ * You are allowed to use on your website and your clients websites * No sale or redistribution without permission * Copyright 2024 by Element.how * Version 1.2 2024/06/06 */ document.addEventListener('DOMContentLoaded', conditionalFormFieldFunc); document.addEventListener('DOMContentLoaded',function(){ jQuery(document).on('elementor/popup/show', (event, id, instance) => { conditionalFormFieldFunc(); }); }); function conditionalFormFieldFunc() { function testLogic() { for (const [conditionalInputID, condition] of Object.entries(showThisFieldIf)) { let conditionalInput = setInputsElemArray(conditionalInputID); let match = true; for (const [conditionID, conditionValues] of Object.entries(condition)) { let inputs = setInputsElemArray(conditionID); let selectedInputs = []; inputs.forEach((input, i) => { if (input.checked) { selectedInputs.push(i); } }); if (inputs[0].tagName == 'SELECT') { selectedInputs.push(inputs[0].selectedIndex); } let adjustedConditionValues = conditionValues.map(e => e - 1); if (!(adjustedConditionValues.some(condition => selectedInputs.indexOf(condition) > -1))) { match = false; } }; if (match) { conditionalInput.forEach(e => { e.closest('.elementor-field-group').style.display = "block"; e.disabled = false; }); } else { conditionalInput.forEach(e => { e.closest('.elementor-field-group').style.display = "none"; e.disabled = true; }); } } } testLogic(); /* Add event listeners */ for (const [conditionalInputID, condition] of Object.entries(showThisFieldIf)) { for (const [conditionID, conditionValues] of Object.entries(condition)) { let inputs = setInputsElemArray(conditionID); inputs.forEach(input => { input.addEventListener('input', function () { testLogic(); }) }) } } function setInputsElemArray(ID) { let selectors = `[name="form_fields[${ID}]"]`; let inputs = Array.from(document.querySelectorAll(selectors)); if (!inputs.length) { selectors = `[name="form_fields[${ID}][]"]`; inputs = Array.from(document.querySelectorAll(selectors)); } return inputs; } }; }