Drupal → Модуль Commerce Fast Ajax Add to Cart — ajax кнопка "Добавить в корзину" без кэширования формы

20.05.2014

Как выяснилось, стандартный способ добавления товаров в корзину через #ajax довольно прожорлив. Например при выводе 30 товаров на одной странице, мы получим 60 новых записей в таблице cache_form на один хит. Каждая запись это 10-20 kb данных. В сумме выходит многовато — у меня на рабочем проекте #ajax даёт оверхеда на 200-300 ms к времени загрузки страницы.

Пришлось искать пути решения проблемы. Самым простым показался отказ от #ajax и ручная ajax-ификация кнопки "Добавить в корзину". Родился модуль — Commerce Fast Ajax Add to Cart.

Модуль не гадит в cache_form, но работает по прежнему через ajax-команды.

Модуль умеет выводить диалоговое окно после добавления товара в корзину. Включается на странице admin/commerce/config/commerce-fast-ajax-atc. По умолчанию в окне выводится текст "Товар добавлен в корзину" и три ссылки — В корзину, Оформить заказ, Продолжить покупки. Шаблон можно переопределить и вывести там например вьюху.

Ajax-команды можно альтерить в hook_commerce_fast_ajax_atc_commands_alter(&$commands).

Модуль может работать совместно с ajax атрибутами комерца, но в таком случае кэширование отключить не удастся.

Написанное актуально для
Drupal 7
Похожие записи

Комментарии

Антон
29.05.2014, 21:38

Большое спасибо! Я правильно понимаю, что вы хотите довести модуль до релиза? Или он так и останется в "песочнице"?

Спасибо за модуль, все отлично работает.
Не подскажите каким способом можно обновить блок корзины при помощи AJAX , при добавлении товара в корзину при помощи вашего модуля

модуль самостоятельно обновляет блок корзины

Посмотрел модуль изнутри, корзина должна обновляться, что может мешать этому? Использую page manager, panels, panels everywere. Блок корзины вывел через page manager, в site template

Дмитрий
13.07.2014, 02:16

Подскажите пожалуйста, как включить данный модуль лишь для какого-то одного типа товара?

в hook_form_FORM_ID_alter удалите у кнопки класс use-ajax-submit

Дмитрий
17.09.2014, 07:03

глючит! в товаре с атрибутами если нажать сначала "добавить в корзину", а потом выбрать какой нибудь из атрибутов, то товар так же автоматически добавляется, как если бы я еще раз нажал на добавить в корзину!

написано же "Модуль не будет работать с формами, в которых есть commerce атрибуты"

Дмитрий
17.09.2014, 07:20

Да, действительно. Невнимательно читал. i'm sorry!
А решение данной проблемы где нибудь есть?

Спасибо, отлично все работает. Но не подскажешь как сделать чтобы выводилось обычное системное сообщение вместо модульного confirmation dialog? Буду оч признателен, спасибо.

Ajax-команды можно альтерить в hook_commerce_fast_ajax_atc_commands_alter(&$commands).

Роман
15.01.2015, 15:21

Добрый день. Понравилась идея, но почему модуль нельзя скачать с друпал.орг?

Расим
20.02.2015, 12:53

Использовал для страницы представления фасеты Search API, т.к. стандартный раскрытый фильтр невозможно разделить на разные блоки. При изменении фильтра, как и у Станислава, перестает работать ajax добавление в корзину в виду изменения у формы "action". Помогло добавления кода в commerce_fast_ajax_atc_form_commerce_cart_add_to_cart_form_alter:

$view = views_get_current_view();
  $path = $view->display['page']->display_options['path'];
  $form['#action'] = $path;
Станислав
20.02.2015, 13:05

Расим, есть модуль для разделения раскрытых фильтров на несколько блоков.
MEFIBS - More exposed forms in blocks
Хоть и dev версия, но вроде багов у себя не заметил при ее использовании

Расим
20.02.2015, 23:28

Подправил предыдущий код

if (isset($_SERVER['HTTP_X_REQUESTED_WITH'])
        && !empty($_SERVER['HTTP_X_REQUESTED_WITH'])
        && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
  $path = $_SERVER['HTTP_REFERER']; 
  $form['#action'] = $path;
  };
Гость
28.02.2015, 19:25

Если несложно, расскажите пожалуйста про этот момент:

// Remove cart block id from drupal_html_id() static cache
 $drupal_html_ids = &drupal_static('drupal_html_id');
 unset($drupal_html_ids['block-commerce-cart-cart']);

Спасибо за статью.

Спасибо за модуль, работает хорошо, но вот по поводу "не гадит в cache_form" - что-то не сильно помогло...

