/home/bdqbpbxa/demo-subdomains/homesearch.goodface.com.ua/frontend/js/custom-solutions.js
// Prevent default function
function preventDefault(e) {
e.preventDefault();
}
// Scroll lock
function lockScroll() {
const html = document.documentElement;
const body = document.body;
const scrollTop = window.scrollY;
html.classList.add("-scroll-lock");
body.classList.add("-scroll-lock");
document.body.scrollTo(0, scrollTop);
html.setAttribute("data-scroll", scrollTop);
$(".--modal-scrollable-element").on("touchmove pointermove", preventDefault);
}
function unlockScroll() {
const html = document.documentElement;
const body = document.body;
const scrollPositionBeforeLock = html.getAttribute("data-scroll");
html.classList.remove("-scroll-lock");
body.classList.remove("-scroll-lock");
window.scrollTo(0, scrollPositionBeforeLock);
document.body.scrollTo(0, 0);
$(".--modal-scrollable-element").off("touchmove pointermove", preventDefault);
}
// Check device type
const isApple = navigator.userAgent.toLowerCase().indexOf("mac") !== -1;
const isAndroid = navigator.userAgent.toLowerCase().indexOf("android") !== -1;
if (isApple) {
document.body.classList.add("-apple");
}
if (isAndroid) {
document.body.classList.add("-android");
}
// Check device size
window.isPc = window.innerWidth > 1024;
window.isTablet = window.innerWidth > 759 && window.innerWidth <= 1024;
window.isMobile = window.innerWidth < 760;
function checkDeviceSize() {
window.isPc = window.innerWidth > 1024;
window.isTablet = window.innerWidth > 759 && window.innerWidth <= 1024;
window.isMobile = window.innerWidth < 760;
}
window.addEventListener("DOMContentLoaded", checkDeviceSize);
window.addEventListener("resize", checkDeviceSize);
// Set CSS variable with window.innerHeight
function setCssWindowInnerHeight() {
document.documentElement.style.setProperty("--window-inner-height", `${window.innerHeight}px`);
}
window.addEventListener("DOMContentLoaded", setCssWindowInnerHeight);
window.addEventListener("resize", setCssWindowInnerHeight);
// Set CSS variable with scrollbar width
function setScrollbarWidthInCSS() {
$("body").append(`
<div id="scrollbar-width-test" style="position: absolute;top: -999px;left: -999px;width: 50px;height: 50px;overflow: scroll;">
<div style="height: 100px;"></div>
</div>
`);
const scrollbarWidthTestEl = $("#scrollbar-width-test")[0];
const scrollbarWidth = scrollbarWidthTestEl.offsetWidth - scrollbarWidthTestEl.clientWidth;
document.documentElement.style.setProperty("--scrollbar-width", `${scrollbarWidth}px`);
window.scrollbarWidth = scrollbarWidth;
scrollbarWidthTestEl.remove();
}
window.addEventListener("DOMContentLoaded", setScrollbarWidthInCSS);
window.addEventListener("resize", setScrollbarWidthInCSS);
// Click outside callback
function customClickOutsideCallback(selector, callback) {
$(document).on("mouseup", function (e) {
const isSelector = $(e.target).is(selector);
const hasParent = $(e.target).closest(selector).length;
if (!isSelector && !hasParent && typeof callback === "function") {
callback(e, selector);
}
});
}
// Selector full transitionend callback
function fullTransitionendCallback(element, callback, customProperty = false) {
if ($(element).length === 0) return;
const transitionProperties = $(element)
.css("transition-property")
.split(",")
.map((property) => {
return property.trim();
});
const transitionDurations = $(element)
.css("transition-duration")
.split(",")
.map((duration) => {
return parseFloat(duration);
});
let longestProperty = false;
if (transitionProperties.length > 1 && customProperty === false) {
longestProperty = transitionProperties[transitionDurations.indexOf(Math.max(...transitionDurations))];
}
$(element).on("transitionstart", function () {
$(this).removeAttr("data-transitionend-triggered");
});
$(element).on("transitionend", function (e) {
const isTriggered = $(this).is("[data-transitionend-triggered]");
if (isTriggered) return;
const isCustomProperty = customProperty && e.originalEvent.propertyName === customProperty;
const isSingleCallback = customProperty === false && longestProperty === false && typeof callback === "function";
const isLongestPropertyCallback =
longestProperty && e.originalEvent.propertyName === longestProperty && typeof callback === "function";
if (isCustomProperty || isSingleCallback || isLongestPropertyCallback) {
$(this).attr("data-transitionend-triggered", true);
callback(e);
}
});
}
// Dropdowns
$(document).on("click", ".--dropdown__value", function () {
$(this).closest(".--dropdown").toggleClass("-active");
});
$(document).on("click", ".--dropdown__list-item", function () {
const dropdown = $(this).closest(".--dropdown");
const valueEl = dropdown.find(".--dropdown__value-text");
const valueContainer = dropdown.find(".--dropdown__value");
const text = $(this).text().trim();
const dataValue = $(this).data("value");
const value = dataValue ? dataValue : text;
if (valueEl.length) {
valueEl.html(value);
} else {
valueContainer.html(value);
}
dropdown.find("input").attr("value", value);
dropdown.find("input").change();
dropdown.find(".--dropdown__list-item").removeClass("-active");
dropdown.addClass("-selected").removeClass("-active");
$(this).addClass("-active");
});
$(document).on("click", ".--dropdown__clear", function () {
const dropdown = $(this).closest(".--dropdown");
const placeholder = dropdown.data("placeholder");
const valueEl = dropdown.find(".--dropdown__value-text");
const valueContainer = dropdown.find(".--dropdown__value");
if (valueEl.length) {
valueEl.html(placeholder ? placeholder : "");
} else {
valueContainer.html(placeholder ? placeholder : "");
}
dropdown.find("input").removeAttr("value");
dropdown.find(".--dropdown__list-item").removeClass("-active");
dropdown.removeClass("-selected -active");
});
customClickOutsideCallback(".--dropdown.-active", function (e, selector) {
$(selector).removeClass("-active");
});
// Phone musk
$(document).ready(function () {
const phoneMask = $(".--phone-mask");
if (!phoneMask.length) return;
phoneMask.inputmask({
mask: "+38 (999) 999 99 99",
showMaskOnHover: false,
});
});
// Adaptive textarea height
function setTextareaAdaptiveHeight(e) {
e.target.style.height = "0";
e.target.style.height = `${e.target.scrollHeight}px`;
}
function updateTextareaAdaptiveHeight() {
$("textarea.-adaptive-height").trigger("input");
}
$(window).on("resize", updateTextareaAdaptiveHeight);
$(document).on("input", "textarea.-adaptive-height", setTextareaAdaptiveHeight);
// Form validation
function formValidation(form) {
$(form)
.find("[data-important]")
.removeClass("-valid -invalid")
.each(function () {
const input = $(this).find("input, textarea");
const validationType = $(this).attr("data-important");
if (validationType === "email") emailValidator(input);
if (validationType === "count") countValidator(input);
if (validationType === "length") lengthValidator(input);
if (validationType === "checked") isCheckedValidator(input);
if (validationType === "not-empty") notEmptyValidator(input);
if (validationType === "inputmask") inputmaskValidator(input);
});
return $(form).find("[data-important].-invalid").length === 0;
}
$(document).on("focus", ".form [data-important] input, .form [data-important] textarea", function () {
$(this).closest("[data-important]").removeClass("-valid -invalid");
});
$(document).on("click", ".file-uploader", function () {
$(this).closest("[data-important]").removeClass("-valid -invalid");
});
// Form validation - helper
function setInputValidation(input, status) {
if (status) {
input.closest("[data-important]").addClass("-valid");
} else {
input.closest("[data-important]").addClass("-invalid");
}
}
// Form validation - validators
function notEmptyValidator(input) {
setInputValidation(input, input.val().trim().length > 0);
}
function inputmaskValidator(input) {
setInputValidation(input, input.inputmask("isComplete"));
}
function isCheckedValidator(input) {
setInputValidation(input, input.is(":checked"));
}
function emailValidator(input) {
const value = input.val().trim();
const reg =
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{1,}))$/;
setInputValidation(input, reg.test(String(value).toLowerCase()));
}
function countValidator(input) {
let isValid = true;
const value = input.val().trim();
const min = input.data("min");
const max = input.data("max");
if (value.length === 0) isValid = false;
if (min && value < min) isValid = false;
if (max && value > max) isValid = false;
setInputValidation(input, isValid);
}
function lengthValidator(input) {
const value = input.val().trim();
const minLength = input.closest("[data-important]").attr("data-min-length");
const maxLength = input.closest("[data-important]").attr("data-max-length");
let isValid = false;
if (minLength && maxLength) {
isValid = value.length >= minLength && value.length <= maxLength;
}
if (minLength && !maxLength) {
isValid = value.length >= minLength;
}
if (!minLength && maxLength) {
isValid = value.length <= maxLength;
}
setInputValidation(input, isValid);
}
// Checkboxes
$(document).on("click", ".--checkbox", function () {
const input = $(this).find('input[type="checkbox"]');
const checked = input.is(":checked");
$(this).toggleClass("-checked");
input[0].checked = !checked;
});
function customCheckboxReady() {
$(".--checkbox").each(function () {
const checked = $(this).find('input[type="checkbox"]').is(":checked");
const hasCheckedClass = $(this).hasClass("-checked");
if (checked && !hasCheckedClass) {
$(this).addClass("-checked");
} else if (!checked && hasCheckedClass) {
let checked = $(this).find('input[type="checkbox"]').is(":checked");
$(this).find('input[type="checkbox"]')[0].checked = !checked;
}
});
}
$(window).on("load", customCheckboxReady);
// Accordions
$(document).on("click", ".--accordion__open", function () {
const accordion = $(this).closest(".--accordion");
const isAccordionLock =
accordion.find("[data-accordion-in-process]").length ||
accordion.parent().closest("[data-accordion-in-process]").length;
if (isAccordionLock) return;
accordion.attr("data-accordion-in-process", true);
const isOpen = accordion.hasClass("-open");
if (isOpen) {
closeCustomAccordion(accordion);
} else {
openCustomAccordion(accordion);
}
});
function openCustomAccordion(accordion) {
const container = accordion.find(".--accordion__content-container").eq(0);
const contentHeight = accordion.find(".--accordion__content").eq(0).outerHeight();
accordion.addClass("-open");
container.css("height", `${contentHeight}px`);
closeSameAccordionGroup(accordion);
}
function closeCustomAccordion(accordion) {
const container = accordion.find(".--accordion__content-container").eq(0);
const containerCurrentHeight = container.outerHeight();
container.css({
height: `${containerCurrentHeight}px`,
transition: "unset",
});
container.outerHeight(); // Lifehack
container.css({
height: "0px",
transition: "",
});
accordion.removeClass("-open");
closeAccordionChildren(accordion);
}
function closeAccordionChildren(accordion) {
if (accordion.is("[data-close-children]")) {
accordion.find(".--accordion").each(function () {
closeCustomAccordion($(this));
});
}
}
function closeSameAccordionGroup(accordion) {
const groupName = accordion.attr("data-accordion-group");
if (groupName) {
$(`.--accordion[data-accordion-group="${groupName}"]`).each(function () {
if (accordion[0] !== this) {
closeCustomAccordion($(this));
}
});
}
}
fullTransitionendCallback(
".--accordion__content-container",
function (e) {
const accordion = $(e.target).closest(".--accordion");
const isOpen = accordion.hasClass("-open");
accordion.removeAttr("data-accordion-in-process");
if (isOpen) {
$(e.target).css("height", "auto");
}
},
"height"
);
// Lazyload - params
// if you set DEFAULT_LAZYLOAD_OFFSET to 0 or false
// then all elements on the page will be loaded the first time the scroll event fires
const DEFAULT_LAZYLOAD_OFFSET = 700;
// Lazyload - loaders
function imgLazyload(customSelector, customLazyloadOffset) {
const isSelectorValid = typeof customSelector === "string";
const selector = isSelectorValid ? `${customSelector} img.-lazyload` : "img.-lazyload";
const notSelector = isSelectorValid ? ".-loaded" : ".-loaded, [data-custom-lazyload-trigger] .-lazyload";
$(selector)
.not(notSelector)
.each(function () {
if (!customSelector && !isElementAllowToLoad(this, customLazyloadOffset)) return;
$(this).on("load", lazyloadFullLoadedCallback);
$(this).removeAttr("srcset").addClass("-loaded");
});
}
function bgLazyload(customSelector, customLazyloadOffset) {
const isSelectorValid = typeof customSelector === "string";
const selector = isSelectorValid ? `${customSelector} .-bg-lazyload` : ".-bg-lazyload";
const notSelector = isSelectorValid ? ".-loaded" : ".-loaded, [data-custom-lazyload-trigger] .-bg-lazyload";
$(selector)
.not(notSelector)
.each(function () {
if (!customSelector && !isElementAllowToLoad(this, customLazyloadOffset)) return;
const src = $(this).attr("data-src");
$(this).css("background-image", `url(${src})`).removeAttr("data-src").addClass("-loaded");
});
}
function videoLazyload(customSelector, customLazyloadOffset) {
const isSelectorValid = typeof customSelector === "string";
const selector = isSelectorValid ? `${customSelector} video.-lazyload` : "video.-lazyload";
const notSelector = isSelectorValid ? ".-loaded" : ".-loaded, [data-custom-lazyload-trigger] .-lazyload";
$(selector)
.not(notSelector)
.each(function () {
if (!customSelector && !isElementAllowToLoad(this, customLazyloadOffset)) return;
$(this).on("loadeddata", lazyloadFullLoadedCallback);
const src = $(this).attr("data-src");
const dataStart = $(this).attr("data-start-position");
const t = dataStart ? `#t=${dataStart}` : "";
const source = `<source type="video/mp4" src="${src}${t}" />`;
$(this).html(source).removeAttr("data-src").addClass("-loaded");
});
}
function iframeLazyload(customSelector, customLazyloadOffset) {
const isSelectorValid = typeof customSelector === "string";
const selector = isSelectorValid ? `${customSelector} iframe.-lazyload` : "iframe.-lazyload";
const notSelector = isSelectorValid ? ".-loaded" : ".-loaded, [data-custom-lazyload-trigger] iframe.-lazyload";
$(selector)
.not(notSelector)
.each(function () {
if (!customSelector && !isElementAllowToLoad(this, customLazyloadOffset)) return;
const src = $(this).attr("data-src");
$(this).on("load", lazyloadFullLoadedCallback);
$(this).attr("src", src).removeAttr("data-src").addClass("-loaded");
});
}
// Lazyload - helpers
function isElementAllowToLoad(el, customLazyloadOffset) {
const lazyloadOffset = customLazyloadOffset ? customLazyloadOffset : DEFAULT_LAZYLOAD_OFFSET;
if (!lazyloadOffset) return true;
const offsetTop = $(el).offset().top;
const offsetToLoad = window.scrollY + window.innerHeight + lazyloadOffset;
return offsetTop < offsetToLoad;
}
function lazyloadFullLoadedCallback(e) {
$(e.target).addClass("-full-loaded");
$(e.target).off("load", lazyloadFullLoadedCallback);
}
function lazyload(customSelector, customLazyloadOffset) {
imgLazyload(customSelector, customLazyloadOffset);
bgLazyload(customSelector, customLazyloadOffset);
videoLazyload(customSelector, customLazyloadOffset);
iframeLazyload(customSelector, customLazyloadOffset);
const notLoadedElementsCount = $(".-lazyload, .-bg-lazyload").not(".-loaded").length;
if (notLoadedElementsCount === 0) {
$(window).off("scroll", lazyloadOnScroll);
window.dispatchEvent(new Event("lazyload-final"));
}
}
function viewportLazyload() {
lazyload(false, 1);
}
function lazyloadOnScroll() {
if (window.scrollY > 0) {
lazyload();
}
}
$(window).on("load", viewportLazyload);
$(window).on("load scroll", lazyloadOnScroll);
// Check in viewport
function checkElementsInViewport() {
$("[data-check-in-viewport]").each(function () {
const viewportTop = window.scrollY;
const viewportBottom = viewportTop + window.innerHeight;
const offsetTop = $(this).offset().top;
const offsetBottom = offsetTop + $(this).outerHeight();
const isInViewport =
(offsetTop > viewportTop && offsetTop < viewportBottom) ||
(offsetBottom > viewportTop && offsetBottom < viewportBottom);
const hasInViewportClass = $(this).hasClass("-in-viewport");
const hasNotInViewportClass = $(this).hasClass("-not-in-viewport");
if (isInViewport && !hasInViewportClass) {
$(this).removeClass("-not-in-viewport").addClass("-in-viewport");
}
if (!isInViewport && !hasNotInViewportClass) {
$(this).removeClass("-in-viewport").addClass("-not-in-viewport");
}
});
}
$(window).on("load resize scroll", checkElementsInViewport);
// Tabs
$(document).on("click", ".--tabs-container__menu-item", function (e) {
const index = $(this).index();
const tabsContainer = $(this).closest(".--tabs-container");
const menuItems = tabsContainer.find(".--tabs-container__menu-item");
const tabs = tabsContainer.find(".--tabs-container__item");
menuItems.removeClass("-active");
menuItems.eq(index).addClass("-active");
updateCustomTabLinePosition(tabsContainer);
updateTabContentHeight(tabsContainer, tabs.eq(index));
tabs.removeClass("-active");
tabs.eq(index).addClass("-active");
});
function updateCustomTabLinePosition(tabsContainer) {
const menu = tabsContainer.find(".--tabs-container__menu");
const menuLine = tabsContainer.find(".--tabs-container__menu-line");
const activeMenuItem = tabsContainer.find(".--tabs-container__menu-item.-active");
if (menuLine.length) {
const lineWidth = activeMenuItem.find(".bold").outerWidth();
const linePosition =
menu.scrollLeft() + activeMenuItem.position().left + activeMenuItem.find(".bold").position().left;
menuLine.css({
width: `${lineWidth}px`,
transform: `translateX(${linePosition}px)`,
});
}
}
function updateTabContentHeight(tabsContainer, nextTab) {
const hasAutoHeight = tabsContainer.is("[data-auto-height]");
const animationInProcess = tabsContainer.is("[data-animation-in-process]");
if (hasAutoHeight) {
const itemsContainer = tabsContainer.find(".--tabs-container__items-inner");
const currTabHeight = tabsContainer.find(".--tabs-container__item.-active").outerHeight();
const nextTabHeight = nextTab.outerHeight();
if (animationInProcess) {
itemsContainer.css("height", `${nextTabHeight}px`);
} else {
tabsContainer.attr("data-animation-in-process", true);
itemsContainer.css({
height: `${currTabHeight}px`,
transition: "unset",
});
itemsContainer.outerWidth(); // Lifehack
itemsContainer.css({
height: `${nextTabHeight}px`,
transition: "",
});
}
}
}
function updateAllCustomTabsLinesPosition() {
$(".--tabs-container").each(function () {
updateCustomTabLinePosition($(this));
});
}
function readyCustomTabs() {
$(".--tabs-container").each(function () {
$(this).find(".--tabs-container__menu-item").eq(0).addClass("-active");
$(this).find(".--tabs-container__item").eq(0).addClass("-active");
});
}
fullTransitionendCallback(
".--tabs-container[data-auto-height] .--tabs-container__items",
function (e) {
$(e.target).css("height", "auto");
$(e.target).closest(".--tabs-container").removeAttr("data-animation-in-process");
},
"height"
);
$(document).ready(function () {
readyCustomTabs();
updateAllCustomTabsLinesPosition();
});
$(window).on("resize", updateAllCustomTabsLinesPosition);