Корзина покупателя на jQuery.

Плагин jqCart.

Когда писал предыдущую статейку на эту тему, которая преследовала цель всего лишь показать абстрактный пример реализации корзины покупателя, то не думал, что она породит такое количество вопросов и просьб, посыпавшихся и в самом блоге, и на мою почту, и т.д. Собственно, поэтому и решил написать этот плагинчик "jqCart", но хочу сразу подчеркнуть несколько моментов:

  1. Хоть код и оформлен в виде плагина, но плагином его можно назвать с большой натяжкой. Да и вообще, в этом направлении, на мой взгляд, сделать плагин полностью универсальным - достаточно сложно;
  2. Писа́лся плагин на скорую руку, поэтому достаточно сыроват, хотя и вполне рабочий;
  3. На данный момент, код не документированный;
  4. Планирую ли я его дорабатывать? Да, но при достаточном количестве свободного времени;

Итак, для работы плагина требуется библиотека jQuery >= 1.8, которая должна быть подключена до подключения самого плагина. Работать должно во всех современных браузера и, по идее, даже в IE8. Проблема для старых "осликов", может заключаться только в применяемых CSS-свойствах и версии jQuery (напомню, что jQuery 2.x - не поддерживает Internet Explorer 6, 7, и 8). Данные передаются на сервер с помощью Ajax и поэтому, я крайне рекомендую использовать кодировку для файлов UTF-8 без BOM!

Подключение:

<link href="css/jqcart.css" rel="stylesheet" type="text/css">
<script src="js/jquery-1.11.3.min.js"></script>
<script src="js/jqcart.min.js"></script>

Использование:

$(function() {
    'use strict';
    // инициализация плагина
    $.jqCart({
        buttons: '.add_item',        // селектор кнопок, аля "Добавить в корзину"
        handler: '/php/handler.php', // путь к обработчику
        visibleLabel: false,         // показывать/скрывать ярлык при пустой корзине (по умолчанию: false)
        openByAdding: false,         // автоматически открывать корзину при добавлении товара (по умолчанию: false)
        currency: '&euro;',          // валюта: строковое значение, мнемоники (по умолчанию "$")
        cartLabel: '.label-place'    /* селектор элемента, где будет размещен ярлык, 
                                        он же - "кнопка" для открытия корзины */
    });
    
    // дополнительные методы
    $.jqCart('openCart'); // открыть корзину
    $.jqCart('clearCart'); // очистить корзину
});

В кнопках ("Добавить в корзину"), должены быть прописаны следующие data-атрибуты:

  1. data-id - ID товара
  2. data-title - Наименование товара
  3. data-price - Цена товара
  4. data-img - URL фото товара (опционально)

Все значения вышеуказанных data-атрибутов, принимают участие при формировании окна корзины. Можно добавлять дополнительные data-атрибуты, значения которых будут отправлены с остальными данными в обработчик. Ключи в полученном массиве на сервере, будут соответствовать имени атрибута после "data-", т.е. значение атрибута "data-somevalue", будет в массиве под ключем "somevalue" Тег для кнопки и её расположение на странице - значения не имеет.

Пример:

<button class="add_item" data-id="7" data-title="Bugatti Veyron Super Sports" data-price="200" data-img="http://site.com/img/photo.png">Добавить в корзину</button>

В архиве найдете пример обработчика (handler.php) с подготовкой и отправкой письма на почту. В конце обработчика, обязательно должен быть ответ клиенту в формате JSON.

<?php
// какой-то код обработки заказа...

// Ответ на запрос
// !для версии PHP < 5.4, используйте традиционный синтаксис инициализации массивов array() вместо короткого []
$response = [
    'errors' => !$send_ok,
    'message' => $send_ok ? 'Заказ принят в обработку!' : 'Хьюстон! У нас проблемы!'
];
exit( json_encode($response) );

Где переменная $send_ok - булевое значение (true/false), в зависимости от результата обработки заказа. Если это будет отправка на почту, то можно так:

<?php
$send_ok = mail($to, $subject, $body, implode("\r\n", $headers));

Ахтунг! В обработчике я не делал фильтрацию данных, поэтому внимательно и тщательно их обрабатывайте перед использованием, а особенно, если вы собираетесь записывать данные в БД!

Версия 1.1.0

  • Данные распределены по разным data-атрибутам кнопки
  • Добавлена возможность отображения фото товара в корзине
  • Добавлен параметр currency для вывода в корзине валюты рядом со стоимостью и ценой
  • Добавлена возможность передавать на сервер дополнительные данные, которые берутся из пользовательских data-атрибутов кнопки