После очистки таблица через некоторое время загаживается до нескольких тысяч записей, пример одной записи: http://pastebin.com/UZwywATk

Пример страницы на которой есть кнопка: http://caramba-shop.ru/product/predlozhenie

Скажите пожалуйста, что-то не так в настройках или все же от загаживания cache_form избавиться полностью не получится?

цитата:

Модуль не будет работать с формами, в которых есть commerce атрибуты.

Всмысле не будет работать? Совсем не должен работать или не решит проблему с кешем?

У меня вроде как вполне работает он на сайте caramba-shop.ru - добавляет правильные товары в корзину через AJAX, жалоб от клиентов вроде бы не было. Проблема пока только с cache_form замечена.

в смысле не будет выполнять своих основных обязанностей — не засорять cache_form

И ещё уточнение: что имеется в виду под атрибутами?

Модуль Commerce Product Attributes у меня не установлен, включены только вот такие модули:
Commerce
Commerce ad hoc payment
Commerce Custom Order Status
Commerce Fast Ajax Add to Cart
Commerce Price Decimals for All
Commerce Price Decimals Formatter
Commerce Shipping RussianPost
Commerce UI

И может тогда подскажете, что ещё можно допилить в модуле, чтобы он на моем сайте работал не засоряя cache_form? Ну или хотя бы с какого места начать копать...

Александр
10.01.2016, 14:48

А как можно обновить div-блок который я вручную вывожу в page.tpl

Например я вывожу в page.tpl

Товаров в корзине: <?=$cart_quantity?>

Мне нужно обновить блок с идентификатором custom-cart. Чем можно заменить ajax_command_replace?

Добрый день. Спасибо за модуль, но обнаружилась проблема. Вы пишите, что модуль не будет работать с атрибутами. У меня используется модуль https://www.drupal.org/project/commerce_option. С ним работает модуль, если выбрать опцию, а вот если поле для выбора опции обязательное, но пользователь ничего не указал, то вылазит ajax-ошибка. Подскажите, как её избежать?

Григорий
26.08.2016, 11:53

Добрый день. Подскажите почему то не добавляется в корзину через AJAX, идет обычная перезагрузка страницы. Хотя в button есть class="use-fast-ajax-submit btn btn-default form-submit"

В чем может быть проблема?

Гость
11.10.2016, 15:22

Проблема, возможно схожая с предыдущим комментарием. При использовании Infinite Scroll, а также ajax_facets, кнопка перестает добавлять в корзину

Александр
20.02.2017, 11:46

Спасибо полезно, только желательно проверить перед обновлением блока, что модуль блок включен module_enable ( array('block')

Добавить бы ещё "полет в корзину" было бы замечательно. Сейчас не очень наглядно, что в корзину что-то добавляется, если нет PopUP-а

Гость
10.11.2017, 12:50

Модуль отличный! Спасибо за проделанную работу
Использую его, так как остальные способы аяксификации кнопки добавления в корзину значительно увеличивают form_cache...

Но есть одно НО, в моем случае...

Периодически (очень редко, но бывает) выскакивает такая ерунда
https://cdn1.savepice.ru/uploads/2017/11/10/d9207edda53892234ed85c40ec8…

В коносли и журнале никаких ошибок...

Когда такое происходит, в ответе возвращается не Json как положено а вот что:
https://cdn1.savepice.ru/uploads/2017/11/10/12ec071fac7f5fd434fb349f1da…

И заголовок ответа отличается:
https://cdn1.savepice.ru/uploads/2017/11/10/ec3c37c95936a846805936c69e4…

Чем может быть вызвано такое поведение?
Два дня различных поисков ни к чему не привели...

Гость
10.11.2017, 12:53

Для пробы можно потыкать в блоке с табами ХИТЫ, НОВИНКИ, АКЦИИ...
По адресу http://sport.segaweb.ru

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

У вас товары рандомно выводятся, а для работы drupal форм, форма после сабмита должна быть на странице, потому что в cache_form ничего нет.

Гость
10.11.2017, 13:18

Точно! В этих вьюсах товары рандомные... Но в момем случае по другому не получается. Что можно предпринять? Посоветуете? Спасибо заранее )

в hook_form_alter пропишите #action формы на страницу, где точна есть эта форма, например на карточку товара: '#action' => url('node/' . $product_display_nid)

Гость
10.11.2017, 17:49

Огромное спасибо!
Я уже что только не перепробовал... Отключал модули, ковырял сервер ) А тут так все просто )

Сергей
16.11.2017, 14:00

