Корзина на сайте — часть 2

Решил написать вторую часть в продолжение того поста, который написал 2 года назад. Судя по статистике переходов на страницу первой части из Яндекс метрики и комментариям по этой теме (в старом блоге), этот модуль имеет популярность, хотя уже и не обновляется вроде, но тем не менее. Использую его сам и код, который будет приводится здесь в описании насущных проблем выдран из рабочего проекта.

Как уже и было сказано в первой части, эта простая библиотека имеет обширную документацию и является очень простым решением JavaScript корзины. А что это значит? Прежде всего, что вам не нужно использовать дополнительный код php и хранить все товары корзины в базе данных, к примеру. Или еще где то. Самый простой и безболезненный вариант состоит в том, что вы просто подключаете скрипт, в карточке товаров даете элементам определенные css-классы, а на странице корзины и оформления заказа выводите все элементы в виде таблицы или списком одной лишь конструкцией:

<div class="simpleCart_items"></div>

Но на практике, конечно, все может обстоять гораздо сложнее. Имеется ввиду, что если, я не хочу стандартный вывод товаров в корзине, который предлагает simpleCart? Да и потом, даже если у меня вывелись все товары в корзине стандартным способом, как же мне сделать так, чтобы потом, когда я начал заполнять форму клиента (Ф.И.О., адрес и т.д.), все данные передать в email? Или отправить платежным системам? Предлагаю, чтобы долго не гулять по документации и не пробовать все методом проб и ошибок, сделать следующим образом.

Карточка товара. Определяем необходимые свойства

На этот раз мы усложним задачу и сделаем добавление, вывод из корзины и отправку всех данных на email менеджеру магазина (а потом не сложно будет и платежным системам эти данные передавать, усвоив это). Но не простым стандартным способом, а используя замечательные методы, любезно предоставляемые автором этой корзины. Отмечу, что код взял с рабочего проекта, разметка карточки товара своя, но на этом примере будет понятней, надеюсь, как работать с simpleCart более плодотворно.

Прежде всего оборачиваем контейнер с карточкой товара в класс simpleCart_shelfItem. В нашем магазине у товаров присутствует:

  • Название. Элементу даем css-класс: item_name
  • Изображение. css-класс: item_image. Причем этот элемент пускай будет не img, а div, и url изображения будет выводится в специальном атрибуте data-img, причем изображение получается применением стиля к этому элементу: background: url("...") center top, где ... — url картинки товара
  • Цена. css-класс: item_price
  • Количество. css-класс: item_Quantity. Поле input, желательно по этому полю еще валидацию на числа подключить
  • Размер. css-класс: item_size
  • Цвет. css-класс: item_color

Минимальные основные поля в карточке товара определили. Еще сделаем кнопку «Добавить в корзину» с классом add_to_cart. Теперь подключаем скрипт на наших страницах в футере после подключения самой библиотеки и пишем:

Обработка кнопки добавления в корзину:

$(function () {
    var btn = $('.add_to_cart');
    setTimeout(function () {
        if (btn.length) {
            var containerSimpleCart = $('.simpleCart_shelfItem'),
                nameProductThis = containerSimpleCart.find('.item_name').text();
            if (simpleCart.find({name: $.trim(nameProductThis)}).length) {
                btn.text('Уже в корзине');
            }
        }
    }, 50);
    btn.on('click', function () {
        var container = $('.simpleCart_shelfItem'),
            nameProduct = container.find('.item_name').text();
        if (parseInt(container.find('.item_Quantity').val()) > 0) {
            if (!simpleCart.find({name: $.trim(nameProduct)}).length) {
                $(this).unbind('click');
                $(this).attr('disabled', 'disabled').css('opacity', 0.5);
                setTimeout(function () {
                    var product = simpleCart.add({
                        name: $.trim(nameProduct),
                        price: parseFloat(container.find('.item_price').text()),
                        image: container.find('.item_image').data('img'),
                        size: container.find('.item_size').text(),
                        color: container.find('.item_color').text(),
                        quantity: parseInt(container.find('.item_Quantity').val())
                    });
                    if (product)
                        alert('Товар добавлен в корзину!');
                    btn.removeAttr('disabled').css('opacity', 1).text('Уже в корзине');
                }, 300);
            } else {
                alert('Товар уже в корзине!');
            }
        } else {
            alert('Не верно заполнено поле количество!');
        }
    });
});

