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

Страница 22 из 33  
polkovnikov 12.02.2017 08:32
Ребят всем привет. Никто случайно не делал ручной ввод количества товара, уже было что то похожее,но я так и не разобрался. Просто человек вводит допустим 5 штук и нажимает добавить в корзину, или в корзине имелась возможность редактирования.
infinitymd 13.02.2017 12:20
@Гость, спасибо, но за это у меня отвечает электронная коммерция от яндекса. Ее очень просто оказалось подключить к этой корзине...
@polkovnikov, а разве в корзине в исходном коде редактирование кол-ва запрещено?
polkovnikov 16.02.2017 10:39
Я имел ввиду, чтобы отказаться от редактирования с помощью +-, а сделать поле для ввода числа.
infinitymd 16.02.2017 14:26
@polkovnikov, в корзине можно число в поле между - и + ввести...
Гость 20.02.2017 01:56
@polkovnikov,
без проблем,
var kolvo = document.getElementById('kolvo' + itemData.id).value;
itemData.count == kolvo;


@infinitymd,
за тебя я... коммерция чистит корзину от не нужных покупателей которые положили товар в корзину и забили - это круто...
infinitymd 20.02.2017 09:15
@Гость, не совсем тебя понял...
Гость 25.03.2017 06:37
Всем привет, пытаюсь внедрить полет картинки в корзину, просто обновление количества не видно для тугого пользователя если товаров много, у кого есть идеи?

Вот накопал это, но пока грабли не заточил.
где #target сама картинка
и #polet это ДИВ куда летит картинка (у меня это сама корзина)

addToCart: function(e)
{
e.preventDefault();
itemData = $(this).data();
var stepCnt = $(this).data('step') || 1;
if(typeof itemData.id === 'undefined')
{
console.log('Отсутствует ID товара');
return false;
}
cartData = actions.getStorage() || {};
if (cartData.hasOwnProperty(itemData.id))
{
cartData[itemData.id].count += stepCnt;
}
else
{
itemData.count = stepCnt;
cartData[itemData.id] = itemData;
}
cartData[itemData.id].step = stepCnt;
actions.setStorage(cartData);
actions.changeTotalCnt(stepCnt);
actions.InPreviewLabel();
//НАЧАЛО ПОЛЕТА
$("#target");
actions.clone();
actions.css({'position' : 'absolute','z-index' : '100'});
actions.appendTo("#polet");
actions.animate({opacity: 0.5, width: 50, height: 50}, 400, function(){$(this).remove();});
//КОНЕЦ ПОЛЕТА
return false;
},

Правильно все али нет, подскажите пжлста)
Гость 27.03.2017 05:55
Добрый день.
Подскажите, как сделать минимальный заказ от 2 шт.?
infinitymd 27.03.2017 15:03
Всем привет, пытаюсь внедрить полет картинки в корзину, просто обновление количества не видно для тугого пользователя если товаров много, у кого есть идеи?

я сделал так:
JS
addToCart: function(e) 
	{
		e.preventDefault();
		itemData = $(this).data();
		var stepCnt = $(this).data('step') || 1;
		if(typeof itemData.id === 'undefined')
		{
			console.log('Отсутствует ID товара');
			return false;
		}
		cartData = actions.getStorage() || {};
		if (cartData.hasOwnProperty(itemData.id)) 
		{
			cartData[itemData.id].count += stepCnt;
		}
		else
		{
			itemData.count = stepCnt;
			cartData[itemData.id] = itemData;
		}
	cartData[itemData.id].step = stepCnt;
	actions.setStorage(cartData);
	actions.changeTotalCnt(stepCnt);
	actions.metrica();
        //Всплывающее сообщение у корзины
	actions.InPreviewLabel();
	 $('<div class="jqcart-cart-alert">Товар добавлен в корзину</div>').insertAfter('.label-place-cart').delay(3000).fadeOut();
	return false;
    },

