You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
aliseptik/local/templates/.default/js/custom.js

471 lines
18 KiB

document.addEventListener("DOMContentLoaded", (event) => {
const cartForm = document.getElementById('cart-form');
Fancybox.bind("[data-fancybox]");
document.body.addEventListener('submit', function (e) {
const form = e.target;
if (form.matches('.add-to-cart-form')) {
e.preventDefault();
e.stopImmediatePropagation();
addToCart(form);
}
});
cartForm?.addEventListener('submit', function (e) {
e.preventDefault();
e.stopImmediatePropagation();
cartCheckout(e.target);
});
});
function cartCheckout(formElement) {
if (!formElement) return;
const formData = new FormData(formElement);
const submitButton = formElement.querySelector('button[type=submit]');
formData.forEach((value, key) => {
console.log(`${key}: ${value}`);
});
}
function addToCart(formElement) {
if (!formElement) return;
const formData = new FormData(formElement);
const submitButton = formElement.querySelector('.add-to-cart-button');
if (submitButton) {
submitButton.disabled = true;
submitButton.classList.add('is-loading');
}
fetch(formElement.getAttribute('action'), { // чтоб работало по action формы
// fetch(window.location.href, {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
if (data.STATUS === 'OK') {
showCartToast();
reloadCartLine();
} else {
showCartToast("Ошибка при добавлении в корзину", 3000, 'error');
}
})
.catch(error => {
showCartToast("Сервер недоступен или произошла ошибка", 3000, 'error');
})
.finally(() => {
if (submitButton) {
submitButton.disabled = false;
submitButton.classList.remove('is-loading');
}
});
}
function showCartToast(message = "Товар добавлен в корзину", timeout = 3000, type = 'success') {
const container = document.querySelector('.cart-toast-container');
if (!container) return;
const toast = document.createElement('div');
toast.className = `cart-toast ${type === 'error' ? 'cart-toast--error' : 'cart-toast--success'}`;
toast.innerHTML = `
<div class="cart-toast__message">${message}</div>
<div class="cart-toast__progress"></div>
`;
container.appendChild(toast);
setTimeout(() => {
toast.classList.add('show');
}, 10);
setTimeout(() => {
toast.classList.remove('show');
toast.addEventListener('transitionend', () => toast.remove());
}, timeout);
}
function reloadCartLine() {
fetch('/local/ajax/cart-line.php')
.then(res => res.text())
.then(html => {
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
const newCart = doc.querySelector('.header__cart');
if (newCart) {
const currentCart = document.querySelector('.header__cart');
currentCart.replaceWith(newCart);
}
})
.catch(err => console.error('Ошибка обновления корзины:', err));
}
function handleConsultationForm(formElement) {
if (!formElement) return;
const formData = new FormData(formElement);
const submitButton = formElement.querySelector('.button');
if (submitButton) {
submitButton.disabled = true;
submitButton.classList.add('is-loading');
}
fetch('/local/ajax/consultation.php', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
if (data.success) {
const isFooterPopup = formElement.querySelector('[name="footer_popup_form"]');
const isConsultation = formElement.querySelector('[name="consultation_form"]');
if (isFooterPopup) {
window.location.href = '/spasibo_blue/';
} else if (isConsultation) {
window.location.href = '/spasibo-footer/';
}
formElement.reset();
} else {
showCartToast("Ошибка при отправке заявки", 3000, 'error');
}
})
.catch(error => {
showCartToast("Произошла ошибка при отправке", 3000, 'error');
})
.finally(() => {
if (submitButton) {
submitButton.disabled = false;
submitButton.classList.remove('is-loading');
}
});
}
function handleForm(formElement) {
if (!formElement) return;
const formData = new FormData(formElement);
const submitButton = formElement.querySelector('.button');
const url='/local/ajax/form.php';
const redurect_url='/spasibo-footer/';
if (submitButton) {
submitButton.disabled = true;
submitButton.classList.add('is-loading');
}
fetch(url, {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
if (data.success) {
window.location.href = redurect_url;
formElement.reset();
} else {
showCartToast("Ошибка при отправке заявки", 3000, 'error');
}
})
.catch(error => {
showCartToast("Произошла ошибка при отправке", 3000, 'error');
})
.finally(() => {
if (submitButton) {
submitButton.disabled = false;
submitButton.classList.remove('is-loading');
}
});
}
// search-history.js
// --- Вспомогательные функции для работы с куками ---
function setCookie(name, value, days = 365) {
let expires = '';
if (days) {
const date = new Date();
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
expires = '; expires=' + date.toUTCString();
}
document.cookie = name + '=' + encodeURIComponent(value) + expires + '; path=/';
}
function getCookie(name) {
const matches = document.cookie.match(new RegExp(
'(?:^|; )' + name.replace(/([.$?*|{}()\[\]\\\/\+^])/g, '\\$1') + '=([^;]*)'
));
return matches ? decodeURIComponent(matches[1]) : undefined;
}
// --- Основная логика ---
function updateHistoryUI(history, containerId, inputId) {
const container = document.getElementById(containerId);
if (!container) return;
container.innerHTML = '';
if (!history.length) {
container.innerHTML = '<div style="padding:10px;color:#888;">Нет истории</div>';
return;
}
history.slice().reverse().forEach((item, idx) => {
const div = document.createElement('div');
div.className = 'header__search-history';
div.innerHTML = `
<button class="header__search-btn header__search-btn--again" data-value="${item}">
<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M17.5 10a7.5 7.5 0 0 1-7.4 7.5H10a7.452 7.452 0 0 1-5.148-2.047.626.626 0 0 1 .859-.909 6.25 6.25 0 1 0-.15-8.947L3.483 7.5h2.141a.625.625 0 0 1 0 1.25h-3.75a.625.625 0 0 1-.625-.625v-3.75a.625.625 0 0 1 1.25 0v2.328l2.207-2.016A7.5 7.5 0 0 1 17.5 10Z" fill="currentColor"></path><path d="M14.254 10.155a.625.625 0 0 0-.442-.183H10.57v-3.75a.625.625 0 0 0-1.25 0v4.375a.625.625 0 0 0 .625.625h3.868a.625.625 0 0 0 .442-1.067Z" fill="currentColor"></path></svg>
<span>${item}</span>
</button>
<button class="header__search-btn header__search-btn--remove" data-idx="${history.length - 1 - idx}">
<svg width="20" height="21" viewBox="0 0 20 21" xmlns="http://www.w3.org/2000/svg"><path d="m6 6.5 8.485 8.485m-8.485 0L14.485 6.5" stroke="currentColor" stroke-width="1.67" stroke-linecap="round"></path></svg>
</button>
`;
container.appendChild(div);
});
// Повторить поиск по истории
container.querySelectorAll('.header__search-btn--again').forEach(btn => {
btn.addEventListener('click', function (e) {
e.preventDefault();
const val = this.getAttribute('data-value');
const input = document.getElementById(inputId);
if (input) input.value = val;
});
});
// Удалить элемент истории
container.querySelectorAll('.header__search-btn--remove').forEach(btn => {
btn.addEventListener('click', function (e) {
e.preventDefault();
const idx = +this.getAttribute('data-idx');
history.splice(idx, 1);
setCookie(containerId, JSON.stringify(history));
updateHistoryUI(history, containerId, inputId);
});
});
}
function setupSearchHistory(formId, inputId, containerId, clearBtnId) {
let history = [];
try {
history = JSON.parse(getCookie(containerId) || '[]');
} catch (e) { history = []; }
updateHistoryUI(history, containerId, inputId);
const form = document.getElementById(formId);
const input = document.getElementById(inputId);
const clearBtn = document.getElementById(clearBtnId);
if (form && input) {
form.addEventListener('submit', function (e) {
e.preventDefault();
const val = input.value.trim();
if (!val) return;
// Не дублируем подряд одинаковые
if (!history.length || history[history.length - 1] !== val) {
history.push(val);
if (history.length > 10) history = history.slice(-10); // максимум 10
setCookie(containerId, JSON.stringify(history));
updateHistoryUI(history, containerId, inputId);
}
// Тут можно добавить реальный поиск (редирект или ajax)
// window.location.href = '/search/?q=' + encodeURIComponent(val);
});
}
if (clearBtn) {
clearBtn.addEventListener('click', function (e) {
e.preventDefault();
history = [];
setCookie(containerId, JSON.stringify(history));
updateHistoryUI(history, containerId, inputId);
});
}
}
function showSearchResults(results, blockId) {
const block = document.getElementById(blockId);
if (!block) return;
// Удаляем все предыдущие результаты
block.querySelectorAll('.search-results, .search-results-empty').forEach(el => el.remove());
let html = '';
if (results && results.length) {
html = '<div class="search-results">' + results.slice(0, 10).map(item =>
`<a href="${item.url}" class="search-result-item"><img src="${item.img}" alt="${item.title}" class="search-result-img"><span>${item.title}</span>${item.price ? `<div class='search-result-price'>${item.price}</div>` : ''}</a>`
).join('') + '</div>';
} else {
html = '<div class="search-results-empty">По вашему запросу ничего не найдено</div>';
}
block.insertAdjacentHTML('beforeend', html);
}
function clearSearchResults(blockId) {
const block = document.getElementById(blockId);
if (!block) return;
const res = block.querySelector('.search-results');
if (res) res.remove();
const empty = block.querySelector('.search-results-empty');
if (empty) empty.remove();
}
function ajaxSearch(inputId, blockId, historyBlockId) {
const input = document.getElementById(inputId);
const historyBlock = document.getElementById(historyBlockId);
if (!input) return;
input.addEventListener('input', function () {
const val = input.value.trim();
clearSearchResults(blockId);
if (historyBlock) {
if (val.length > 0) {
historyBlock.style.display = 'none';
} else {
historyBlock.style.display = '';
}
}
if (val.length < 1) return; // показываем результаты только если есть хотя бы 1 символ
fetch(`/local/ajax/search.php?q=${encodeURIComponent(val)}`)
.then(r => r.json())
.then(data => {
showSearchResults(data, blockId);
})
.catch(() => {
showSearchResults([], blockId);
});
});
// Скрывать результаты при потере фокуса
input.addEventListener('blur', function () {
setTimeout(() => clearSearchResults(blockId), 200);
if (historyBlock && input.value.trim().length === 0) {
historyBlock.style.display = '';
}
});
}
function setupSearchBlockFocus(inputId, blockId) {
const input = document.getElementById(inputId);
const block = document.getElementById(blockId);
if (!input || !block) return;
input.addEventListener('focus', function () {
block.classList.add('active');
});
input.addEventListener('blur', function () {
setTimeout(() => block.classList.remove('active'), 200);
});
}
function toggleSearchTopAndHistory(inputId, topId, historiesId) {
const input = document.getElementById(inputId);
const top = document.getElementById(topId);
const histories = document.getElementById(historiesId);
if (!input || !top || !histories) return;
input.addEventListener('input', function () {
if (input.value.trim().length > 0) {
top.style.display = 'none';
histories.style.display = 'none';
} else {
top.style.display = '';
histories.style.display = '';
}
});
input.addEventListener('blur', function () {
if (input.value.trim().length === 0) {
setTimeout(() => {
top.style.display = '';
histories.style.display = '';
}, 200);
}
});
}
function addToHistory(query, containerId, inputId) {
let history = [];
try {
history = JSON.parse(getCookie(containerId) || '[]');
} catch (e) { history = []; }
if (!history.length || history[history.length - 1] !== query) {
history.push(query);
if (history.length > 10) history = history.slice(-10);
setCookie(containerId, JSON.stringify(history));
updateHistoryUI(history, containerId, inputId);
}
}
function setupResultClickToHistory(inputId, containerId) {
document.addEventListener('click', function (e) {
const target = e.target.closest('.search-result-item');
if (target) {
const input = document.getElementById(inputId);
if (input) {
const val = input.value.trim();
if (val) {
addToHistory(val, containerId, inputId);
}
}
}
}, true);
}
document.addEventListener('DOMContentLoaded', function () {
setupSearchHistory('header-search-form', 'header-search-input', 'header-search-histories', 'header-search-clear');
setupSearchHistory('mobile-search-form', 'mobile-search-input', 'mobile-search-histories', 'mobile-search-clear');
ajaxSearch('header-search-input', 'header-search-history-block', 'header-search-histories');
ajaxSearch('mobile-search-input', 'mobile-search-history-block', 'mobile-search-histories');
setupSearchBlockFocus('header-search-input', 'header-search-history-block');
setupSearchBlockFocus('mobile-search-input', 'mobile-search-history-block');
toggleSearchTopAndHistory('header-search-input', 'header-search-top', 'header-search-histories');
toggleSearchTopAndHistory('mobile-search-input', 'mobile-search-top', 'mobile-search-histories');
setupResultClickToHistory('header-search-input', 'header-search-histories');
setupResultClickToHistory('mobile-search-input', 'mobile-search-histories');
});
// Открытие попапа для local/components/era/calculator/templates/.default/ajax.php
function openCartPopupForProduct(productName) {
document.querySelector('.cart-popup__wrapper').classList.remove('cart-popup__wrapper--hidden');
document.getElementById('fast_product').value = productName;
}
// From main.js
// const filter = document.querySelector(".catalog-page__filter");
// if (filter) {
// const openFilterBtn = document.querySelector(".js-show-filter");
// const hideFilterBtn = document.querySelector(".js-close-filter");
// const html = document.querySelector("html");
// if (openFilterBtn) openFilterBtn.addEventListener("click", ()=>{
// filter.classList.add("is-active");
// html.style.overflow = "hidden";
// });
// if (hideFilterBtn) hideFilterBtn.addEventListener("click", ()=>{
// filter.classList.remove("is-active");
// html.removeAttribute("style");
// });
// }
//recaptcha v3
if (typeof grecaptcha != 'undefined') {
grecaptcha.ready(function () {
grecaptcha.execute('6LcSCXArAAAAAO7T88PqurMYA2xeBWTAtOOWfrbo', { action: 'send_form' }).then(function (token) {
let recResponse = document.querySelectorAll('form');
if (recResponse.length){
recResponse.forEach((form) => {
let input = document.createElement("input");
input.setAttribute('type', 'hidden');
input.setAttribute('name', 'recaptcha_response');
input.setAttribute('value', token);
form.appendChild(input);
})
}
});
});
}