Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- document.addEventListener("DOMContentLoaded", function () {
- const nav = document.getElementById("main-navbar");
- if (!nav) return;
- const threshold = 40;
- const hideOffset = 120;
- const delta = 6;
- let lastY = window.scrollY;
- let ticking = false;
- const isMenuOpen = () => {
- const collapse = nav.querySelector(".navbar-collapse");
- return collapse && collapse.classList.contains("show");
- };
- const onScroll = () => {
- const y = window.scrollY;
- if (y > threshold) nav.classList.add("scrolled");
- else nav.classList.remove("scrolled");
- if (y <= 5) nav.classList.add("at-top");
- else nav.classList.remove("at-top");
- if (isMenuOpen()) {
- nav.classList.add("menu-open");
- nav.classList.remove("nav-hidden");
- lastY = y;
- return;
- } else {
- nav.classList.remove("menu-open");
- }
- const diff = y - lastY;
- if (Math.abs(diff) > delta) {
- if (diff > 0 && y > hideOffset) nav.classList.add("nav-hidden");
- else nav.classList.remove("nav-hidden");
- lastY = y;
- }
- };
- const onScrollRaf = () => {
- if (ticking) return;
- ticking = true;
- requestAnimationFrame(() => {
- onScroll();
- ticking = false;
- });
- };
- onScroll();
- window.addEventListener("scroll", onScrollRaf, { passive: true });
- nav.addEventListener("shown.bs.collapse", () => {
- nav.classList.add("menu-open");
- nav.classList.remove("nav-hidden");
- });
- nav.addEventListener("hidden.bs.collapse", () => {
- nav.classList.remove("menu-open");
- });
- if (typeof bootstrap === "undefined") return;
- const DESKTOP = window.matchMedia("(min-width: 992px)");
- function bindHoverDropdowns() {
- document.querySelectorAll(".navbar .dropdown").forEach(function (dd) {
- const toggle = dd.querySelector(":scope > a.dropdown-toggle");
- const menu = dd.querySelector(":scope > .dropdown-menu");
- if (!toggle || !menu) return;
- const instance = bootstrap.Dropdown.getOrCreateInstance(toggle, { autoClose: "outside" });
- let hideTimer = null;
- const showNow = () => {
- if (!DESKTOP.matches) return;
- if (hideTimer) clearTimeout(hideTimer);
- instance.show();
- };
- const hideLater = () => {
- if (!DESKTOP.matches) return;
- if (hideTimer) clearTimeout(hideTimer);
- hideTimer = setTimeout(() => instance.hide(), 180);
- };
- dd.addEventListener("mouseenter", showNow);
- dd.addEventListener("mouseleave", hideLater);
- menu.addEventListener("mouseenter", showNow);
- menu.addEventListener("mouseleave", hideLater);
- toggle.addEventListener("click", function (e) {
- if (!DESKTOP.matches) return;
- const href = toggle.getAttribute("href");
- if (href && href !== "#") {
- e.preventDefault();
- window.location.href = href;
- } else {
- e.preventDefault();
- instance.toggle();
- }
- });
- dd.addEventListener("hide.bs.dropdown", function () {
- dd.querySelectorAll(".dropdown-menu.show").forEach(function (m) {
- m.classList.remove("show");
- });
- dd.querySelectorAll(".nht-submenu-toggle[aria-expanded='true']").forEach(function (b) {
- b.setAttribute("aria-expanded", "false");
- });
- });
- });
- }
- bindHoverDropdowns();
- document.querySelectorAll(".navbar .dropdown-submenu").forEach(function (li) {
- if (li.classList.contains("no-submenu-toggle")) return;
- const link = li.querySelector(":scope > a.dropdown-toggle");
- const sub = li.querySelector(":scope > .dropdown-menu");
- if (!link || !sub) return;
- let btn = li.querySelector(":scope > button.nht-submenu-toggle");
- if (!btn) {
- btn = document.createElement("button");
- btn.type = "button";
- btn.className = "nht-submenu-toggle";
- btn.setAttribute("aria-label", "Open submenu");
- btn.setAttribute("aria-expanded", "false");
- li.insertBefore(btn, sub);
- }
- const closeSiblings = () => {
- const parentMenu = li.closest(".dropdown-menu");
- if (!parentMenu) return;
- parentMenu.querySelectorAll(":scope > li > .dropdown-menu.show").forEach(function (openMenu) {
- if (openMenu !== sub) {
- openMenu.classList.remove("show");
- const ownerBtn = openMenu.parentElement.querySelector(":scope > button.nht-submenu-toggle");
- if (ownerBtn) ownerBtn.setAttribute("aria-expanded", "false");
- }
- });
- };
- const openSub = () => {
- closeSiblings();
- sub.classList.add("show");
- btn.setAttribute("aria-expanded", "true");
- };
- const closeSub = () => {
- sub.classList.remove("show");
- btn.setAttribute("aria-expanded", "false");
- };
- const toggleSub = () => {
- if (sub.classList.contains("show")) closeSub();
- else openSub();
- };
- btn.addEventListener("click", function (e) {
- e.preventDefault();
- e.stopPropagation();
- toggleSub();
- });
- li.addEventListener("mouseenter", function () {
- if (!DESKTOP.matches) return;
- openSub();
- });
- li.addEventListener("mouseleave", function () {
- if (!DESKTOP.matches) return;
- closeSub();
- });
- });
- document.querySelectorAll(".dropdown-menu.nht-mega").forEach(function (mega) {
- const tabs = mega.querySelectorAll(".nht-mega__tab");
- const panels = mega.querySelectorAll(".nht-mega__panel");
- if (!tabs.length || !panels.length) return;
- const activate = (key) => {
- tabs.forEach((t) => t.classList.remove("is-active"));
- panels.forEach((p) => p.classList.remove("is-active"));
- const tab = mega.querySelector('.nht-mega__tab[data-mega-tab="' + key + '"]');
- const panel = mega.querySelector('.nht-mega__panel[data-mega-panel="' + key + '"]');
- if (tab) tab.classList.add("is-active");
- if (panel) panel.classList.add("is-active");
- };
- tabs.forEach(function (tab) {
- const key = tab.getAttribute("data-mega-tab");
- tab.addEventListener("mouseenter", function () {
- if (!DESKTOP.matches) return;
- if (mega.querySelector('.nht-mega__panel[data-mega-panel="' + key + '"]')) activate(key);
- });
- tab.addEventListener("click", function (e) {
- e.preventDefault();
- e.stopPropagation();
- if (mega.querySelector('.nht-mega__panel[data-mega-panel="' + key + '"]')) activate(key);
- });
- });
- });
- const root = document.querySelector(".pkg-page");
- if (!root) return;
- const postId = root.getAttribute("data-post-id");
- const msg = document.getElementById("pkgActionMsg");
- const showMsg = (t) => {
- if (!msg) return;
- msg.textContent = t;
- window.clearTimeout(showMsg._t);
- showMsg._t = window.setTimeout(() => (msg.textContent = ""), 2400);
- };
- const shareBtn = document.getElementById("pkgShareBtn");
- const url = window.location.href;
- if (shareBtn) {
- shareBtn.addEventListener("click", async () => {
- try {
- if (navigator.share) {
- await navigator.share({ title: document.title, url });
- showMsg("Shared successfully.");
- return;
- }
- await navigator.clipboard.writeText(url);
- showMsg("Link copied to clipboard.");
- } catch (e) {
- try {
- await navigator.clipboard.writeText(url);
- showMsg("Link copied to clipboard.");
- } catch (err) {
- showMsg("Unable to share. Please copy the URL manually.");
- }
- }
- });
- }
- const wishBtn = document.getElementById("pkgWishlistBtn");
- const storageKey = "pkg_wishlist_ids";
- const getList = () => {
- try {
- return JSON.parse(localStorage.getItem(storageKey) || "[]");
- } catch (e) {
- return [];
- }
- };
- const setList = (arr) => localStorage.setItem(storageKey, JSON.stringify(arr));
- const setWishUI = (active) => {
- if (!wishBtn) return;
- wishBtn.classList.toggle("is-active", active);
- wishBtn.setAttribute("aria-pressed", active ? "true" : "false");
- const icon = wishBtn.querySelector("i");
- if (icon) {
- icon.classList.toggle("fa-regular", !active);
- icon.classList.toggle("fa-solid", active);
- icon.classList.toggle("fa-heart", true);
- }
- showMsg(active ? "Added to wishlist." : "Removed from wishlist.");
- };
- if (wishBtn && postId) {
- const list = getList();
- setWishUI(list.includes(postId));
- wishBtn.addEventListener("click", () => {
- const listNow = getList();
- const idx = listNow.indexOf(postId);
- if (idx >= 0) listNow.splice(idx, 1);
- else listNow.push(postId);
- setList(listNow);
- setWishUI(listNow.includes(postId));
- });
- }
- const items = Array.from(document.querySelectorAll(".pkg-gallery-item"));
- const modalEl = document.getElementById("pkgGalleryModal");
- const imgEl = document.getElementById("pkgGalleryImg");
- const prevBtn = document.getElementById("pkgPrevImg");
- const nextBtn = document.getElementById("pkgNextImg");
- let index = 0;
- let modal = null;
- const openAt = (i) => {
- if (!items.length || !modalEl || !imgEl) return;
- index = i;
- const full = items[index].dataset.full || "";
- const alt = items[index].dataset.alt || "";
- imgEl.src = full;
- imgEl.alt = alt;
- if (!modal) modal = new bootstrap.Modal(modalEl);
- modal.show();
- };
- items.forEach((a, i) => {
- a.addEventListener("click", (e) => {
- e.preventDefault();
- openAt(i);
- });
- });
- if (prevBtn) prevBtn.addEventListener("click", () => openAt((index - 1 + items.length) % items.length));
- if (nextBtn) nextBtn.addEventListener("click", () => openAt((index + 1) % items.length));
- document.querySelectorAll(".price-counter").forEach((counter) => {
- const updateCount = () => {
- const target = Number(counter.getAttribute("data-target")) || 0;
- const count = Number(counter.innerText) || 0;
- const increment = target / 100;
- if (count < target) {
- counter.innerText = String(Math.ceil(count + increment));
- setTimeout(updateCount, 20);
- } else {
- counter.innerText = String(target);
- }
- };
- updateCount();
- });
- document.querySelectorAll(".counter-number").forEach((counter) => {
- const updateCounter = () => {
- const target = Number(counter.getAttribute("data-target")) || 0;
- const count = Number(counter.innerText) || 0;
- const increment = target / 200;
- if (count < target) {
- counter.innerText = String(Math.ceil(count + increment));
- setTimeout(updateCounter, 15);
- } else {
- counter.innerText = String(target);
- }
- };
- updateCounter();
- });
- const featureButtons = document.querySelectorAll("#activities .btn");
- const featureCards = document.querySelectorAll("#activities .activity-card");
- if (featureButtons.length && featureCards.length) {
- featureButtons.forEach((btn) => {
- btn.addEventListener("click", () => {
- featureButtons.forEach((b) => b.classList.remove("active"));
- btn.classList.add("active");
- const target = btn.getAttribute("data-target");
- featureCards.forEach((card) => {
- if (target === "all") card.style.display = "block";
- else card.style.display = card.classList.contains(target) ? "block" : "none";
- });
- });
- });
- }
- const featureFeatureButtons = document.querySelectorAll("#activities-feature .btn");
- const featureFeatureCards = document.querySelectorAll("#activities-feature .activity-card");
- const btnRow = document.querySelector("#activities-feature .filter-row");
- if (featureFeatureButtons.length && featureFeatureCards.length && btnRow) {
- featureFeatureButtons.forEach((btn) => {
- btn.addEventListener("click", () => {
- if (btn.dataset.dragged === "true") {
- btn.dataset.dragged = "false";
- return;
- }
- featureFeatureButtons.forEach((b) => b.classList.remove("active"));
- btn.classList.add("active");
- const target = btn.getAttribute("data-target");
- featureFeatureCards.forEach((card) => {
- if (target === "all") card.style.display = "block";
- else card.style.display = card.classList.contains(target) ? "block" : "none";
- });
- });
- });
- let isDraggingBtn = false;
- let startXBtn = 0;
- let scrollStartBtn = 0;
- btnRow.addEventListener("pointerdown", (e) => {
- isDraggingBtn = true;
- startXBtn = e.clientX;
- scrollStartBtn = btnRow.scrollLeft;
- btnRow.setPointerCapture?.(e.pointerId);
- });
- btnRow.addEventListener("pointermove", (e) => {
- if (!isDraggingBtn) return;
- const walk = e.clientX - startXBtn;
- if (Math.abs(walk) > 5) {
- btnRow.scrollLeft = scrollStartBtn - walk * 2;
- featureFeatureButtons.forEach((b) => (b.dataset.dragged = "true"));
- }
- });
- const stopBtnDrag = () => (isDraggingBtn = false);
- btnRow.addEventListener("pointerup", stopBtnDrag);
- btnRow.addEventListener("pointercancel", stopBtnDrag);
- btnRow.addEventListener("pointerleave", stopBtnDrag);
- }
- const slider = document.getElementById("activities-slider");
- if (slider) {
- let isDown = false;
- let startX = 0;
- let scrollLeft = 0;
- slider.addEventListener("mousedown", (e) => {
- isDown = true;
- slider.classList.add("active");
- startX = e.pageX - slider.offsetLeft;
- scrollLeft = slider.scrollLeft;
- });
- ["mouseleave", "mouseup"].forEach((evt) => {
- slider.addEventListener(evt, () => {
- isDown = false;
- slider.classList.remove("active");
- });
- });
- slider.addEventListener("mousemove", (e) => {
- if (!isDown) return;
- e.preventDefault();
- const x = e.pageX - slider.offsetLeft;
- const walk = (x - startX) * 2;
- slider.scrollLeft = scrollLeft - walk;
- });
- }
- const scrollElements = document.querySelectorAll(
- "small, h1, h2, h3, h4, h5, h6, p, a, .search-form, .gallery-img-other, .gallery-img-center, .service-card, .feature-card, .right-content img, #activities-images img, .blog-card, #testimonial-section img"
- );
- scrollElements.forEach((el) => {
- el.classList.add("animate-on-scroll");
- if (
- el.classList.contains("search-form") ||
- el.classList.contains("gallery-img-other") ||
- el.classList.contains("gallery-img-center") ||
- el.classList.contains("service-card") ||
- el.classList.contains("feature-card") ||
- el.classList.contains("blog-card") ||
- el.closest(".right-content") ||
- el.closest("#activities-images") ||
- el.closest("#testimonial-section")
- ) {
- el.classList.add("zoom-on-scroll");
- }
- if (el.tagName === "SMALL") el.classList.add("fade-in");
- if (/^H[1-6]$/.test(el.tagName)) el.classList.add("slide-up");
- if (el.tagName === "P") el.classList.add("fade-in-up");
- if (el.tagName === "A") el.classList.add("fade-in-link");
- });
- if (scrollElements.length) {
- const observer = new IntersectionObserver(
- (entries) => {
- entries.forEach((entry) => {
- if (entry.isIntersecting) entry.target.classList.add("in-view");
- else entry.target.classList.remove("in-view");
- });
- },
- { threshold: 0.1 }
- );
- scrollElements.forEach((el) => observer.observe(el));
- }
- const carousel = document.getElementById("testimonial-carousel");
- if (carousel) {
- let offset = 0;
- const firstCard = carousel.querySelector(".col-md-4");
- if (firstCard) {
- const cardWidth = firstCard.offsetWidth + 16;
- let interval;
- let isPaused = false;
- function slideCarousel() {
- offset -= cardWidth;
- carousel.style.transform = `translateX(${offset}px)`;
- setTimeout(() => {
- carousel.appendChild(carousel.firstElementChild);
- offset += cardWidth;
- carousel.style.transition = "none";
- carousel.style.transform = `translateX(${offset}px)`;
- carousel.offsetHeight;
- carousel.style.transition = "transform 0.6s ease-in-out";
- }, 600);
- }
- function startCarousel() {
- interval = setInterval(slideCarousel, 3000);
- }
- function stopCarousel() {
- clearInterval(interval);
- }
- startCarousel();
- carousel.addEventListener("click", () => {
- if (isPaused) return;
- stopCarousel();
- isPaused = true;
- setTimeout(() => {
- startCarousel();
- isPaused = false;
- }, 5000);
- });
- }
- }
- document.querySelectorAll(".faq-item").forEach((item) => {
- const toggle = item.querySelector(".faq-toggle");
- const title = item.querySelector(".faq-title") || item.querySelector(".faq-question");
- if (!title || !toggle) return;
- title.addEventListener("click", () => {
- item.classList.toggle("active");
- toggle.textContent = item.classList.contains("active") ? "–" : "+";
- });
- });
- const cardsWrapper = document.getElementById("left-cards-wrapper");
- if (cardsWrapper) {
- const allCards = Array.from(cardsWrapper.getElementsByClassName("blog-card"));
- const cardsPerPage = 5;
- const totalPages = Math.ceil(allCards.length / cardsPerPage);
- const paginationWrapper = document.getElementById("blog-pagination");
- if (paginationWrapper && totalPages > 1) {
- paginationWrapper.innerHTML = "";
- for (let i = 1; i <= totalPages; i++) {
- const li = document.createElement("li");
- li.className = "page-item";
- li.innerHTML = `<a class="page-link" href="#" data-page="${i}">${i}</a>`;
- paginationWrapper.appendChild(li);
- }
- const showPage = (page) => {
- allCards.forEach((card, idx) => {
- const start = (page - 1) * cardsPerPage;
- const end = page * cardsPerPage;
- if (idx >= start && idx < end) card.classList.add("active");
- else card.classList.remove("active");
- });
- };
- showPage(1);
- paginationWrapper.querySelectorAll(".page-link").forEach((link) => {
- link.addEventListener("click", (e) => {
- e.preventDefault();
- showPage(parseInt(link.dataset.page, 10));
- });
- });
- } else {
- allCards.forEach((card) => card.classList.add("active"));
- }
- }
- });
- /* ====================================================================
- TOP CONTACT BAR
- ==================================================================== */
- document.addEventListener("DOMContentLoaded", function() {
- const dropdown = document.getElementById("nhtCountryDropdown");
- const phoneLink = document.getElementById("phoneLink");
- if (!dropdown) return;
- dropdown.addEventListener("click", function(e) {
- e.stopPropagation();
- this.classList.toggle("is-active");
- });
- document.addEventListener("click", function() {
- dropdown.classList.remove("is-active");
- });
- const options = dropdown.querySelectorAll(".nht-option");
- options.forEach(option => {
- option.addEventListener("click", function() {
- const country = this.getAttribute("data-country");
- const phone = this.getAttribute("data-phone");
- const flag = this.querySelector("img").src;
- dropdown.querySelector(".nht-selected-name").textContent = country;
- dropdown.querySelector(".nht-current-flag").src = flag;
- if (phoneLink) {
- phoneLink.textContent = phone;
- phoneLink.href = "tel:" + phone.replace(/\s+/g, "");
- }
- });
- });
- });
- jQuery(document).ready(function($) {
- $('.pkg-enquiry-form').on('submit', function(e) {
- e.preventDefault();
- var $form = $(this);
- var $btn = $form.find('button[type="submit"]');
- var $alert = $form.find('.alert');
- $alert?.remove();
- $btn.prop('disabled', true).text('Sending...');
- // Prepare AJAX data
- var data = {
- action: 'pkg_enquiry',
- pkg_enquiry_nonce: nht_ajax_obj.enquiry_nonce,
- name: $form.find('input[name="name"]').val(),
- email: $form.find('input[name="email"]').val(),
- phone: $form.find('input[name="phone"]').val(),
- country: $form.find('input[name="country"]').val(),
- message: $form.find('textarea[name="message"]').val(),
- package_id: $form.find('input[name="package_id"]').val(),
- package_title: $form.find('input[name="package_title"]').val()
- };
- // Send AJAX request
- $.ajax({
- url: nht_ajax_obj.ajax_url,
- method: 'POST',
- data: data,
- dataType: 'json',
- success: function(response) {
- console.log('AJAX response:', response);
- if (response.success) {
- $form.prepend('<div class="alert alert-success small">'+response.data.message+'</div>');
- $form[0].reset();
- } else {
- $form.prepend('<div class="alert alert-danger small">'+response.data.message+'</div>');
- }
- },
- error: function(xhr, status, error) {
- console.error('AJAX error:', status, error, xhr.responseText);
- $form.prepend('<div class="alert alert-danger small">Something went wrong. Try again.</div>');
- },
- complete: function() {
- $btn.prop('disabled', false).text('Send enquiry');
- }
- });
- });
- });
- jQuery(document).ready(function ($) {
- /* =====================================================
- * FRONTEND BOOKING FORM SUBMISSION
- ====================================================== */
- $('#nhtBookingForm').on('submit', function (e) {
- e.preventDefault();
- var form = $(this);
- var submitBtn = form.find('button[type="submit"]');
- var messageDiv = $('#booking-message');
- // --- FRONTEND VALIDATION ---
- var travelDate = form.find('input[name="travel_date"]').val();
- var pax = parseInt(form.find('input[name="pax"]').val(), 10);
- var name = form.find('input[name="name"]').val().trim();
- var email = form.find('input[name="email"]').val().trim();
- var phone = form.find('input[name="phone"]').val().trim();
- if (!name || !email || !phone || !travelDate || pax < 1) {
- messageDiv.html('<div class="alert alert-danger">Please fill all required fields correctly.</div>');
- return;
- }
- var today = new Date();
- today.setHours(0,0,0,0);
- var selectedDate = new Date(travelDate);
- if (selectedDate < today) {
- messageDiv.html('<div class="alert alert-danger">Travel date cannot be in the past.</div>');
- return;
- }
- // --- END FRONTEND VALIDATION ---
- var formData = form.serialize(); // keep the original ajax logic
- submitBtn.prop('disabled', true).text('Processing...');
- $.ajax({
- url: nht_ajax_obj.ajax_url,
- type: 'POST',
- data: formData,
- dataType: 'json',
- success: function (response) {
- if (response.success) {
- messageDiv.html('<div class="alert alert-success">' + response.data.message + '</div>');
- form[0].reset();
- // Optional: Close modal after 2 seconds
- setTimeout(function() {
- $('#pkgBookTripModal').modal('hide');
- messageDiv.html('');
- }, 2000);
- } else {
- messageDiv.html('<div class="alert alert-danger">' + response.data + '</div>');
- }
- },
- error: function () {
- messageDiv.html('<div class="alert alert-danger">Something went wrong. Please try again.</div>');
- },
- complete: function () {
- submitBtn.prop('disabled', false).text('Confirm Booking');
- }
- });
- });
- /* =====================================================
- * ADMIN BOOKING STATUS UPDATE
- ====================================================== */
- $('.nht-booking-action').on('click', function () {
- var btn = $(this);
- var post_id = btn.data('id');
- var status = btn.data('status');
- btn.prop('disabled', true).text('Updating...');
- $.ajax({
- url: nht_ajax_obj.ajax_url,
- type: 'POST',
- data: {
- action: 'nht_update_booking_status',
- nonce: nht_ajax_obj.nonce,
- post_id: post_id,
- status: status
- },
- dataType: 'json',
- success: function (response) {
- if (response.success) {
- var statusSpan = btn.closest('tr').find('.nht-status-pill');
- statusSpan.text(response.data.status);
- var colors = {
- 'Pending': '#e67e22',
- 'Approved': '#27ae60',
- 'Rejected': '#c0392b'
- };
- statusSpan.css('background', colors[response.data.status] || '#7f8c8d');
- btn.remove();
- } else {
- alert(response.data || 'Failed to update status.');
- btn.prop('disabled', false).text(btn.data('status').charAt(0).toUpperCase() + btn.data('status').slice(1));
- }
- },
- error: function () {
- alert('Something went wrong. Please try again.');
- btn.prop('disabled', false).text(btn.data('status').charAt(0).toUpperCase() + btn.data('status').slice(1));
- }
- });
- });
- });
Advertisement
Add Comment
Please, Sign In to add comment