Корзина покупателя на 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 комментариев

Страница 25 из 33  
goliaf 29.11.2016 03:14
Здравствуйте!
А как вывести корзину не в модальном окне, а на отдельной страничке.html
Подскажите?
goliaf 29.11.2016 05:32
@goliaf,
реализовал через $(location).attr('href',url);
Пришлось немного плагин заточить, и теперь не робит delFromCart (((
goliaf 29.11.2016 08:11
Так я и не победил его ((
Подскажите, почему на другой странице .count == undefined?
(-cartData[itemId].count)
Гость 10.12.2016 21:42
Хотелось бы, чтобы было на ссылке открытия корзины такая надпись, что в корзине столько-то товаров на такую-то сумму. Не понятно только, как это чудо осуществить. Кстати, кнопку "Очистить корзину" я добавил в модальное окно, думаю, так красивее... Если кому надо такое, поделюсь
Гость 10.12.2016 23:53
Здравствуйте!
Подскажите, пожалуйста, как можно отобразить на странице-каталоге товаров, что товар уже добавлен в корзину. Мне нужно сделать большой каталог информационных товаров и без такой подсказки в нем очень сложно ориентироваться.
В javascript знания минимальны, но очень хочется сделать, чтобы по клику на кнопку "добавить в корзину" рядом с названием товара появлялся зеленый значок-галочка или текст "товар добавлен в корзину".
Смотрела информацию по "onclick" событию, ничего не нашла подходящего, сама буду искать дальше, но если это не очень сложно реализуемо, буду Вам очень-очень признательна за подсказку)))
Ваш плагин просто находка и комментарии к коду многое поясняют и, конечно, хочется еще больше и лучше, и вот очень хочется такой "бантик" к вашему чудесному плагину добавить )))
Гость 11.12.2016 14:19
Всё идеально, но как вернуть значение общей суммы на главную страницу - вот вопрос, сам пробовал, не получается
Гость 22.12.2016 06:14
...."Подскажите, пожалуйста, как можно отобразить на странице-каталоге товаров, что товар уже добавлен в корзину. Мне нужно сделать большой каталог информационных товаров и без такой подсказки в нем очень сложно ориентироваться."


if (cartData.hasOwnProperty(itemData.id)) {
//cartData[itemData.id].count++;
alert( "Товар в корзине" );
} else {
itemData.count = 1;
cartData[itemData.id] = itemData;
}
Гость 23.12.2016 01:07
Может кому пригодится


printOrder: function (){
var contents = $(this).closest('.jqcart-checkout').prop('outerHTML');
if(!contents) {
return false;
};
var d = new Date();
var curDate = ('0' + d.getDate()).slice(-2) + '-' + ('0' + (d.getMonth() + 1)).slice(-2) + '-' + d.getFullYear() + ' ' + ('0' + d.getHours()).slice(-2) + ':' + ('0' + d.getMinutes()).slice(-2) + ':' + ('0' + d.getSeconds()).slice(-2);

var frame1 = $('<iframe />');
frame1[0].name = "frame1";
frame1.css({ "position": "absolute", "top": "-1000000px" });
$("body").append(frame1);
var frameDoc = frame1[0].contentWindow ? frame1[0].contentWindow : frame1[0].contentDocument.document ? frame1[0].contentDocument.document : frame1[0].contentDocument;
frameDoc.document.open();
//Create a new HTML document.
frameDoc.document.write('<html><head><title>Заказ ' + curDate + '</title>');
frameDoc.document.write('</head><body>');
//Append the external CSS file.
frameDoc.document.write('<link href="css/jqcart.css" rel="stylesheet" type="text/css" />');
//Append the DIV contents.
frameDoc.document.write(contents);
frameDoc.document.write('</body></html>');
frameDoc.document.close();
setTimeout(function () {
window.frames["frame1"].focus();
window.frames["frame1"].print();
frame1.remove();
}, 500);
},