Товар в корзине, все происходит без перезагрузки страницы и глобальный объект корзины уже содержит данные по этой позиции. Пойдем в другую карточку товара, добавим еще одну позицию и опять simpleCart все запомнит. Причем в самой библиотеки реализовано хранение данных (через куки). Даже если пользователь закроет браузер и не будет некоторое время посещать сайт, а потом вернется, то все что он ложил в корзину, будет актуально, пока он не сделает заказ или не очистит корзину. За полное очищение корзины отвечает метод .empty( ). Код добавления вы можете и должны будете перепиливать под свои нужды и свои свойства товара в карточке. Самое главное тут (в доке это есть, но надо м/у строк читать), это simpleCart.find( ), — нужен для поиска в глобальном объекте текущего товара, simpleCart.add( ), — нужен для добавления текущей позиции и всех ее свойств, которые вы захотите использовать в своем магазине. Если с этим разобрались, то идем дальше.

Страница корзины. Выводим товары

Оборачиваем контейнер этой страницы в класс cart_page. Дополняем наш код, который выше (после обработчика «Добавить в корзину»), следующим:

var pathToHandlers = "/views/myshop/handlers/";
    if ($('.cart_page').length) {
        setTimeout(function () {
            var itemsLenght = simpleCart.items().length,
                arr = [];
            simpleCart.each(function (item, x) {
                var productName = item.get("name"),
                    productPrice = item.get("price"),
                    productQuantity = item.get("quantity"),
                    productImage = simpleCart.items()[x].options().image,
                    productSize = simpleCart.items()[x].options().size,
                    productColor = simpleCart.items()[x].options().color;
                arr.push([productName, productPrice, productQuantity, productImage, productSize, productColor]);
            });
            if (!simpleCart.quantity()) {
                $('.cart_page').html('<p>Корзина пуста</p>');
            } else {
                $.post(pathToHandlers + "out-cart.php", {products: arr}, function (data) {
 
                    /* Выводим все товары на страницу: */
                    $('.cart_page').html(data);
 
                    /*
                    * --- Далее можно сделать ---
                    *
                    * Очистка корзины:
                    * Повесить обработчик: .empty() на кнопку очистить корзину
                    *
                    * Удаление позиции
                    *
                    * Вывод общей суммы: simpleCart.total()
                    *
                    * Вывести кнопку оплаты платежных систем
                    *
                    * Обработка кнопки отправить завку на email и многое другое...
                    * */
                });
            }
        }, 50);
    }

Переменная pathToHandlers содержит путь к файлу out-cart.php (у вас путь будет свой!), к которому идет обращение из скрипта асинхронно и загрузка на страницу html именно из файла out-cart.php. В этом файле, как минимум, вы обязаны будете принять данные $products = $_POST['arr'], это будет массив товаров в корзине по всем позициям, и в php-цикле foreach($products as $product){...} вывести каждую позицию товара со всеми его свойствами в том html, который вам нужен (здесь, в этом же файле, после цикла, можно нарисовать и вашу любимую форму клиента, дать ей все айдишники по полям и кнопку отправить, на которую повесить обработчик отправки email, можно также легко через ajax). В данном случае, в цикле мы будем получать переменные:

  • $product[0], — название
  • $product[1], — цена
  • $product[2], — кол-во
  • $product[3], — url картинки
  • $product[4], — размер
  • $product[5], — цвет

В итоге файл скрипта у вас примерно должен получиться примерно такой:

