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

Страница 21 из 33  
Гость 12.04.2017 10:50
Здравствуйте, очень удобный плагин! но есть два момента, которые мне нужно подправить.

Как мне поменять текст "Оформить заказ" в том месте где выводится количество товаров в корзине? Вот эту вот строку:"\u041e\u0444\u043e\u0440\u043c\u0438\u0442\u044c \u0437\u0430\u043a".

И второй момент: мне нужно количество товаров в корзине выводить в двух местах ( в мобильной и обычной версии в разных местах) при попытке 2 раза выводить неправильно считается общее количество... Подскажите пожалуйста.
Гость 12.04.2017 12:40
Я тоже думал как поменять надпись. Просто пиши русскими буквами что тебе нужно и сохраняй, а эта строка закодированная фраза "Оформить заказ"
infinitymd 12.04.2017 17:45
@Гость, так попробуйте
Показать код
infinitymd 12.04.2017 17:49
@Гость,
html

<button class="add_item" 
data-id="id" 
data-link="ссылка на товар" 
data-title="Название" 
data-price="Цена" 
data-code="артикул" 
data-img="картинка" 
data-step="Шаг">
Купить
</button>

js

orderPreview += '<div><a href="'+ cartData[key].link + '">' + cartData[key].title + '</a></div>';
infinitymd 12.04.2017 17:54
@Гость,
И второй момент: мне нужно количество товаров в корзине выводить в двух местах ( в мобильной и обычной версии в разных местах) при попытке 2 раза выводить неправильно считается общее количество... Подскажите пожалуйста.

Если адаптивный дизайн, то только через css, либо создать 2 файла js для мобильной и обычной версии и там уже располагать ко-во
Гость 14.04.2017 21:42
Здравствуйте!
Может, кто-то делал или знает, как сделать проверку чекбокса в обработчике handler.php

<input name="subscribe" type="checkbox" checked value="Согласен">
<span>Хочу получать рассылку на мою электронную почту</span>

Если правильно поняло, то в обработчик добавляется строка:
<li><b>Рассылка:</b> '.$userdata['subscribe'].'</li>

конструкция проверки, взятая из интернета, не помогла:
$userdata['subscribe'] = '';
if (empty($_POST["subscribe"]))
{
$emailsabcr = "не актуально";
}
elseif (!empty($_POST["subscribe"]) && is_array($_POST["subscribe"]))
{
$userdata['subscribe'] = implode(" ", $_POST["subscribe"]);
}

Если пользователь, согласен, то в письме прилетает "Ежемесячная рассылка: Array". Если не согласен, то просто пусто. Конечно, можно догадаться и запомнить, что Аrray - согласен, путо - не согласен. А хотелось бы, чтобы было сразу видно, что согласен или нет. Плиз, помогите! )))
infinitymd 17.04.2017 10:51
зачем так городить? Для рассылки нужен email, он есть в оформлении заказа. Вам достаточно поставить проверку на чекбокс рассылки.
if (!empty($_POST["subscribe"]))
{
$emailsabcr = "Подписался";
}
Гость 17.04.2017 13:53
@infinitymd, что-то не срабатывает. Также прилетает Array, если согласен на подписку.
fizikas 18.04.2017 10:35
Доброго времени суток! Автору за скрипт большое спасибо!. Скрипт поставил на тестовый ресурс(самописная витрина на Yii) которому для превращения в простенький магазин как раз корзины и не хватало. Возникли некоторые трудности, которые пытался несколько дней побороть сам, многое разобрал, однако видимо знаний пока недостаточно.

Пациент здесь: _http://winner.corner.com.ua/production/shkolnye_rjukzaki_dlja_malchikov_optom (страница категорий, кнопка Купить появляется при хавэрэ на карточке товаров) и
вот пример карточки товара _http://winner.corner.com.ua/production/shkolnye_rjukzaki_dlja_malchikov_optom/rjukzaki_dlja_malchikov_372 (Попытка реализации кроме Купить еще и Купить в 1 клик. Требования: при нажатии Купить, товар добавляется в Корзину, Купить в 1 клик, добавляется в Корзину и корзина открывается)

Скрипт немного перепиливал, но сейчас вернулся к исходному состоянию с небольшими изменениями в дизайне.

Вопросы:
1) Обнаружил баг при отображении количества товаров в Корзине при нажатии кнопки Купить. Если в Корзине уже что-то есть, Например 1 товар, при последующем нажатии получается 12, после этого 1213 и т.п до перезагрузки страницы, когда количество показывает верное. Вычислил, что функция changeTotalCnt при вызове ее из addToCart и delFromCart предварительно конкатенирует содержимое Количества товаров и только потом арифметически добавляет 1 к количеству. Тоесть. Было "1". Потом ГДЕ ТО происходит "1"+"1"="11" и уже в функции +"11"+"1"=12, Вместо 2. А вот что является первопричиной понять не могу? Подскажите где ошибка.

2) Как правильно реализовать Купить в 1 клик? Пробовал 2 способа. Если добавить для этой кнопки кроме класса Добавить в корзину класс с методом Открыть корзину, вначале вызывает Показать корзину и так как товар еще не добавлен - получаем КОрзина пуста.
По другому: Добавлял в кнопку класс и скрипт, чтобы при клике на этом классе openByAdding: false менялось на openByAdding: true. В этом случае КОрзина открывается с удвоенным количеством товара.