Привет. Возникла проблема: вывожу кнопку и форму добавления товара в своем модуле.

 $line_item = commerce_line_item_new($product->type, $order_id = 0);
        $line_item->data['context']['product_ids'] = array($product->product_id);
        $line_item->quantity = 1;

        $form_id = commerce_cart_add_to_cart_form_id(array($product->product_id), 1, false);
        $render_addtocart_form = render(drupal_get_form($form_id, $line_item));

Кнопка и форма выводится , но при нажатии на кнопку добавления в корзину не всплывает диалоговое окно подтверждения.
Функция commerce_fast_ajax_atc_add_to_cart_form_submit срабатывает так же, как и при нажатии в карточке pdoruct_display или в views с товарами. Классы , action формы commerce-add-to-cart проверил, нигде ничего не потеряно.
Непонятно, в какую сторону копать.

Сергей
16.11.2017, 14:02

Вдогонку: сами товары после перезагрузки страницы в корзине появляются, не срабатывает только вывод диалога.

Копать как обычно в сторону пошаговой отладки.

Сергей
16.11.2017, 14:09

да сломался уже на отладке(( не получается. думал, может необходимо еще как то хитро альтерить форму добавления в корзину.

Сергей
16.11.2017, 14:11

может у вас есть пример программного вывода кнопки Купить, чтобы срабатывало диалоговое окно подтверждения?

Сергей
18.06.2018, 16:40

Подскажите кто-нибудь, пожалуйста. Такая ситуация:

Есть блок вьюса в котором выводятся четыре товара с формой корзины. Так вот если я вывожу блок стандартно в регионы все ок, ajax кнопка добавления товара в корзину прекрасно работает.

Мне же нужно программно выводить этот вьюс либо блок в tpl шаблоне (пробовал оба сценария). При такой ситуации ajax сабмит не хочет работать ни в какую. Происходит перезагрузка страницы, товар добавляется в корзину. При чем все нужные библиотеки и скрипты на страницу выгружаются, класс ajax-processed из модуля добавляется на все кнопки...

В каком направлении копать проблему, подскажите, пожалуйста...

Сергей
18.06.2018, 16:43

ps. Проверял построчно commerce_fast_ajax_atc.js, все работает в нормальном режиме...Смущает Drupal.ajax[base] + программный вывод блока или вьюса в шаблоне... Может быть в этом проблема?

Сергей
18.06.2018, 16:53

Смотрел, ошибок нет совершенно никаких )

Сергей
18.06.2018, 16:56

При чем на этой же странице есть еще кнопка добавить в корзину, самого товара и она прекрасно работает. Заковыра именно с программным выводом блока в шаблоне. Почему то теряется ajax функционал

Дебажьте js, выясняйте почему не навешивается ajax

Гость
11.07.2018, 12:41

Добрый день, а как скачать Ваш модуль Commerce Fast Ajax Add to Cart ?
Заранее спасибо за овтет.

Почему то иногда в логах возникала ошибка:

Notice: Undefined index: entity_id in commerce_fast_ajax_atc_form_commerce_cart_add_to_cart_form_alter() (line 43 of /sites/all/modules/commerce_fast_ajax_add_to_cart/commerce_fast_ajax_atc.module).

Добавил в 42-ю строку модуля проверку на наличие entity_id
if (strpos($form['#action'], url('views/ajax')) !== FALSE && !empty($form_state['context']['entity_id']))

Гость
18.02.2019, 12:40

Приветствую.

Возникает ошибка:

Notice: Undefined index: entity_id in commerce_fast_ajax_atc_form_commerce_cart_add_to_cart_form_alter() (line 43 of /sites/all/modules/commerce_fast_ajax_add_to_cart/commerce_fast_ajax_atc.module).

Так же при ajax фильтрации, кнопка переставала работать пока не обновишь страницу.

Решил проблему так:

 
 if(strpos($form['#action'], url('views/ajax')) !== FALSE) {
    // Было так
    //$form['#action'] = url('node/' . $form_state['context']['entity_id']);    
    // Стало так
    $form['#action'] = url(drupal_get_path_alias());    
  }

Кнопка стала хорошо работать при ajax фильтрах в views.

Гость
16.04.2019, 10:48

Добрый день, спасибо за отличный модуль. Есть такой вопрос, реализую модуль для одного товара с разными размерами. Вывожу отдельную кнопку, при нажатие на которую, нажимаются все кнопки добавления одновременно. Бывает возникает проблеема того что не все товары падают в корзину. в чем может быть проблема? Заранее спасибо за ответ, я в этом деле новичок, не судите строго если задаю глупый вопрос.

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