$(function () {
    var btn = $('.add_to_cart'),
        pathToHandlers = "/views/myshop/handlers/";
    setTimeout(function () {
        if (btn.length) {
            var containerSimpleCart = $('.simpleCart_shelfItem'),
                nameProductThis = containerSimpleCart.find('.item_name').text();
            if (simpleCart.find({name: $.trim(nameProductThis)}).length) {
                btn.text('Уже в корзине');
            }
        }
    }, 50);
    btn.on('click', function () {
        var container = $('.simpleCart_shelfItem'),
            nameProduct = container.find('.item_name').text();
        if (parseInt(container.find('.item_Quantity').val()) > 0) {
            if (!simpleCart.find({name: $.trim(nameProduct)}).length) {
                $(this).unbind('click');
                $(this).attr('disabled', 'disabled').css('opacity', 0.5);
                setTimeout(function () {
                    var product = simpleCart.add({
                        name: $.trim(nameProduct),
                        price: parseFloat(container.find('.item_price').text()),
                        image: container.find('.item_image').data('img'),
                        size: container.find('.item_size').text(),
                        color: container.find('.item_color').text(),
                        quantity: parseInt(container.find('.item_Quantity').val())
                    });
                    if (product)
                        alert('Товар добавлен в корзину!');
                    btn.removeAttr('disabled').css('opacity', 1).text('Уже в корзине');
                }, 300);
            } else {
                alert('Товар уже в корзине!');
            }
        } else {
            alert('Не верно заполнено поле количество!');
        }
    });
    if ($('.cart_page').length) {
        setTimeout(function () {
            var itemsLenght = simpleCart.items().length,
                arr = [];
            simpleCart.each(function (item, x) {
                var productName = item.get("name"),
                    productPrice = item.get("price"),
                    productQuantity = item.get("quantity"),
                    productImage = simpleCart.items()[x].options().image,
                    productSize = simpleCart.items()[x].options().size,
                    productColor = simpleCart.items()[x].options().color;
                arr.push([productName, productPrice, productQuantity, productImage, productSize, productColor]);
            });
            if (!simpleCart.quantity()) {
                $('.cart_page').html('<p>Корзина пуста</p>');
            } else {
                $.post(pathToHandlers + "out-cart.php", {products: arr}, function (data) {

                    /* Выводим все товары на страницу: */
                    $('.cart_page').html(data);

                    /*
                     * --- Далее можно сделать ---
                     *
                     * Очистка корзины:
                     * Повесить обработчик: .empty() на кнопку очистить корзину
                     *
                     * Удаление позиции
                     *
                     * Вывод общей суммы: simpleCart.total()
                     *
                     * Вывести кнопку оплаты платежных систем
                     *
                     * Обработка кнопки отправить завку на email и многое другое...
                     * */
                });
            }
        }, 50);
    }
});

Резюмируя все вышесказанное, вам просто нужно взять за основу этот материал, документацию simpleCart, предварительно знать немного js/jQuery и у вас все получится. Если нет, — обсуждения новых проблем в комментариях, думаю будут вопросы, так как очень бегло написал статью, на самом деле.



Похожие заметки:

Скрипт динамической ширины

Скрипт для равномерного распределения блоков по ширине родительского контейнера. В качестве контейнера может выступать любой блок как определенной ширины, так и неопределенной, вплоть до body. Что умеет?

  • Нарезать блоки на одинаковую ширину в зависимости от заданного количества колонок
  • Генерировать нужное количество колонок
  • Проставлять clearfix после оканчивающей ряд колонки, чтобы вовремя отменить обтекание
  • Удалять лишние clearfix

Открыть здесь

Верстка

Услуги » верстка страниц сайта

Открыть здесь

Удобная разработка с livereload, установка browser-sync

Livereload — «живая» перезагрузка страниц в браузере, при изменении в файлах проекта. Обычно очень удобно при разработке нового проекта, когда постоянно вносятся и тестируются изменения, особенно если дебажим во многих вкладках и браузерах сразу

Открыть здесь


Перед тем как писать комментарии, рекомендую ознакомиться:

Markdown синтаксис »

Оформление кода »

Нужна аватарка »

Комментарии


2
avatar

Дмитрий сказал 20-02-2019 в 18:52


Здравствуйте. Спасибо за интернет-корзину. Есть вопрос. Возможность добавления на страницу товара второй кнопки "Оформить заказ", чтобы одна кнопка была на всех страницах в правом верхнем углу, а вторая рядом с кнопкой "Купить" в карточке товара, отображая количество зарезервированных товарных позиций.


avatar

Админ

Роман Жариков сказал 27-02-2019 в 01:16

   В ответ на комментарии автора Дмитрий

Добрый вечер!Не совсем понял ваш вопрос :)

Статью писал очень давно, но использовал этот функционал на одном проекте, который остался на у меня на поддомене - вот здесь. Можете там посмотреть. Если что то аналогичное, то смогу поделиться мыслями