3) Можно ли в карточке товара организовать передачу количества товара из input? Подскажите как.
Заранее благодарен за помощь
Гость 19.04.2017 09:55
Подскажите, как в headler.php убрать отправку копии письма админу? Пробовал закомментировать и скрипт перестает работать вообще. Удалять строку пробовал, тот же результат. Как-будто без нее не работает скрипт
Гость 22.04.2017 02:33
@fizikas,
во всем виноват cache.
для полной надежности этого скрипта нужно назначать на кнопку продолжить и на очистку корзины функцию location.reload(); для пользователя это пофиг ну перезагрузилась страница ну и что? а для Вас это сто процентная уверенность в очистке переменных.
wmaker 22.04.2017 14:05
При большом количество товаров, кнопки уезжают вниз и не дают оформить заказ :-) Вертикальный скроллинг не появляется. Как решить эту проблему?
Incode 22.04.2017 15:14
@wmaker, в css на 98-ой строке, раскомментируйте стили для .jqcart-table-wrapper. Высоту установите свою или используйте другие правила. Например, max-height и т.д.
wmaker 22.04.2017 18:04
@Incode, Большое спасибо!
Гость 24.04.2017 16:51
Спасибо, все работает кроме одного момента. Url для data-img прописано верно и в корзине минимизированная версия фотографии отображается, но при отправке на почту в письме нет этой фотки(тоже самое в демо версии вашей). (soaprana.com можете сделать тестовый заказ со своей почтой и посмотреть, если потребуется) Вот ошибка из консоли,

"Refused to load the image 'https://mc.yandex.ua/sync_cookie_image_check?body=1401.ffi4V7NeFyIE62tFTXx%…4nrKz2N4XOdNceHVHhDjMVpx7qGlEZJB%2FydT8ma.RHIzZ4%2FklEeV64FYTWks55pmcG8%3D' because it violates the following Content Security Policy directive: "img-src 'self' data: *.gemius.pl *.tns-counter.ru maps.googleapis.com *.yandex.ru resize.yandex.net resize.rs.yandex.net *.yandex.net *.yandex.ru yadi.sk https://avatars.mds.yandex.net https://avatars.mdst.yandex.net yandex.ua webattach.mail.yandex.net view.atdmt.com ad.adriver.ru comscore.com s1.countby.com bl1.datamind.ru *.doubleclick.net secure-it.imrworldwide.com lamoda25.ru omirussia.ru amch.questionmarket.com jsre.r24-tech.com yandex.dsp.redfog.ru yandex-bidder.rutarget.ru bs.serving-sys.com eu-propulsor.sociomantic.com tns.ru yandex.st yastatic.net".
infinitymd 24.04.2017 17:29
а каким образом прописан путь к картинке "домен можете заменить" (а лучше весь код <button> скиньте)
Гость 24.04.2017 22:08
infinitymd, Вот так записан путь
<a class="add_item btn btn-success" data-id="1" data-title="Fresh Strawberry" data-price="7.35" data-img="http://www.soaprana.com/wp-content/themes/soap/images/img-4.jpg">Add to cart</a>
Гость 25.04.2017 01:14
А как быть, если цена зависит от колличества? Например когда 1 товар стоит 7 долларов, а 2 по 5 за единицу, а больше 2 будет цена 10 + 2 за единицу. iluha0906 - мой скайп, готов заплатить за решение.
Гость 25.04.2017 19:01
Добрый день, в моей постановке задачи, рядом с кнопкой добавить в корзину, есть поле для ввода количества товара. атрибут кнопки data-count="100" не передаёт количество в корзину. Каким образом это реализовать ? и что нужно сделать, что бы кнопка печати заработала ?
Гость 26.04.2017 14:44
Подключил на сайте jquery.inputmask.js . Во всех формах работает маска (по номеру телефона). В модальном окне корзины jqCart - маска не работает. Ломаю голову! Подскажите, пожалуйста, как реализовать.
Incode 26.04.2017 16:17
В модальном окне корзины jqCart - маска не работает.
Элементы модального окна выводятся динамически. Поэтому необходимо инициализировать плагин inputmask каждый раз, после открытия корзины.
Гость 26.04.2017 16:19
Разобрался с jquery.inputmask.js. Прописал
$("#user_phone").inputmask("+7 (999) 999-99-99");
в конце функции openCart: function() после строки
$(modal).appendTo('body').find('.jqcart-checkout').html(cartHtml);
Гость 28.04.2017 17:22
Очень полезная статья и скрипт для корзины. Спасибо вам огромное. Однако проблема вот в чем я совсем новичок и не понимаю язык php. Можете мне помочь а как сделать чтобы заказы присылались на мой gmail или на базу данных.
Гость 03.05.2017 19:19
Хорошая корзина, но у кого-то нажимается кнопка когда заказ оформлен и нужно его отправить?
Гость 04.05.2017 23:34
@Гость,

<?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'];
	$total_count += (float)$item_data['count'];
	$vote=0;
$subject = 'Заказ от '.date('d.m.Y').'г.';
$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->Item_name =$item_data['title'];
$addf->Item_vin =$item_data['id'];
$addf->Item_count =$item_data['count'];
$addf->Item_price=$item_data['price'];
$addf->Items_total_price=$total_sum;
$addf->order_time=$subject;
$addf->already_vote=$vote;
$id = R::store($addf);
 $upload = R::load('forvin',$item_data['id']);
$upload->count-=$item_data['count'];
R::store($upload);
	
}
$addf = R::dispense('addr');
$addf->name = $userdata['user_name'];
$addf->Email =$userdata['user_mail'];
$addf->Item_count =$total_count;
$addf->Items_total_price=$total_sum;
$addf->order_time=$subject;
$id = R::store($addf);
 ?>

Вот тебе тот кусочек. Реализовано криво, плюс ко всему на Рэдбине и там еще много того, что тебе не нужно. При добавлении в базу - в файле Хэндлер.пхп находишь цикл - это не сложно, а в нем уже пишешь запрос на добавдление в базу
Страница 21 из 33  
Ваш комментарий:
X