'use strict'; // element toggle function const elementToggleFunc = function (elem) { elem.classList.toggle("active"); } // sidebar variables const sidebar = document.querySelector("[data-sidebar]"); const sidebarBtn = document.querySelector("[data-sidebar-btn]"); // sidebar toggle functionality for mobile sidebarBtn.addEventListener("click", function () { elementToggleFunc(sidebar); }); // testimonials variables const testimonialsItem = document.querySelectorAll("[data-testimonials-item]"); const modalContainer = document.querySelector("[data-modal-container]"); const modalCloseBtn = document.querySelector("[data-modal-close-btn]"); const overlay = document.querySelector("[data-overlay]"); // modal variable const modalImg = document.querySelector("[data-modal-img]"); const modalTitle = document.querySelector("[data-modal-title]"); const modalText = document.querySelector("[data-modal-text]"); // modal toggle function const testimonialsModalFunc = function () { modalContainer.classList.toggle("active"); overlay.classList.toggle("active"); } // add click event to all modal items for (let i = 0; i < testimonialsItem.length; i++) { testimonialsItem[i].addEventListener("click", function () { modalImg.src = this.querySelector("[data-testimonials-avatar]").src; modalImg.alt = this.querySelector("[data-testimonials-avatar]").alt; modalTitle.innerHTML = this.querySelector("[data-testimonials-title]").innerHTML; modalText.innerHTML = this.querySelector("[data-testimonials-text]").innerHTML; testimonialsModalFunc(); }); } // add click event to modal close button modalCloseBtn.addEventListener("click", testimonialsModalFunc); overlay.addEventListener("click", testimonialsModalFunc); // custom select variables const select = document.querySelector("[data-select]"); const selectItems = document.querySelectorAll("[data-select-item]"); const selectValue = document.querySelector("[data-selecct-value]"); const filterBtn = document.querySelectorAll("[data-filter-btn]"); select.addEventListener("click", function () { elementToggleFunc(this); }); // add event in all select items for (let i = 0; i < selectItems.length; i++) { selectItems[i].addEventListener("click", function () { let selectedValue = this.innerText.toLowerCase(); selectValue.innerText = this.innerText; elementToggleFunc(select); filterFunc(selectedValue); }); } // filter variables const filterItems = document.querySelectorAll("[data-filter-item]"); const filterFunc = function (selectedValue) { for (let i = 0; i < filterItems.length; i++) { if (selectedValue === "all") { filterItems[i].classList.add("active"); } else if (selectedValue === filterItems[i].dataset.category) { filterItems[i].classList.add("active"); } else { filterItems[i].classList.remove("active"); } } } // add event in all filter button items for large screen let lastClickedBtn = filterBtn[0]; for (let i = 0; i < filterBtn.length; i++) { filterBtn[i].addEventListener("click", function () { let selectedValue = this.innerText.toLowerCase(); selectValue.innerText = this.innerText; filterFunc(selectedValue); lastClickedBtn.classList.remove("active"); this.classList.add("active"); lastClickedBtn = this; }); } // contact form variables const form = document.querySelector("[data-form]"); const formInputs = document.querySelectorAll("[data-form-input]"); const formBtn = document.querySelector("[data-form-btn]"); // add event to all form input field for (let i = 0; i < formInputs.length; i++) { formInputs[i].addEventListener("input", function () { // check form validation if (form.checkValidity()) { formBtn.removeAttribute("disabled"); } else { formBtn.setAttribute("disabled", ""); } }); } // page navigation variables const navigationLinks = document.querySelectorAll("[data-nav-link]"); const pages = document.querySelectorAll("[data-page]"); // add event to all nav link for (let i = 0; i < navigationLinks.length; i++) { navigationLinks[i].addEventListener("click", function () { for (let i = 0; i < pages.length; i++) { if (this.innerHTML.toLowerCase() === pages[i].dataset.page) { pages[i].classList.add("active"); navigationLinks[i].classList.add("active"); window.scrollTo(0, 0); } else { pages[i].classList.remove("active"); navigationLinks[i].classList.remove("active"); } } }); } // add event to all toExp link const toExpLinks = document.querySelectorAll("[data-toExp-link]"); for (let i = 0; i < toExpLinks.length; i++) { toExpLinks[i].addEventListener("click", function () { for (let i = 0; i < pages.length; i++) { if (pages[i].dataset.page === "experience") { pages[i].classList.add("active"); toExpLinks[i].classList.add("active"); window.scrollTo(0, 0); navigationLinks[i].classList.add("active"); } else { pages[i].classList.remove("active"); toExpLinks[i].classList.remove("active"); navigationLinks[i].classList.remove("active"); } } }); } // blog navigation variables const blogLinks = document.querySelectorAll("[data-blog-link]"); const blogs = document.querySelectorAll("[data-blog]"); // add event to all blog links for (let i = 0; i < blogLinks.length; i++) { blogLinks[i].addEventListener("click", function () { for (let i = 0; i < blogs.length; i++) { if (this.children[1].children[1].innerHTML.toLowerCase() === blogs[i].dataset.blog.toLowerCase()) { blogs[i].classList.add("active"); blogLinks[i].classList.add("active"); window.scrollTo(0, 0); // update URL hash to allow shareable link (slugified) try { const t = this.children[1].children[1].innerHTML; const slug = t.toLowerCase() .replace(/[^a-z0-9\s]/g, '') // remove special chars .replace(/\s+/g, '-') // spaces to hyphens .replace(/-+/g, '-') // multiple hyphens to single .replace(/^-|-$/g, ''); // trim leading/trailing hyphens window.location.hash = 'blog=' + slug; } catch(e) {} pages[4].classList.remove("active"); //navigationLinks[4].classList.remove("active"); for (let j = 0; j < navigationLinks.length; j++) { navigationLinks[j].addEventListener("click", function () { blogs[i].classList.remove("active"); }) } } else { blogs[i].classList.remove("active"); blogLinks[i].classList.remove("active"); } } }); } var btn = document.getElementById('buttonUp') btn.addEventListener('click', function() { window.scroll({ top: 0, left: 0, behavior: 'smooth' }); }); // window.scrollY // this.window.scroll(function() { // if (this.window.scrollTop() > 300) { // btn.addClass('show'); // } else { // btn.removeClass('show'); // } // }); // btn.addEventListener('click', function(e) { // e.preventDefault(); // $('html, body').animate({scrollTop:0}, '300'); // }); // Allow opening a specific blog via hash: #blog=Title function openBlogFromHash(){ if (!window.location.hash) return; const m = window.location.hash.match(/^#blog=(.*)$/); if (!m) return; const slug = m[1] || ''; for (let i = 0; i < blogs.length; i++) { // create slug from data-blog for comparison const blogSlug = blogs[i].dataset.blog ? blogs[i].dataset.blog.toLowerCase() .replace(/[^a-z0-9\s]/g, '') .replace(/\s+/g, '-') .replace(/-+/g, '-') .replace(/^-|-$/g, '') : ''; if (blogSlug === slug) { // hide all main pages for (let p = 0; p < pages.length; p++) { pages[p].classList.remove('active'); } // show blog article blogs[i].classList.add('active'); // set navbar state to Blog if (navigationLinks && navigationLinks.length) { for (let n = 0; n < navigationLinks.length; n++) { navigationLinks[n].classList.remove('active'); } if (navigationLinks[4]) navigationLinks[4].classList.add('active'); } window.scrollTo(0,0); break; } } } // Clear hash when navigating to other sections for (let i = 0; i < navigationLinks.length; i++) { navigationLinks[i].addEventListener('click', function(){ if (window.location.hash) history.replaceState(null, '', window.location.pathname); // Clear blogs view when navigating to other sections for (let i = 0; i < blogs.length; i++) { blogs[i].classList.remove("active"); blogLinks[i].classList.remove("active"); } }); } window.addEventListener('load', openBlogFromHash); window.addEventListener('hashchange', openBlogFromHash); //Expand Image // Get the main elements once var modal = document.getElementById("imageModal"); var modalImgExpand = document.getElementById("modalImage"); // Get ALL images that should be expandable (using the class name) var expandableImages = document.querySelectorAll(".expandable-image"); // Function to open the modal function openModal(clickedImage) { // Set the modal's display to 'flex' to make it visible and centered modal.style.display = "flex"; // Get the source (src) of the image that was clicked and set it to the modal image modalImgExpand.src = clickedImage.src; // Optional: Copy the 'alt' text as well for accessibility modalImgExpand.alt = clickedImage.alt; } // Function to close the modal function closeModal() { modal.style.display = "none"; } // ---------------------------------------------------- // Loop through all images and attach the click handler // ---------------------------------------------------- expandableImages.forEach(function(img) { img.addEventListener("click", function() { // When an image is clicked, call openModal and pass the clicked image object openModal(this); }); }); // ---------------------------------------------------- // Also close the modal if the user clicks anywhere outside of the modal content // ---------------------------------------------------- window.onclick = function(event) { if (event.target == modal) { closeModal(); } } // IMAGE SLIDER const sliders = document.querySelectorAll('.slider-wrapper'); sliders.forEach(wrapper => { const image = wrapper.querySelector('.expandable-image-toSlide'); const leftButton = wrapper.querySelector('.nav-button-left'); const rightButton = wrapper.querySelector('.nav-button-right'); let imageWidth = 0; let currentLeft = 0; image.addEventListener('load', () => { imageWidth = (image.width * wrapper.offsetHeight) / image.height; console.log("wrapper.offsetHeight : " + wrapper.offsetHeight) console.log("imageWidth : " + imageWidth) }); function moveImage(direction) { const wrapperWidth = wrapper.offsetWidth; const step = wrapperWidth * 0.25; console.log("wrapperWidth : " + wrapperWidth) if (direction === 'left') { imageWidth = (image.width * wrapper.offsetHeight) / image.height; currentLeft = Math.max(- imageWidth + wrapperWidth, currentLeft - step); console.log("currentLeft : " + direction + " "+ currentLeft) console.log("wrapper.offsetHeight : " + wrapper.offsetHeight) } else { imageWidth = (image.width * wrapper.offsetHeight) / image.height; currentLeft = Math.min(0, currentLeft + step); console.log("currentLeft : " + direction + " "+ currentLeft) console.log("wrapper.offsetHeight : " + wrapper.offsetHeight) } image.style.left = currentLeft + 'px'; } leftButton.addEventListener('click', () => moveImage('left')); rightButton.addEventListener('click', () => moveImage('right')); });