Версия 1.1.1

  • Добавлена опция visibleLabel. Показывать ярлык при пустой корзине
  • Добавлена опция openByAdding. Автоматически открывать корзину при добавлении товара
  • Добавлена кнопка вывода заказа на печать

Версия 1.1.2

  • Исправлен расчет сумм с плавающей точкой

Просьба описывать в комментариях найденные вами ошибки/баги. По мере возможностей, я буду их править, НО глобальными изменениями или дополнениями, буду заниматься, как уже говорил, при наличии свободного времени

Incode Pro logo

807 комментариев

Страница 24 из 33  
Гость 26.12.2016 21:07
Напишите поподробнее, пожалуйста, вашу мысль. Что добавить везде?



добавляем

addToCart: function(e) {
e.preventDefault();
itemData = $(this).data();
if(typeof itemData.id === 'undefined') {
console.log('Отсутствует ID товара');
return false;
}
cartData = actions.getStorage() || {};
if (cartData.hasOwnProperty(itemData.id)) {
//cartData[itemData.id].count++;
//#-------------------------------------
swal({ title: "Внимание!", text: "Товар в корзине. Откройте корзину для редактирования"} );
//#-------------------------------------
var cntOutput = $('.jqcart-total-cnt');
cntOutput.text(+cntOutput.text());
return false;
} else {


itemData.count = $(this).data('count');
itemData.price = $(this).data('price');

cartData[itemData.id] = itemData;

}
actions.setStorage(cartData);
actions.changeTotalCnt(1);
label.show();
if(opts.openByAdding) {
actions.openCart();
}
//#-----------------------------------
document.getElementById("korzina_no_in_put_" + itemData.id).removeAttribute('class');
document.getElementById("korzina_no_in_put_" + itemData.id).setAttribute('class', 'fa fa-cart-arrow-down');
//#-----------------------------------
return false;
},

-------------------------------------------

удаляем

delFromCart: function() {
var $that = $(this),
line = $that.closest('.jqcart-tr'),
itemId = line.data('id');
cartData = actions.getStorage();
actions.changeTotalCnt(-cartData[itemId].count);
delete cartData[itemId];
//#-----------------------------------
if (document.getElementById("korzina_no_in_put_" + itemId) !== null)
{
document.getElementById("korzina_no_in_put_" + itemId).removeAttribute('class');
document.getElementById("korzina_no_in_put_" + itemId).setAttribute('class', 'fa fa-cart-plus');
}
//#----------------------------------
actions.setStorage(cartData);
line.remove();
actions.recalcSum();
return false;
},


------------------------------------------
при инициализации

init: function(o) {
opts = $.extend(opts, o);
cartData = actions.getStorage();
if (cartData !== null && Object.keys(cartData).length) {
for (var key in cartData) {
//#------------------------------
if (document.getElementById("korzina_no_in_put_" + cartData[key].id) !== null)
{
var elementById = document.getElementById("korzina_no_in_put_" + cartData[key].id);
var elemenID = elementById.id;
var elementDataKey = "korzina_no_in_put_" + cartData[key].id;
if (elemenID == elementDataKey) {
document.getElementById("korzina_no_in_put_" + cartData[key].id).removeAttribute('class');
document.getElementById("korzina_no_in_put_" + cartData[key].id).setAttribute('class', 'fa fa-cart-arrow-down');
}}
//#-------------------------------------
if (cartData.hasOwnProperty(key)) {
totalCnt += cartData[key].count;
}
}
visibleLabel = true;
}

------------------------------------------

<div class="item_box">
<span><i id="korzina_no_in_put_1" style="cursor:pointer; color: gray; font-size: 24px;" class="fa fa-cart-plus"></i></span>
<img src="img/lg.png" alt="">
<h3 class="item_title">HTS 500</h3>
<p>Цена: <span class="item_price">0.6</span>$</p>
<button class="add_item" data-id="1" data-title="HTS 500" data-price="0.6" data-img="http://incode.pro/demo/icp_example20/img/lg.png" data-count="1">Добавить в корзину</button>
</div>


так понятно
Гость 26.12.2016 22:42
ну и Очистить корзину (вызов метода clearCart)

clearCart: function(){
cartData = actions.getStorage();
var key
for (key in cartData) {
if (cartData.hasOwnProperty(key)) {
//#------------------------------
if (document.getElementById("korzina_no_in_put_" + cartData[key].id) !== null)
{
var elementById = document.getElementById("korzina_no_in_put_" + cartData[key].id);
var elemenID = elementById.id;
var elementDataKey = "korzina_no_in_put_" + cartData[key].id;
if (elemenID == elementDataKey) {
document.getElementById("korzina_no_in_put_" + cartData[key].id).removeAttribute('class');
document.getElementById("korzina_no_in_put_" + cartData[key].id).setAttribute('class', 'fa fa-cart-plus');
}}
//#-------------------------------------
}}
localStorage.removeItem('jqcart');
label[opts.visibleLabel ? 'show' : 'hide']().find('.jqcart-total-cnt').text(0);
actions.hideCart();
},
Гость 27.12.2016 00:23
ну и Очистить корзину (вызов метода clearCart)

Спасибо вам большое за помощь! Код работает ширарно ))) с clearCart завтра буду пищать от восторга, что вообще все работает, сегодня температурю по 38,5.
И с наступающими вас праздниками )))
Гость 27.12.2016 16:49
сегодня температурю по 38,5.