CSS
.jqcart-cart-alert {
    border: 2px solid #C11A11;
    background-color: #C11A11;
    border-radius: 5px;
    height: 35px;
    width: 130px;
    padding: 5px;
    position: fixed;
    top: 100px;
    right: 20px;
    text-align: center;
    color: #fff;
    z-index: 9999999;
infinitymd 27.03.2017 15:09
Добрый день.
Подскажите, как сделать минимальный заказ от 2 шт.?

<button class="add_item" data-id="..." data-link="..." data-title="..." data-price="..." data-code="..." data-img="..." data-step="Тут поставить минимальное кол-во для заказа" onclick="...">Купить</button>

Код js без корзины:
Показать код
Nygaard 28.03.2017 23:37
Здравствуйте, к вопросу про покупку более чем от двух товаров, сам скрипт внедрил, все собственно, работает,

<?php
parse_str($_POST['orderlist'], $orderlist);
parse_str($_POST['userdata'], $userdata);
$total_sum = 0;
foreach($orderlist as $id => $item_data) {
	$total_sum += (float)$item_data['count'] * (float)$item_data['price'];
	$tbl .= '
	<tr>
		<td style="border: 1px solid #333333; padding: 5px;">'.$item_data['id'].'</td>
		<td style="border: 1px solid #333333;"><img src="'.$item_data['img'].'" alt="" style="max-width: 64px; max-height: 64px;"></td>
		<td style="border: 1px solid #333333; padding: 5px;">'.$item_data['title'].'</td>
		<td style="border: 1px solid #333333; padding: 5px;">'.$item_data['price'].'</td>
		<td style="border: 1px solid #333333; padding: 5px;">'.$item_data['count'].'</td>
	</tr>';
}
require "db.php";
$addf = R::dispense('addr');
$addf->name = $userdata['user_name'];
$addf->phone =$userdata['user_phone'];
$addf->Email =$userdata['user_mail'];
$addf->adress =$userdata['user_address'];
$addf->comment =$userdata['user_comment'];
$addf->count =...
$id = R::store($addf);
 ?>

Вопрос в том, могу ли я реализовать добавление информации о заказе в базу, понимаю, что вопрос ламерский, но все же буду признателен если мне скажут можно ли как-то занести информаию о товаре в базу, если куплено больше двух штук. Там где многоточие - если куплено 3 разных товара, туда необходимо ввести их кол-во, например 2,7,3. Я думаю, что возможно это сделать, но немного не могу понять как именно
Nygaard 29.03.2017 02:01
или же сделать иначе и добавить цикличиское добавление в бд, когда пользователь закупает несколько товаров, то есть, для каждой строки в базе указывается один пользователь, и его информация, которая дублируется, на следующие строки, если тот покупает три товара, то есть
пользователь|товар |кол-во|...
Иван Иванов |товар1 | 5 |...
Иван Иванов |товар2 | 3 |...
Иван Иванов |товар3 | 2 |...
Я буду очень-очень признателен за помощь, т.к. что я уже только не пытался сделать - толку ноль..
Nygaard 29.03.2017 02:10
Прошу прощения за спам, ошибка была тупее меня самого, т.к. в цикл я еще засовывал и подключение к бд. Если что, вот рабочий пхпшный скрипт добавление товара в Бд, использую ОРМ, readbeanPHP.
опять таки, здесь лишь только пример того, как все заполняется

<?php
require "db.php";
parse_str($_POST['orderlist'], $orderlist);
parse_str($_POST['userdata'], $userdata);
$total_sum = 0;
foreach($orderlist as $id => $item_data) {
	$total_sum += (float)$item_data['count'] * (float)$item_data['price'];
$addf = R::dispense('addr');
$addf->name = $userdata['user_name'];
$addf->phone =$userdata['user_phone'];
$addf->Email =$userdata['user_mail'];
$addf->adress =$userdata['user_address'];
$addf->comment =$userdata['user_comment'];
$addf->count =$item_data['count'];
$id = R::store($addf);
	$tbl .= '
	<tr>
		<td style="border: 1px solid #333333; padding: 5px;">'.$item_data['id'].'</td>
		<td style="border: 1px solid #333333;"><img src="'.$item_data['img'].'" alt="" style="max-width: 64px; max-height: 64px;"></td>
		<td style="border: 1px solid #333333; padding: 5px;">'.$item_data['title'].'</td>
		<td style="border: 1px solid #333333; padding: 5px;">'.$item_data['price'].'</td>
		<td style="border: 1px solid #333333; padding: 5px;">'.$item_data['count'].'</td>
	</tr>';
}
 ?>
infinitymd 29.03.2017 10:13
А почему бы не добавлять в базу каждый заказ после его совершения прямо из handler.php?
Nygaard 29.03.2017 22:42
"А почему бы не добавлять в базу каждый заказ после его совершения прямо из handler.php?"
Вроде именно так у меня все и работает. Я не могу даже выразить насколько я вам признателен за вашу корзину. лишь тема диплома, еще учусь. А этот скрипт это и был непосредственно Handler, просто на данный момент я его упростил, что ли, оставил лишь самое необходимое, хоть и остальное, я готов поспорить, мне так же потребуется позже
Nygaard 30.03.2017 01:32
И еще, есть у меня один вопрос, ответ на который я никак не могу найти.
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8"/>
<meta name="generator" content="2015.2.0.352"/>
<link href="css/jqcart.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" type="text/css" href="css/site_global.css?crc=3916556066"/>
<link rel="stylesheet" type="text/css" href="css/index.css?crc=30110382" id="pagesheet"/>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="js/jqcart.js"></script>
<script src="js/jquery-1.11.3.min.js"></script>
<script src="js/jqcart.min.js"></script> <script> $(function() {
'use strict';
// инициализация плагина
$.jqCart({
buttons: '.add_item',
handler: 'handler.php',
cartLabel: '.label-place',
visibleLabel: true,
openByAdding: false,
currency: '&dollar;'
}); // Пример с дополнительными методами
$('#open').click(function() {
$.jqCart('openCart'); // открыть корзину
});
$('#clear').click(function() {
$.jqCart('clearCart'); // очистить корзину
});
});
</script> <script>
$(document).ready(function() {
//Скрыть PopUp при загрузке страницы
PopUpshow();
});
//Функция отображения PopUp
function PopUpShow() {
$("#popup1").fadeToggle("slow");
}
//Функция скрытия PopUp
function PopUpHide() {
$("#popup1").hide();
} </script> </head>

Вот мой хэдэр, в нем все интуитивно понятно, как по мне.
Подключаются библиотеки, хоть и две предыдущих версий подключать бесполезно, но просто для наглядности, что бы все было так же как и в примере, дальше идет скрипт подключающий основной джес. И перед этим линка к нему
"<script src="js/jqcart.js"></script>
<script src="js/jquery-1.11.3.min.js"></script>
<script src="js/jqcart.min.js"></script>

<script>
$(function(){
..."
Суть в том, что строка является соурсом на файл со скриптом, если я как-либо видоизменяю скрипт, могу его вообще удалить и оставить пустой файл - коризна так же идеально работает и будто бы ничего не случилось. Но если я указываю неверный путь к файлу или удаляю его вообще "<script src="js/jqcart.js"></script>" - даже сам лэйбл корзины перестает отображаться. Как это вообще возможно я ума не приложу, но вопрос в том, как видоизменить корзину, поднастроить под себя. Просто не понимаю и прошу совета, заранее спасибо
Nygaard 30.03.2017 01:35
Приношу извинения
при монипуляциями с этой линкой лишь что-то меняется
<script src="js/jqcart.min.js"></script>
Nygaard 30.03.2017 02:04
Что самое ироничное - даже если полностью вырезать эти два файла - все идеально работает. Но если убрать к ним линки, ко второму из них - нет
infinitymd 30.03.2017 09:50
jcart.min.js это сжатый вид файла jcart.js из них должен остаться только один :)
По поводу вырезания начинки файлов - все работает скорее всего из-за кеширования. Попробуйте после вырезания очистить кеш браузера - корзина сломается...
Гость 07.04.2017 21:00
Жму отправить заказ и ничего не происходит. Просто скачал демку, закинул на хостинг папку и открыл по ссылке. Проверил, не работает отправка
Гость 07.04.2017 22:33
Жму отправить заказ и ничего не происходит. Просто скачал демку, закинул на хостинг папку и открыл по ссылке. Проверил, не работает отправка

Может версия php на хостинге более ранняя, тогда нужно раскомментировать строку для php более старой версии, ну и прописать адрес получателя в настройках скрипта.
Гость 07.04.2017 22:42
@Гость, Да, версия php более ранняя, перенес корзину на другой сервер-работает. Подскажете, как раскомментировать, что прописать? И там есть еще строка отправки скрытой копии письма админу сайта, как отменить это? Удаление строки приводит скрипт в нерабочее состояние. Спасибо
infinitymd 10.04.2017 12:17
Вот так:
<?php
parse_str($_POST['orderlist'], $orderlist);
parse_str($_POST['userdata'], $userdata);
/*
$orderlist - массив со списком заказа
$userdata - данные заказчика
*/
// При желании, можно посмотреть полученные данные, записав их в файл:
// file_put_contents('cart_data_log.txt', var_export($orderlist, 1) . "\r\n");
// file_put_contents('cart_data_log.txt', var_export($userdata, 1), FILE_APPEND);
// Заголовок письма
$subject = 'Заказ от '.date('d.m.Y').'г.';
// ваш Email
$admin_mail = 'admin@best-shop.piva.net';
// Email заказчика (как fallback - ваш же Email)
$to = !empty($userdata['user_mail']) ? $userdata['user_mail'] : $admin_mail;
// Формируем таблицу с заказанными товарами
$tbl = '<table style="width: 100%; border-collapse: collapse;">
	<tr>
		<th style="width: 1%; border: 1px solid #333333; padding: 5px;">ID</th>
		<th style="width: 1%; border: 1px solid #333333; padding: 5px;"></th>
		<th style="border: 1px solid #333333; padding: 5px;">Наименование</th>
		<th style="border: 1px solid #333333; padding: 5px;">Цена</th>
		<th style="border: 1px solid #333333; padding: 5px;">Кол-во</th>
	</tr>';
$total_sum = 0;
foreach($orderlist as $id => $item_data) {
	$total_sum += (float)$item_data['count'] * (float)$item_data['price'];
	$tbl .= '
	<tr>
		<td style="border: 1px solid #333333; padding: 5px;">'.$item_data['id'].'</td>
		<td style="border: 1px solid #333333;"><img src="'.$item_data['img'].'" alt="" style="max-width: 64px; max-height: 64px;"></td>
		<td style="border: 1px solid #333333; padding: 5px;">'.$item_data['title'].'</td>
		<td style="border: 1px solid #333333; padding: 5px;">'.$item_data['price'].'</td>
		<td style="border: 1px solid #333333; padding: 5px;">'.$item_data['count'].'</td>
	</tr>';
}
$tbl .= '<tr>
		<td  style="border: 1px solid #333333; padding: 5px;" colspan="3">Итого:</td>
		<td style="border: 1px solid #333333; padding: 5px;"><b>'.$total_sum.'</b></td>
		<td style="border: 1px solid #333333;">&nbsp;</td>
	</tr>
</table>';
// Тело письма
$body = '
<html>
<head>
  <title>'.$subject.'</title>
</head>
<body>
  <p>Информация о заказчике:</p>
	<ul>
		<li><b>Ф.И.О.:</b> '.$userdata['user_name'].'</li>
		<li><b>Тел.:</b> '.$userdata['user_phone'].'</li>
		<li><b>Email:</b> '.$userdata['user_mail'].'</li>
		<li><b>Адрес:</b> '.$userdata['user_address'].'</li>
		<li><b>Комментарий:</b> '.$userdata['user_comment'].'</li>
	</ul>
	<p>Информация о заказае:</p>
  '.$tbl.'
	<p>Письмо создано автоматически. Пожалуйста, не отвечайте на него, т.к. все ушли на пляж!</p>
</body>
</html>';
// Заголовки
$headers   = []; // или $headers = array() для версии ниже 5.4
$headers[] = 'MIME-Version: 1.0'; // Обязательный заголовок
$headers[] = 'Content-type: text/html; charset=utf-8'; // Обязательный заголовок. Кодировку изменить при необходимости
$headers[] = 'From: Best Shop <noreply@best-shop.piva.net>'; // От кого
#$headers[] = 'Bcc: Admin <'.$admin_mail.'>'; // скрытая копия админу сайта, т.е. вам
$headers[] = 'X-Mailer: PHP/'.phpversion();
// Отправка
$send_ok = mail($to, $subject, $body, implode("\r\n", $headers));
// Ответ на запрос
/*
$response = [
	'errors' => !$send_ok,
	'message' => $send_ok ? 'Заказ принят в обработку!' : 'Хьюстон! У нас проблемы!'
];
*/
// ! Для версий PHP < 5.4 использовать традиционный синтаксис инициализации массивов:
$response = array (
	'errors' => !$send_ok,
	'message' => $send_ok ? 'Заказ принят в обработку!' : 'Хьюстон! У нас проблемы!'
);
exit( json_encode($response) );
Гость 11.04.2017 20:09
Спасибо, но не работает файл вообще после изменений этих.
Гость 11.04.2017 23:10
Подскажите, как сделать название товара в корзине ссылкой, чтобы из корзины можно было по ней перейти на страницу товара? И можно ли для каждого значения в ячейке корзины создать свой стиль в css?
Страница 22 из 33  
Ваш комментарий:
X