ну и в css добавить
.....
@media print {
* {
margin: 0;
padding: 0;
}
.jqcart-table-wrapper {
height: auto;
padding: 0 5px;
}
........
Гость 23.12.2016 08:48
Может кому пригодится


А куда эту печать вставить - растолкуйте чайнику.
спасибо.
Гость 23.12.2016 20:31
не портим архитектуру и добавляем в корзину data-price="100500"

//itemData.count = 1;
var key;
for (key in cartData, this) {
if (cartData.hasOwnProperty(key)) {
itemData.count = (cartData[key]).count
}};
cartData[itemData.id] = itemData;
Гость 23.12.2016 20:37
извините data-count="100500"
Гость 24.12.2016 17:25
Гость 22.12.2016 06:14
...."Подскажите, пожалуйста, как можно отобразить на странице-каталоге товаров, что товар уже добавлен в корзину. Мне нужно сделать большой каталог информационных товаров и без такой подсказки в нем очень сложно ориентироваться."


if (cartData.hasOwnProperty(itemData.id)) {
//cartData[itemData.id].count++;
alert( "Товар в корзине" );
} else {
itemData.count = 1;


Спасибо, но это не то. Браузерам не нравится часто всплывающие окна (вызов alert), да и пользователям тоже напрягает.
Мне хотелось добавить значок около названия товара, что он добавлен в корзину.
Условно, задается в css некий класс .plusproduct со свойствами display:none сontent:"Товар добавлен в корзину". На странице каталога div c этим классом располагается рядом с названием продукта, но не виден пользователю. Когда пользователь кликает на кнопку "добавить в корзину", то этот div.plusproduct становится видим - и появляется и скрытый текст "Товар добавлен в корзину".
Вот вопрос в том, как в javascript оформить это событие.
Гость 24.12.2016 20:38
if (cartData.hasOwnProperty(itemData.id)) {
//cartData[itemData.id].count++;
//-------------------------------------
swal({ title: "Внимание!", text: "Товар в корзине. Откройте корзину для редактирования"} );
document.getElementById("korzina_no_put_" + itemData.id).style.display='none';
document.getElementById("korzina_in_put_" + itemData.id).style.display='block';

...................


ну и далее где init: function(o) {
Где delFromCart: function() {
где actions.openCart();
Гость 24.12.2016 23:22
За swal тоже спасибо, но мне не нужно модальное окно. У меня вопрос в более сложном варианте - чтобы на странице каталога рядом с продуктом появлялась надпись "товар добавлен в корзину" после того как пользователь кликнул на кнопку "добавить в корзину".
Гость 24.12.2016 23:24
+ и в идеале, если еще и при очистке корзины эти бы надписи удалялись, то вообще сказка бы получилась )))
Гость 24.12.2016 23:43
добовляем

if (cartData.hasOwnProperty(itemData.id)) {
//cartData[itemData.id].count++;
//-------------------------------------
document.getElementById("korzina_no_put_" + itemData.id).style.display='none';
document.getElementById("korzina_in_put_" + itemData.id).style.display='block';
//-------------------------------------
var cntOutput = $('.jqcart-total-cnt');
cntOutput.text(+cntOutput.text());
return false;
} else {

itemData.count = 1;
cartData[itemData.id] = itemData;
}
actions.setStorage(cartData);
actions.changeTotalCnt(1);
label.show();
if(opts.openByAdding) {
actions.openCart();
}
document.getElementById("korzina_no_put_" + itemData.id).style.display='none';
document.getElementById("korzina_in_put_" + itemData.id).style.display='block';
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];
//#-----------------------------------
document.getElementById("korzina_in_put_" + itemId).style.display='none';
document.getElementById("korzina_no_put_" + itemId).style.display='block';
//#----------------------------------
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) {
document.getElementById("korzina_no_put_" + cartData[key].id).style.display='none';
document.getElementById("korzina_in_put_" + cartData[key].id).style.display='block';
if (cartData.hasOwnProperty(key)) {
totalCnt += cartData[key].count;
}
}
visibleLabel = true;
}

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

так понятно
Гость 25.12.2016 00:41
так понятно

Что-то туплю ((( после правок скрипт перестал работать. Попробовала по-разному внести новые строки кода, но тщетно. Если есть файл со скриптом и страницей продуктов, буду крайне признательна за образец ))
Гость 25.12.2016 00:47
<div class="item_box">
<span id="korzina_no_put_1"><i style="cursor:pointer; color: gray; font-size: 24px;" class="fa fa-cart-plus"></i></span>
<span id="korzina_in_put_1" style="display:none"><i style="cursor:pointer; color: gray; font-size: 24px;" class="fa fa-cart-arrow-down"></i></span>
<img src="img/samsung.png" alt="">
<h3 class="item_title">Samsung Galaxy S10</h3>
<p>Цена: <span class="item_price">20</span>&#8381</p>
<button class="add_item" data-id="1" data-title="Samsung Galaxy S10" data-price="20" data-img="http://incode.pro/demo/icp_example20/img/samsung.png" data-count="1">Добавить в корзину</button>
</div>
Гость 25.12.2016 02:20
Спасибо за образец, скрипт заработал в части, где korzina_in_put_- все просто шикарно работает )))) Часть с id korzina_on_put_ у меня почему-то не сработала - не добавляется по клику на него продукт в корзину. Завтра посмотрю внимательно, может где опечатку в коде сделала. Спасибо вам большое-пребольшое!
Гость 25.12.2016 15:21
К сожалению с korzina_on_put_ / korzina_in_put_ выяснилось, что это работает только в пределах одной страницы каталога, например на странице kat1 есть 2 продукта c id #1 и #2. Добавляем их в корзину и переходим на следующую страницу каталога kat2, где есть другие 2 продукта с id #3 и #4 - и на этой странице скрипт корзины уже не работает: не выводится div c ярлыкjv корзины, кнопки очистки, открытия корзины и добавления в корзину не отвечают. Возвращаемся на страницу kat1 и снова скрипт работает ((( Это можно как-то поправить? Пожалуйста )))
Гость 26.12.2016 03:14
так добавьте везде даже и не понял Вашей проблемы и в кат1 и в кат2 и т.д
Гость 26.12.2016 03:45
Здравствуйте.
Спасибо за ваш труд.
Столкнулся с такой проблемой. На одном хостинге у меня корзина отказывается работать, а на другом всё ок. Там где не работает ошибка POST http://mesite.ru/cart/php/handler.php 500 (Internal Server Error)
Что может быть на хостинге (виртуальном) не так? Если на другом (выделенный сервер) работает.
Гость 26.12.2016 14:39
@Гость, Поменял параметры Для версий PHP < 5.4 ошибок нет но письмо не приходит админу на почту. А заказчику приходит. В чём проблема подскажите друзья кто знает?
Гость 26.12.2016 14:59
так добавьте везде даже и не понял Вашей проблемы и в кат1 и в кат2 и т.д

Напишите поподробнее, пожалуйста, вашу мысль. Что добавить везде?
Гость 26.12.2016 15:37
Почему mail.ru отправляет письма в спам? Как то можно это обойти? С гуглом нет таких проблем.
Страница 25 из 33  
Ваш комментарий:
X