С таким рвением как у Вас уже бы ocstore подключили и не парились...
Гость 28.12.2016 13:41
ну и Очистить корзину (вызов метода clearCart)

Все работает просто супер!!! Ура!!!

С таким рвением как у Вас уже бы ocstore подключили и не парились..

Мне под задачу создания магазина информационных продуктов подошел именно jqcart. А так, да, до этого, как вы верно отметили "с таким рвением", были осмотрено n-ое количество коробочных модулей интернет-магазинов, и как-то с ним не срослось. Так что стартовать мой новый интернет-проект будет с jqcart )))
Гость 09.01.2017 04:21
Битая ссылка на архив https://incode.pro/examples/icp_example20.zip может кто-нибудь выложит в коменты ссылку на файлик, если не сложно?
Гость 09.01.2017 05:32
А как в значке корзины вывести количество наименований товаров. Например, есть рубашка1 и рубашка2. Каждой из них купили по 5 штук, итого в корзине 2 наименования товара, но количество 10 штук. Вот нужно вывести именно что 2 наименования.
Гость 09.01.2017 06:42
Очень нужная штука, где если товар в корзине, то написано, что товар уже в корзине и добавить ещё раз нельзя. Но в комментах так непонятно написано, что куда добавлять, что где удалять .. Пожалуйста, для чайников, напишите понятнее, пожалуйста)
Incode 09.01.2017 10:53
Битая ссылка на архив
Поправил.

По всем остальным вопросам - в сотый раз повторю, что в ближайшее время у меня нет возможности заняться модернизацией плагина. У меня нет даже времени отвечать на все комментарии. Прошу простить и понять, что проект, над которым я сейчас работаю, абсолютно не оставляет мне свободного времени.
P.S. Спасибо тем, кто, как я видел выше, помогает тут другим в решении проблем.
Гость 10.01.2017 22:05
Очень нужная штука, где если товар в корзине, то написано, что товар уже в корзине и добавить ещё раз нельзя. Но в комментах так непонятно написано, что куда добавлять, что где удалять .. Пожалуйста, для чайников, напишите понятнее, пожалуйста)


cartData[itemData.id].count++; эта строка добавляет товар в корзину автоматом

нужно автоматом то тогда так


cartData[itemData.id].count++;
//#-------------------------------------
//swal({ title: "Внимание!", text: "Товар в корзине. Откройте корзину для редактирования"} );
//#-------------------------------------
Гость 10.01.2017 22:31
Гость 09.01.2017 05:32
А как в значке корзины вывести количество наименований товаров. Например, есть рубашка1 и рубашка2. Каждой из них купили по 5 штук,


Для этого нужно сравнить id товара если есть то добавить в некий див cntOutput1.text(+cntOutput1.text());
если нет
cntOutput1.text((+cntOutput1.text() + n));
Гость 10.01.2017 22:55
Уважаемые пользователи скрипта!
Моя помощь девушке которая просила помочь ей со значками для корзины, это частный случай и она понимала зачем ей это надо. Для тех кто пишет, что они "чайники" это сложный скрипт, любая Ваша ошибка приведет к тому, что пользователь Вашего магазина не сможет им воспользоваться т.к. это не сессия на стороне сервера, это локальное хранилище на стороне клиента и не "убив" localStorage.setItem('jqcart', JSON.stringify(o)); Вы обречены...
Поэтому прочитайте сначала, что такое localStorage, а потом решайте зачем он Вам нужен.
Этот скрипт чистый лист и его модификация довольно муторная штука.
Гость 13.01.2017 20:22
перепробовал кучу корзин
на некоторых даже сделал довольно нормально работающие магазины...
но все время чего-то не хватало...

