// script.js $(document).ready(function() { // Инициализация корзины let cart = { items: [ { id: 1, name: 'Кресло OPPORTUNITY', price: 16999, quantity: 1 }, { id: 2, name: 'Кресло GOLDEN', price: 19999, quantity: 1 }, { id: 3, name: 'Светильник POLET', price: 7999, quantity: 1 } ], delivery: 2000, discount: 0 }; // Функция обновления общей суммы function updateTotal() { let productsTotal = 0; let totalCount = 0; // Пересчитываем товары $('.products__item').each(function() { const $item = $(this); const price = parseInt($item.data('price')); const quantity = parseInt($item.find('.products__qty-value').text()); productsTotal += price * quantity; totalCount += quantity; }); // Обновляем отображение $('.products-total').text(productsTotal + ' ₽'); $('.summary-count').text(totalCount); $('.total-count').text(totalCount + ' шт.'); $('.cart-count').text(totalCount); // Обновляем итоговую сумму const finalTotal = productsTotal + cart.delivery - cart.discount; $('.final-total').text(finalTotal + ' ₽'); } // Функция валидации email function validateEmail(email) { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(email); } // Функция валидации имени (ФИО) function validateFullName(name) { // Проверяем, что имя содержит только буквы, пробелы, дефисы и апострофы const nameRegex = /^[a-zA-Zа-яА-ЯёЁ\s\-']+$/; // Проверяем, что имя состоит минимум из 2 слов const words = name.trim().split(/\s+/); return nameRegex.test(name) && words.length >= 2; } // Функция валидации телефона function validatePhone(phone) { // Российский формат телефона: +7XXXXXXXXXX const phoneRegex = /^\+7\d{10}$/; return phoneRegex.test(phone); } // Функция отображения сообщения function showMessage(messageId, duration = 5000) { // Скрываем все сообщения $('.message').hide(); // Показываем нужное сообщение $(messageId).fadeIn(300); // Автоматически скрываем через указанное время if (duration > 0) { setTimeout(() => { $(messageId).fadeOut(300); }, duration); } } // Функция показа ошибки приватности function showPrivacyError(show) { if (show) { $('#privacy-error').show(); } else { $('#privacy-error').hide(); } } // Функция отображения ошибки конкретного поля function showFieldError(fieldId, message) { // Убираем старые ошибки $(fieldId).removeClass('error-input'); $(fieldId + '-error').remove(); if (message) { $(fieldId).addClass('error-input'); $(fieldId).after('
' + message + '
'); } } // Валидация поля при потере фокуса с указанием конкретной ошибки $('#fullname').on('blur', function() { const value = $(this).val().trim(); if (value) { if (!validateFullName(value)) { showFieldError('#fullname', 'ФИО должно содержать только буквы и состоять минимум из 2 слов'); } else { showFieldError('#fullname', ''); } } else { showFieldError('#fullname', ''); } }); $('#email').on('blur', function() { const value = $(this).val().trim(); if (value) { if (!validateEmail(value)) { showFieldError('#email', 'Введите корректный email адрес (например: example@mail.ru)'); } else { showFieldError('#email', ''); } } else { showFieldError('#email', ''); } }); $('#phone').on('blur', function() { const value = $(this).val().trim(); if (value) { if (!validatePhone(value)) { showFieldError('#phone', 'Введите номер в формате +7XXXXXXXXXX (10 цифр после +7)'); } else { showFieldError('#phone', ''); } } else { showFieldError('#phone', ''); } }); // Валидация обязательных полей $('#region').on('blur', function() { const value = $(this).val().trim(); if (!value) { showFieldError('#region', 'Укажите регион доставки'); } else { showFieldError('#region', ''); } }); $('#address').on('blur', function() { const value = $(this).val().trim(); if (!value) { showFieldError('#address', 'Укажите адрес доставки (улица, дом, квартира)'); } else { showFieldError('#address', ''); } }); // Очистка ошибки при начале ввода $('.form__input').on('input', function() { const fieldId = '#' + $(this).attr('id'); showFieldError(fieldId, ''); }); // Обработчик увеличения количества $('.products__qty-btn.plus').click(function() { const $qtyValue = $(this).siblings('.products__qty-value'); let quantity = parseInt($qtyValue.text()); $qtyValue.text(quantity + 1); updateTotal(); }); // Обработчик уменьшения количества $('.products__qty-btn.minus').click(function() { const $qtyValue = $(this).siblings('.products__qty-value'); let quantity = parseInt($qtyValue.text()); if (quantity > 1) { $qtyValue.text(quantity - 1); updateTotal(); } }); // Обработчик удаления товара $('.remove-from-cart').click(function() { const $productItem = $(this).closest('.products__item'); $productItem.fadeOut(300, function() { $(this).remove(); updateTotal(); // Показываем сообщение, если корзина пуста if ($('.products__item').length === 0) { $('.products__list').html('
Корзина пуста
'); } }); }); // Обработчик применения промокода $('.promo__btn').click(function() { const promoCode = $('.promo__input').val().toUpperCase(); if (promoCode === 'SALE10') { cart.discount = Math.round(parseInt($('.products-total').text()) * 0.1); $('.discount-total').text(cart.discount + ' ₽'); showMessage('#form-error', 3000); $('#form-error').text('Промокод применен! Скидка 10%').removeClass('error').addClass('success'); } else if (promoCode === 'FREE') { cart.delivery = 0; $('.delivery-price').text('0 ₽'); showMessage('#form-error', 3000); $('#form-error').text('Промокод применен! Бесплатная доставка').removeClass('error').addClass('success'); } else if (promoCode) { showMessage('#form-error', 3000); $('#form-error').text('Промокод недействителен').removeClass('success').addClass('error'); } updateTotal(); }); // Обработчик выбора доставки $('input[name="delivery"]').change(function() { if ($(this).val() === 'pickup') { cart.delivery = 0; $('.delivery-price').text('0 ₽'); } else { cart.delivery = 2000; $('.delivery-price').text('2000 ₽'); } updateTotal(); }); // Функция проверки всех полей формы function validateForm() { let isValid = true; let errorMessages = []; // Очищаем все старые ошибки $('.field-error').remove(); $('.form__input').removeClass('error-input'); // Проверка обязательных полей const requiredFields = [ { id: '#fullname', value: $('#fullname').val().trim(), validator: validateFullName, required: true, message: 'ФИО должно содержать только буквы и состоять минимум из 2 слов' }, { id: '#phone', value: $('#phone').val().trim(), validator: validatePhone, required: true, message: 'Введите корректный номер телефона в формате +7XXXXXXXXXX' }, { id: '#email', value: $('#email').val().trim(), validator: validateEmail, required: true, message: 'Введите корректный email адрес' }, { id: '#region', value: $('#region').val().trim(), validator: (val) => val.length > 0, required: true, message: 'Поле "Регион" обязательно для заполнения' }, { id: '#address', value: $('#address').val().trim(), validator: (val) => val.length > 0, required: true, message: 'Поле "Адрес" обязательно для заполнения' } ]; // Проверяем каждое поле requiredFields.forEach(field => { if (field.required && (!field.value || !field.validator(field.value))) { isValid = false; errorMessages.push(field.message); showFieldError(field.id, field.message); } }); // Проверка согласия на обработку данных if (!$('#privacy-checkbox').is(':checked')) { isValid = false; showPrivacyError(true); errorMessages.push('Необходимо согласие на обработку персональных данных'); } else { showPrivacyError(false); } // Показываем общее сообщение, если есть ошибки if (!isValid && errorMessages.length > 0) { showMessage('#form-error', 5000); $('#form-error').text('Исправьте следующие ошибки: ' + errorMessages.join('; ')).removeClass('success').addClass('error'); // Прокручиваем к первой ошибке $('html, body').animate({ scrollTop: $('.error-input').first().offset().top - 100 }, 500); } return isValid; } // Обработчик оформления заказа $('#submit-order').click(function() { // Проверка валидации всех полей if (!validateForm()) { return; } // Симуляция отправки заказа $(this).prop('disabled', true).text('ОБРАБОТКА...'); setTimeout(() => { showMessage('#order-success', 5000); $(this).prop('disabled', false).text('ОФОРМИТЬ ЗАКАЗ'); // Здесь можно добавить редирект на страницу благодарности // window.location.href = 'спасибо.html'; }, 2000); }); // Маска для телефона $('#phone').on('input', function() { let phone = $(this).val().replace(/\D/g, ''); if (phone.length > 0) { if (phone[0] !== '7' && phone[0] !== '8') { phone = '7' + phone; } phone = '+7' + phone.substring(1, 11); $(this).val(phone); } }); // Инициализация при загрузке updateTotal(); });