window.$ = window.jQuery = jQuery; // Keep a local alias for backward compatibility with existing scripts var $ = jQuery; $mainHeaderHeight = $('.main-header').outerHeight(); $stickyHeaderHeight = $('.header-sticky').outerHeight(); /* Script on ready ------------------------------------------------------------------------------*/ $(document).ready(function () { function setStickyHeaderHeight() { $mainHeaderHeight = $('.main-header').outerHeight(); $stickyHeaderHeight = $('.header-sticky').outerHeight(); document.documentElement.style.setProperty('--sticky-header-height', $stickyHeaderHeight + 'px'); } function toggleStickyHeader() { var scrollTop = $(window).scrollTop(); var isSticky = scrollTop > 1; $('.header-sticky').toggleClass('sticky', isSticky); $('body').toggleClass('sticky-header-active', isSticky); if (isSticky) { $('.header-static').hide(); } else { $('.header-static').show(); } } setStickyHeaderHeight(); toggleStickyHeader(); if ($('.home-banner-slider').length > 0 || $('.about-section').length > 0 || $('.catDetailSection').length > 0 || $('.subCatProduct-section').length > 0 || $('.downloads-wrapper').length > 0 || $('.client-tabs').length > 0) { $('.wow').each(function () { var currentDuration = $(this).attr('data-wow-duration'); var currentOffset = parseInt($(this).attr('data-wow-offset'), 10); if (!currentDuration || currentDuration === '2s' || currentDuration === '0.7s') { $(this).attr('data-wow-duration', '0.85s'); } if (isNaN(currentOffset) || currentOffset < 80) { $(this).attr('data-wow-offset', '100'); } }); } if ($('.catDetailSection').length > 0) { $('.catDetailSection .wow').each(function () { $(this).attr('data-wow-duration', '0.75s'); $(this).attr('data-wow-offset', '120'); }); } if ($('.subCatProduct-section').length > 0) { $('.subCatProduct-section .wow, .catProductDescSection .wow').each(function () { $(this).attr('data-wow-duration', '0.75s'); $(this).attr('data-wow-offset', '120'); }); } if ($('.downloads-wrapper').length > 0) { $('.downloads-wrapper .wow').each(function () { $(this).attr('data-wow-duration', '0.65s'); $(this).attr('data-wow-offset', '140'); }); } if ($('.client-tabs').length > 0) { $('.client-tabs .wow, .ourClients-wrapper .wow').each(function () { $(this).attr('data-wow-duration', '0.65s'); $(this).attr('data-wow-offset', '140'); }); } /* Responsive/dropdown Navigation */ $('.main-dropdown-nav, .main-dropdown-nav ul li ul').slideUp(); if (window.matchMedia('(max-width: 1199px)').matches) { $('.main-dropdown-nav-wrap .hamburger').click(function () { $(this).toggleClass('is-open'); $(this).parents('.main-dropdown-nav-wrap').find('.main-dropdown-nav').slideToggle(); }); }; $(document).mouseup(function (e) { var maindropdown = $(".main-dropdown-nav-wrap"); if (!maindropdown.is(e.target) && maindropdown.has(e.target).length === 0) { $('.main-dropdown-nav-wrap .hamburger').removeClass('is-open'); $('.main-dropdown-nav').slideUp(); } }); $('.main-dropdown-nav ul li ul').parent().addClass('has-child'); $('.main-dropdown-nav ul li.has-child').prepend(''); $('.menu-open-button').click(function () { $(this).toggleClass('child-open'); $(this).parent().find('ul').slideToggle(); }); /* header sticky */ $(window).scroll(function () { toggleStickyHeader(); }); $(window).on('resize', function () { setStickyHeaderHeight(); toggleStickyHeader(); }); /* home-slider */ setInterval(function () { $(".boxnav__item--next").click(); }, 5000); /* mobile search */ $('.mobile-header-search').click(function () { $(this).addClass('active'); $(this).find('input[type="search"]').focus(); }); $(document).mouseup(function (e) { var maindropdown = $(".mobile-header-search"); if (!maindropdown.is(e.target) && maindropdown.has(e.target).length === 0) { $('.mobile-header-search').removeClass('active'); } }); $(document).on('click focus', 'input[type="date"]', function () { if (typeof this.showPicker === 'function') { this.showPicker(); } else { this.focus(); } }); function syncEmptyFieldState(field) { var isEmpty = !$(field).val(); $(field).toggleClass('is-placeholder', isEmpty); } $('.gi-field select, .gi-field input[type="date"]').each(function () { syncEmptyFieldState(this); }); $(document).on('change input', '.gi-field select, .gi-field input[type="date"]', function () { syncEmptyFieldState(this); }); /* Home banner slider */ if ($('.home-banner-slider').length > 0) { var homeBannerSliderActive = ".home-banner-slider"; var homeBannerSliderInit = new Swiper(homeBannerSliderActive, { loop: true, slidesPerView: 1, effect: "fade", speed: 600, autoplay: { delay: 7000, disableOnInteraction: false, }, navigation: { nextEl: '.swiper-button-prev', prevEl: '.swiper-button-next', }, pagination: { el: ".home-banner-slider-dots", clickable: true, }, normalizeSlideIndex: true, }); /* Home banner slide animation */ function animated_swiper(selector, init) { var animated = function animated() { $(selector + " [data-animation]").each(function () { var anim = $(this).data("animation"); var delay = $(this).data("delay"); var duration = $(this).data("duration"); $(this) .removeClass("anim" + anim) .addClass(anim + " animated") .css({ webkitAnimationDelay: delay, animationDelay: delay, webkitAnimationDuration: duration, animationDuration: duration, }) .one("animationend", function () { $(this).removeClass(anim + " animated"); }); }); }; animated(); init.on("slideChange", function () { $(homeBannerSliderActive + " [data-animation]").removeClass("animated"); }); init.on("slideChange", animated); } animated_swiper(homeBannerSliderActive, homeBannerSliderInit); } /* Home banner end */ setOwnCarousalPosition(); var owlOurProcess = $(".ourProcess-wrapper .owl-carousel"); owlOurProcess.owlCarousel({ autoWidth: true, autoHeight: true, loop: true, margin: 0, nav: true, navText: ["", ""], autoplay: 2000, autoplaySpeed: 1000, responsive: { 0: { items: 1, autoWidth: false, }, 575: { items: 3 }, 1000: { items: 3 } } }); $('.ourProcess-wrapper .ourProcess-box').on('mouseover', function (e) { owlOurProcess.trigger('stop.owl.autoplay'); }); $('.ourProcess-wrapper .ourProcess-box').on('mouseleave', function (e) { owlOurProcess.trigger('play.owl.autoplay'); }); var owlOurClients = $(".ourClients-wrapper .owl-carousel"); owlOurClients.owlCarousel({ loop: true, margin: 0, nav: true, slideBy: 'page', navText: ["", ""], autoplay: 2000, autoplaySpeed: 1000, responsive: { 0: { items: 1 }, 575: { items: 2 }, 768: { items: 3 } } }); $('.ourClients-wrapper .ourClient-box').on('mouseover', function (e) { owlOurClients.trigger('stop.owl.autoplay'); }); $('.ourClients-wrapper .ourClient-box').on('mouseleave', function (e) { owlOurClients.trigger('play.owl.autoplay'); }); var owlOurBlogs = $(".ourBlogs-wrapper .owl-carousel"); owlOurBlogs.owlCarousel({ loop: true, margin: 10, nav: true, navText: ["", ""], items: 1, autoplay: 2000, autoplaySpeed: 1000, }); $('.ourBlogs-wrapper .ourBlogs-box').on('mouseover', function (e) { owlOurBlogs.trigger('stop.owl.autoplay'); }); $('.ourBlogs-wrapper .ourBlogs-box').on('mouseleave', function (e) { owlOurBlogs.trigger('play.owl.autoplay'); }); var owlOurCategories = $(".ourCategories-wrapper .owl-carousel"); owlOurCategories.owlCarousel({ loop: true, margin: 0, nav: true, navText: ["", ""], autoplay: 2000, autoplaySpeed: 1000, responsive: { 0: { items: 1 }, 575: { items: 2 }, 768: { items: 3 }, 992: { items: 4 } } }); $('.ourCategories-wrapper .ourCategories-box').on('mouseover', function (e) { owlOurCategories.trigger('stop.owl.autoplay'); }); $('.ourCategories-wrapper .ourCategories-box').on('mouseleave', function (e) { owlOurCategories.trigger('play.owl.autoplay'); }); var ourVenturesItemCount = $('.owl-carousel .item').length; // Get the number of items var owlOurVentures = $(".ourVentures-wrapper .owl-carousel"); owlOurVentures.owlCarousel({ loop: ourVenturesItemCount >= 3, // Only loop if there are 4 or more items margin: 50, nav: true, navText: ["", ""], autoplay: ourVenturesItemCount >= 3, // Only autoplay if there are 4 or more items autoplaySpeed: 1000, responsive: { 0: { items: 1, margin: 10, }, 768: { items: 2, margin: 20, }, 992: { items: 3, margin: 30, }, 1200: { items: 3, margin: 40, } } }); $('.ourVentures-wrapper .ourVentures-box').on('mouseover', function (e) { owlOurVentures.trigger('stop.owl.autoplay'); }); $('.ourVentures-wrapper .ourVentures-box').on('mouseleave', function (e) { owlOurVentures.trigger('play.owl.autoplay'); }); /* subCatDetail-pills slider */ if ($('.subCatDetail-pills-slider').length > 0) { $('.subCatDetail-pills-slider').slick({ infinite: true, slidesToShow: 4, prevArrow: "", nextArrow: "", focusOnSelect: true, variableWidth: true, pauseOnHover: true, responsive: [ { breakpoint: 992, settings: { slidesToShow: 3, }, }, { breakpoint: 768, settings: { slidesToShow: 2, }, }, { breakpoint: 575, settings: { slidesToShow: 1, }, }, ], }); } /* subCatProducts-pills slider */ if ($('.subCatProducts-pills-main-slider').length > 0) { $('.subCatProducts-pills-main-slider').slick({ infinite: true, variableWidth: true, prevArrow: "", nextArrow: "", focusOnSelect: true, pauseOnHover: true, responsive: [ { breakpoint: 575, settings: { variableWidth: false, slidesToShow: 1, }, }, ], }); } if ($('.subCatProducts-pills-inner-slider').length > 0) { $('.subCatProducts-pills-inner-slider').slick({ infinite: true, variableWidth: true, prevArrow: "", nextArrow: "", focusOnSelect: true, pauseOnHover: true, responsive: [ { breakpoint: 575, settings: { variableWidth: false, slidesToShow: 1, }, }, ], }); } /* footer sliders */ var connectWithUsSlider = $('.connect-with-us .owl-carousel'); var connectWithUsItemCount = connectWithUsSlider.children().length; var connectWithUsCanSlide = connectWithUsItemCount > 1; connectWithUsSlider.owlCarousel({ loop: false, rewind: false, nav: false, dots: false, navText: ["", ""], autoplay: false, autoplaySpeed: 1000, responsive: { 0: { items: 1, margin: 10, loop: connectWithUsCanSlide, rewind: connectWithUsCanSlide, nav: connectWithUsCanSlide, dots: connectWithUsCanSlide, autoplay: connectWithUsCanSlide, }, 640: { items: Math.min(connectWithUsItemCount, 2), margin: 20, loop: false, rewind: false, nav: false, dots: false, autoplay: false, }, 992: { items: Math.min(connectWithUsItemCount, 3), margin: 30, loop: false, rewind: false, nav: false, dots: false, autoplay: false, }, 1366: { items: Math.min(connectWithUsItemCount, 4), margin: 30, loop: false, rewind: false, nav: false, dots: false, autoplay: false, } } }); $('.footer-bottom-row.owl-carousel').owlCarousel({ dots: false, mouseDrag: false, nav: true, navText: ["", ""], autoplay: 2000, autoplaySpeed: 1000, responsive: { 0: { items: 1, loop: true, autoplay: { delay: 2000, }, }, 575: { items: 2, loop: true, autoplay: { delay: 2000, }, }, 992: { items: 3, }, } }); /* product slider with tabs */ if ($('.ourProducts-wrapper').length > 0) { var $ourProductsContent = $('.ourProducts-content-gg'); var $ourProductsBottomBar = $('.ourProducts-bottombar'); var $ourProductsTabs = $('.ourProducts-wrapper .tabs').not('.product-page-slide-tabs'); function getNormalizedPortfolioSlideIndex($slider) { var slickInstance = $slider.slick('getSlick'); var slideCount = slickInstance && slickInstance.slideCount ? slickInstance.slideCount : 0; var currentIndex = $slider.find('.slick-current').data('slick-index'); if (typeof currentIndex !== 'number') { currentIndex = $slider.slick('slickCurrentSlide'); } if (!slideCount) { return 0; } return ((currentIndex % slideCount) + slideCount) % slideCount; } function syncPortfolioIndicators() { var activeSlideNumber = getNormalizedPortfolioSlideIndex($ourProductsTabs) + 1; $ourProductsBottomBar.find('.carousel-indicators .indicator').removeClass('active'); $ourProductsBottomBar.find('.carousel-indicators .indicator[data-slide="' + activeSlideNumber + '"]').addClass('active'); } $ourProductsContent.slick({ slidesToShow: 1, slidesToScroll: 1, arrows: false, autoplay: true, autoplaySpeed: 4000, pauseOnHover: true, speed: 350, waitForAnimate: false, asNavFor: '.ourProducts-wrapper .tabs', fade: true, cssEase: 'linear' }); $ourProductsTabs.slick({ variableWidth: true, slidesToScroll: 1, speed: 350, waitForAnimate: false, asNavFor: '.ourProducts-content-gg', prevArrow: "", nextArrow: "", focusOnSelect: true, responsive: [ { breakpoint: 575, settings: { variableWidth: false, slidesToShow: 1, }, }, ], }); $ourProductsBottomBar.find('.owl-prev').on('click', function (event) { event.preventDefault(); $ourProductsContent.slick('slickPrev'); }); $ourProductsBottomBar.find('.owl-next').on('click', function (event) { event.preventDefault(); $ourProductsContent.slick('slickNext'); }); // Click event for indicators $ourProductsBottomBar.find('.carousel-indicators .indicator').on('click', function () { var slideNumber = parseInt($(this).data('slide'), 10); var slideIndex = slideNumber - 1; if (slideIndex >= 0) { $ourProductsContent.slick('slickGoTo', slideIndex); $ourProductsBottomBar.find('.carousel-indicators .indicator').removeClass('active'); $(this).addClass('active'); } }); $ourProductsContent.on('init reInit afterChange setPosition', syncPortfolioIndicators); $ourProductsTabs.on('init reInit afterChange setPosition', syncPortfolioIndicators); syncPortfolioIndicators(); } if ($('.product-page-slide-list').length > 0) { $('.ourProducts-wrapper').each(function () { var $section = $(this); var $marquee = $section.find('[data-product-tabs-marquee]'); var $viewport = $section.find('[data-tabs-viewport]'); var $tabs = $viewport.find('.tabs'); var $list = $section.find('.product-page-slide-list'); var $loadMoreButton = $section.find('[data-load-more-products]'); var step = parseInt($loadMoreButton.attr('data-load-step'), 10) || 3; var visibleCount = step; var autoScrollSpeed = 0.6; var autoScrollTimer = null; var isPaused = false; var originalTabsWidth = 0; var currentOffset = 0; if ($marquee.length === 0 || $viewport.length === 0 || $tabs.length === 0 || $list.length === 0) { return; } if ($tabs.find('[data-clone-tab]').length === 0) { $tabs.children('[data-product-tab]').clone().attr('data-clone-tab', 'true').removeClass('is-active slick-current').appendTo($tabs); } function getOriginalTabButtons() { return $tabs.find('[data-product-tab]').not('[data-clone-tab], .slick-cloned [data-product-tab], .slick-cloned'); } function updateTabsWidth() { originalTabsWidth = 0; getOriginalTabButtons().each(function () { originalTabsWidth += $(this).outerWidth(true); }); currentOffset = originalTabsWidth > 0 ? currentOffset % originalTabsWidth : 0; renderTabsPosition(); } function renderTabsPosition() { $tabs.css('transform', 'translate3d(' + (-currentOffset) + 'px, 0, 0)'); } function refreshVisibleItems() { var $items = $list.find('[data-product-item]'); $items.each(function () { var $item = $(this); var $row = $item.find('.row').first(); var itemIndex = parseInt($item.attr('data-product-index'), 10); $item.toggleClass('is-hidden', itemIndex >= visibleCount); $row.toggleClass('product-page-slide-row-reverse', itemIndex % 2 !== 0); }); $loadMoreButton.toggle($items.length > visibleCount); } function syncActiveTabs(targetIndex) { $tabs.find('[data-product-tab]').removeClass('is-active slick-current'); $tabs.find('[data-product-tab="' + targetIndex + '"]').addClass('is-active slick-current'); } function centerTabInViewport(targetIndex) { var $targetTab = getOriginalTabButtons().filter('[data-product-tab="' + targetIndex + '"]').first(); if ($targetTab.length === 0 || originalTabsWidth === 0) { return; } var targetOffset = $targetTab.position().left - (($viewport.innerWidth() - $targetTab.outerWidth()) / 2); while (targetOffset < 0) { targetOffset += originalTabsWidth; } while (targetOffset >= originalTabsWidth) { targetOffset -= originalTabsWidth; } currentOffset = targetOffset; renderTabsPosition(); } function activateProductTab(targetIndex) { var $items = $list.find('[data-product-item]'); var $targetItem = $items.filter('[data-product-index="' + targetIndex + '"]').first(); if ($targetItem.length === 0) { return; } syncActiveTabs(targetIndex); $list.prepend($targetItem); refreshVisibleItems(); centerTabInViewport(targetIndex); } function getActiveIndex() { return parseInt($section.find('.ourProducts-wrapper--left-full [data-product-tab].is-active').attr('data-product-tab'), 10) || 0; } function goToRelativeProduct(direction) { var currentIndex = getActiveIndex(); var totalTabs = getOriginalTabButtons().length; var nextIndex = (currentIndex + direction + totalTabs) % totalTabs; activateProductTab(nextIndex); } function stepContinuousTabs() { if (!isPaused && originalTabsWidth > 0) { currentOffset += autoScrollSpeed; if (currentOffset >= originalTabsWidth) { currentOffset -= originalTabsWidth; } renderTabsPosition(); } } function startContinuousTabs() { if (autoScrollTimer) { window.clearInterval(autoScrollTimer); } autoScrollTimer = window.setInterval(stepContinuousTabs, 16); } $tabs.on('click', '[data-product-tab]', function () { var targetIndex = parseInt($(this).attr('data-product-tab'), 10); if (!$(this).closest('.slick-cloned').length && !isNaN(targetIndex)) { activateProductTab(targetIndex); } }); $marquee.find('[data-tabs-dir="-1"]').on('click', function (event) { event.preventDefault(); isPaused = true; goToRelativeProduct(-1); window.setTimeout(function () { isPaused = false; }, 1200); }); $marquee.find('[data-tabs-dir="1"]').on('click', function (event) { event.preventDefault(); isPaused = true; goToRelativeProduct(1); window.setTimeout(function () { isPaused = false; }, 1200); }); $loadMoreButton.on('click', function () { var totalItems = $list.find('[data-product-item]').length; visibleCount = Math.min(visibleCount + step, totalItems); refreshVisibleItems(); }); refreshVisibleItems(); updateTabsWidth(); activateProductTab(parseInt(getOriginalTabButtons().first().attr('data-product-tab'), 10) || 0); startContinuousTabs(); $(window).on('resize', function () { updateTabsWidth(); }); }); } $(".simpleImageSlider").slick({ autoplay: true, autoplaySpeed: 2500, infinite: true, speed: 500, dots: false, arrows: false, fade: true, pauseOnHover: true, cssEase: 'linear' }); /* client tabs */ $('.client-tabs-body .client-tabs-content:first-child').fadeIn(); $('.client-tabs-col:first-child button').addClass('active'); $('.client-tabs-col button').click(function () { $('.client-tabs-col button').removeClass('active'); $(this).addClass('active'); let match1 = $('.client-tabs-col button.active').attr('data-tab'); $('.client-tabs-content').removeClass('active').hide(); $(`.client-tabs-content[data-content="${match1}"]`).fadeIn(); }); /* sticky sidebar top space */ $('.connect-block.stick').css('top', $stickyHeaderHeight + 10); /* sub-categoty-detail slider */ if ($('.catDetailThumb').length > 0) { var thumbnailSlider = new Swiper(".catDetailThumb", { loop: true, freeMode: true, watchSlidesProgress: true, navigation: { nextEl: ".swiper-button-next", prevEl: ".swiper-button-prev", }, breakpoints: { '0': { slidesPerView: 3, spaceBetween: 10, }, '480': { slidesPerView: 4, spaceBetween: 15, }, '768': { slidesPerView: 5, spaceBetween: 20, }, '992': { slidesPerView: 4, spaceBetween: 25, }, '1200': { slidesPerView: 5, spaceBetween: 25, }, '1500': { slidesPerView: 6, spaceBetween: 30, }, }, }); var catDetailBig = new Swiper(".catDetailBig", { loop: true, spaceBetween: 30, autoplay: { delay: 5000, disableOnInteraction: false }, navigation: { nextEl: ".swiper-button-next", prevEl: ".swiper-button-prev", }, thumbs: { swiper: thumbnailSlider, }, }); }; /* blog-content-height */ ourBlogsBox = $('.ourBlogs-box').outerHeight(); ourBlogsHead = $('.ourBlogs-head').outerHeight(); //$('.ourBlogs-desc').css('height', ourBlogsBox - ourBlogsHead - 57); lineclamp(); blogDetailTitle = $('.blog-detail-title').outerHeight(); $('.blog-detail-connect-block').css('margin-top', blogDetailTitle + 14); // Initialize main carousel $('.owl-carousel-main').owlCarousel({ items: 1, loop: true, margin: 10, nav: true, dots: true, autoplay: true, autoplayTimeout: 5000, autoplayHoverPause: true, animateOut: 'fadeOut', animateIn: 'fadeIn', }); // Initialize content carousel $('.owl-carousel-content').owlCarousel({ items: 1, loop: true, margin: 10, nav: false, dots: false, mouseDrag: false, touchDrag: false, pullDrag: false, animateOut: 'fadeOut', animateIn: 'fadeIn', }); // Sync the carousels $('.owl-carousel-main').on('changed.owl.carousel', function (event) { $('.owl-carousel-content').trigger('to.owl.carousel', [event.item.index, 300, true]); }); }); /* Script on load ------------------------------------------------------------------------------*/ $(window).on('load', function () { }); /* Script on scroll ------------------------------------------------------------------------------*/ $(window).on('scroll', function () { }); /* Script on resize ------------------------------------------------------------------------------*/ $(window).on('resize', function () { setOwnCarousalPosition(); lineclamp(); }); /* Script all functions ------------------------------------------------------------------------------*/ function setOwnCarousalPosition() { var leftSideOffset = $(".heading").offset().left; $(".ourProcess-wrapper").css("padding-left", (leftSideOffset - 16) + "px"); } function lineclamp() { // var lineheight = parseFloat($('.ourBlogs-desc p').css('line-height')); // var calc = parseInt(ourBlogsBox / lineheight); // $(".ourBlogs-desc").css({ "-webkit-line-clamp": "" + calc + "" }); } function submitContact(form) { // clearFormErrors(); // Get form elements const name = form.querySelector('input[name="name"]'); const email = form.querySelector('input[name="email"]'); const phone = form.querySelector('input[name="phone"]'); const country = form.querySelector('select[name="country"]'); const message = form.querySelector('textarea[name="message"]'); // Validation rules let isValid = true; let errors = []; // Name validation if (!name.value.trim()) { showError(name, 'Name is required'); isValid = false; } else if (name.value.length < 2) { showError(name, 'Name must be at least 2 characters'); isValid = false; } // Email validation if (email.value) { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!emailRegex.test(email.value)) { showError(email, 'Please enter a valid email address'); isValid = false; } } // Phone validation if (phone.value) { const phoneRegex = /^[0-9+\-\s()]{8,20}$/; if (!phoneRegex.test(phone.value)) { showError(phone, 'Please enter a valid phone number'); isValid = false; } } // Either email or phone is required if (!email.value && !phone.value) { showError(email, 'Either email or phone is required'); showError(phone, 'Either email or phone is required'); isValid = false; } // Country validation if (!country.value) { showError(country, 'Please select a country'); isValid = false; } // Message validation if (!message.value.trim()) { showError(message, 'Message is required'); isValid = false; } if (isValid) { // Wait until reCAPTCHA is loaded if (typeof grecaptcha === 'undefined' || !window.recaptchaLoaded) { alert('Captcha is still loading. Please wait a moment and try again.'); return; } grecaptcha.ready(function() { grecaptcha.execute(window.RECAPTCHA_SITEKEY, {action: 'submit'}).then(function(token) { form.querySelector('input[name="g-recaptcha-response"]').value = token; const formData = new FormData(form); const submitBtn = form.querySelector('button[type="button"]'); const originalBtnText = submitBtn.innerHTML; submitBtn.innerHTML = 'Sending...'; submitBtn.disabled = true; fetch('/api/admin/send-contact', { method: 'POST', headers: { 'X-CSRF-TOKEN': document.querySelector('input[name="_token"]').value }, body: formData }) .then(async response => { const text = await response.text(); console.log('Raw response:', text); let data; try { data = JSON.parse(text); } catch (err) { console.error('JSON parse error:', err); throw new Error('Invalid JSON response from server'); } if (data.success) { // Check if this was a download form submission var pendingFile = $('#downloadContactModal').data('file'); var pendingTitle = $('#downloadContactModal').data('title') || 'download'; if ($('#downloadContactModal').hasClass('show') && pendingFile) { // Trigger download instead of redirect var a = document.createElement('a'); a.href = pendingFile; a.download = pendingTitle + '.pdf'; a.target = '_blank'; document.body.appendChild(a); a.click(); document.body.removeChild(a); $('#downloadContactModal').modal('hide'); } else { // Normal form — redirect as usual window.location.href = data.redirect_url; } } else { alert(data.message || "An error occurred. Please try again."); } }) .catch(error => { console.error('Fetch error:', error); alert('Failed to submit the form. Please try again.'); }); }); }); } } function submitContactpage(form) { // clearFormErrors(); // Get form elements const companyName = form.querySelector('input[name="company_name"]'); const name = form.querySelector('input[name="name"]'); const email = form.querySelector('input[name="email"]'); const phone = form.querySelector('input[name="phone"]'); const country = form.querySelector('select[name="country"]'); const deliveryLocation = form.querySelector('select[name="delivery_location"]'); const type = form.querySelector('select[name="type"]'); const expectedDeliveryDate = form.querySelector('input[name="expected_delivery_date"]'); const message = form.querySelector('textarea[name="message"]'); // Validation rules let isValid = true; let errors = []; // Name validation if (!name.value.trim()) { showError(name, 'Name is required'); isValid = false; } else if (name.value.length < 2) { showError(name, 'Name must be at least 2 characters'); isValid = false; } // Email validation if (email.value) { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!emailRegex.test(email.value)) { showError(email, 'Please enter a valid email address'); isValid = false; } } // Phone validation if (phone.value) { const phoneRegex = /^[0-9+\-\s()]{8,20}$/; if (!phoneRegex.test(phone.value)) { showError(phone, 'Please enter a valid phone number'); isValid = false; } } // Either email or phone is required if (!email.value && !phone.value) { showError(email, 'Either email or phone is required'); showError(phone, 'Either email or phone is required'); isValid = false; } // Country validation if (!country.value) { showError(country, 'Please select a country'); isValid = false; } // Message validation if (!message.value.trim()) { showError(message, 'Message is required'); isValid = false; } if (isValid) { // Wait until reCAPTCHA is loaded if (typeof grecaptcha === 'undefined' || !window.recaptchaLoaded) { alert('Captcha is still loading. Please wait a moment and try again.'); return; } grecaptcha.ready(function() { grecaptcha.execute(window.RECAPTCHA_SITEKEY, {action: 'submit'}).then(function(token) { form.querySelector('input[name="g-recaptcha-response"]').value = token; const formData = new FormData(form); const submitBtn = form.querySelector('button[type="button"]'); const originalBtnText = submitBtn.innerHTML; submitBtn.innerHTML = 'Sending...'; submitBtn.disabled = true; fetch('/api/admin/send-contactpage', { method: 'POST', headers: { 'X-CSRF-TOKEN': document.querySelector('input[name="_token"]').value }, body: formData }) .then(async response => { const text = await response.text(); console.log('Raw response:', text); let data; try { data = JSON.parse(text); } catch (err) { console.error('JSON parse error:', err); throw new Error('Invalid JSON response from server'); } if (data.success) { // Redirect immediately window.location.href = data.redirect_url; } else { alert(data.message || "An error occurred. Please try again."); } }) .catch(error => { console.error('Fetch error:', error); alert('Failed to submit the form. Please try again.'); }); }); }); } } function showError(element, message) { // Remove any existing error clearError(element); // Add error class to input element.classList.add('is-invalid'); // Create and append error message const errorDiv = document.createElement('div'); errorDiv.className = 'invalid-feedback'; errorDiv.textContent = message; element.parentNode.appendChild(errorDiv); } function clearError(element) { element.classList.remove('is-invalid'); const errorDiv = element.parentNode.querySelector('.invalid-feedback'); if (errorDiv) { errorDiv.remove(); } } function showSuccessMessage(message) { iziToast.success({ title: 'Success', message: message, position: 'topRight' }); } function showErrorMessage(message) { iziToast.error({ title: 'Error', message: message, position: 'topRight' }); } $(document).ready(function () { // Disable hash navigation globally for Fancybox Fancybox.defaults.Hash = false; // Bind Fancybox with custom options Fancybox.bind("[data-fancybox='gallery']", { // Disable hash-based navigation Hash: false, // Hook into the afterShow event to update the URL on: { done: (fancybox, slide) => { // Generate the custom URL format let imageSlug = slide.$trigger.dataset.slug || "gallery"; let cleanUrl = window.location.origin + window.location.pathname + '/' + imageSlug.replace(/\s+/g, '-').toLowerCase(); window.history.pushState(null, null, cleanUrl); }, closing: (fancybox, slide) => { // Revert the URL when the Fancybox is closed window.history.pushState(null, null, window.location.pathname); } } }); }); $(document).ready(function () { $(document).on('click', '.download-btn', function (e) { e.preventDefault(); var fileUrl = $(this).data('file'); var title = $(this).data('title') || 'download'; $('#downloadContactModal').data('file', fileUrl); $('#downloadContactModal').data('title', title); $('#downloadContactModal').modal('show'); }); });