Метод передачи в скрипт цены и пр. через data-атрибуты
для меня сущее золото!!!

Учитывая как и на чем я делаю сайты, это то что надо!

Но, учитывая то, что я в скриптах НОЛЬ, нужна конечно адаптация....
Готов оплатить работу, если потяну конечно...

Залил на сайт, заказ что-то на отправляется (после нажатия на кнопку ОТПРАВИТЬ заказ ничего не происходит, соответственно письмо мне не приходит)

А где прописывается Email администратора?
Гость 13.01.2017 20:29
>А где прописывается Email администратора?

нашел !
altlogik 13.01.2017 20:43
авторизовался...
кнопка ОТПРАВИТЬ ЗАКАЗ так и не работает
Гость 13.01.2017 21:14
авторизовался...
кнопка ОТПРАВИТЬ ЗАКАЗ так и не работает

а если не секрет куда Вы отправляете заказ

handler: './php/handler.php', ???
Гость 13.01.2017 21:23
Метод передачи в скрипт цены и пр. через data-атрибуты
для меня сущее золото!!!


и это не самый лучший способ передачи данных в скрипт
Гость 13.01.2017 21:32
добавляем кнопку очистить корзину в диалоговое окно

$(document)
.on('click', opts.buttons, actions.addToCart)
.on('click', '.jqcart-layout', function(e) {
if (e.target === this) {
actions.hideCart();
}
})
.on('click', '.jqcart-incr', actions.changeAmount)
.on('input keyup', '.jqcart-amount', actions.changeAmount)
.on('click', '.jqcart-del-item', actions.delFromCart)
.on('submit', '.jqcart-orderform', actions.sendOrder)
.on('reset', '.jqcart-orderform', actions.hideCart)
.on('click', '.jqcart-print-order', actions.printOrder)
//----------------------------------------
.on('click', '.jqcart-clearCart-order', methods.clearCart);
//----------------------------------------
return false;
},







orderform = '<form class="jqcart-orderform"><p><input type="button" class="jqcart-clearCart-order" value="Очистить корзину"></p><p><input type="submit" value="Отправить заказ"><input type="reset" value="Продолжить"></p></form>';
altlogik 14.01.2017 07:17
а если не секрет куда Вы отправляете заказ

handler: './php/handler.php', ???

Что значит куда? (СОРИ за бестолковость)
Указываю email в заказе, в скрипте выставил Email админа,
никуда ничто не приходит... после нажатия кнопки окно подтверждающее отправку не всплывает
altlogik 14.01.2017 17:47
http://morozko58.ru/10/ вот тут
altlogik 14.01.2017 18:15
сори, все заработало.
Была проблема описанная в посте
08.02.2016 21:51
altlogik 14.01.2017 19:15
Данные передаются на сервер с помощью Ajax и поэтому, я крайне рекомендую использовать кодировку для файлов UTF-8 без BOM!


А можно все же работать в windows-1251 ?
Дело в том, что моя CMS работает только на windows-1251
А менять ее ОЧЕНЬ не хочется...

Попробовал перевести все файлы в windows-1251,
на сайте все ОК, но письма приходят с кривозябликами.

Это тоже поправил.
$headers[] = 'Content-type: text/html; charset=windows-1251'; // Обязательный заголовок. Кодировку изменить при необходимости
altlogik 14.01.2017 20:43
Понял, что проблему с windows-1251 решить можно
https://habrahabr.ru/post/17640/

Но самому мне это не осилить....
altlogik 15.01.2017 13:17
ИМХО
Было бы неплохо разделить Корзину и Контактную информацию.

Т.е. СНАЧАЛА набиваем корзину, определяемся с количеством/суммой,
а затем нажимая кнопку ОФОРМИТЬ ЗАКАЗ, попадаем уже на Контактную информацию.

Тем самым уменьшаем размер общего окна, что особенно критично на мобильных устройствах.
infinitymd 16.01.2017 16:06
Тогда уже лучше делать корзину на статичной странице, а не всплывающим окном...
Страница 24 из 33  
Ваш комментарий:
X