Drupal → AJAX кнопка "Добавить в корзину" в Drupal Commerce

04.03.2013

Код, позволяющий добавлять товары в корзину с помощью AJAX:

/**
 * Implements hook_form_FORM_ID_alter(): commerce_cart_add_to_cart_form
 */
function modulename_form_commerce_cart_add_to_cart_form_alter(&$form, &$form_state) {
  $form['submit']['#ajax'] = array('callback' => 'modulename_add_to_cart_ajax_callback');
  $form['#submit'][] = 'modulename_add_to_cart_form_submit';
}

/**
 * "Add to cart" button ajax callback.
 */
function modulename_add_to_cart_ajax_callback($form, &$form_state) {
  drupal_get_messages();
  $cart_block = module_invoke('commerce_cart', 'block_view', 'cart');
  return array(
    '#type' => 'ajax',
    '#commands' => array(
      // Возможно придётся изменить селектор, если у вас кастомный шаблон для блока корзины
      ajax_command_html('#block-commerce-cart-cart .content', render($cart_block['content'])),
    ),
  );
}

/**
 * "Add to cart" button submit callback.
 */
function modulename_add_to_cart_form_submit($form, &$form_state){
  $form_state['rebuild'] = TRUE;
}

Код конфликтует с dev версией Commerce Cart Ajax, потому что модуль достаточно кривой.

Добавлено 29.04.2014

Способ подружить ajax кнопки с модулем Views Infinite Scroll:

(function ($) {
  Drupal.behaviors.commerceAjaxCart = {
    attach: function (context, settings) {
      $('.commerce-add-to-cart .form-submit', context).once('ajax', function () {
        var base = this.id;
        Drupal.ajax[base] = new Drupal.ajax(base, this, {
          event: 'mousedown',
          url: Drupal.settings.basePath + 'system/ajax'
        });
      });
    }
  }
})(jQuery);

Добавлено 18.05.2014

Как выяснилось, у способа есть большой недостаток — при добавлении к любому элементу формы свойства #ajax, у формы включается кеширование и при каждом выводе такой формы, создаётся 2 записи в таблице cache_form.

Т.е. если открыть страницу с 20-ю товарами и ajax формой "Добавить в корзину", то в таблицу cache_form добавится 40 новых записей, и эти записи будут добавляться каждую загрузку страницы. Если учесть, что одна запись в кэше весит 10-20 kb, то картина выходит довольно печальная.

Решение здесь.

Обсуждения:

Cache form table saves very large records when forms are displayed in a view
Don't store the full node in the add to cart form state
problem with cache_form table

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

Комментарии

у тебя там целая корзина, а тут только ajax, только хардкор

:) код я незадолго до этого выкладывал, но там тоже больше про блок.

Сергей
18.06.2013, 03:04

Здравствуйте! Не подскажете, по подробней, желательно пошагово как пользоваться вашим модулем?

Наташа
13.08.2013, 19:44

Здравствуйте. Может Вы мне поможете один вопрос решить.
Имеется магазин с товарами. На странице товара форма добавления в корзину.
В качестве атрибутов выводятся размеры товара.
Переделала функцию add_to_cart_form таким образом, чтобы
1. Выводились размеры не только товаров со статусом "активен", но и отключенных товаров.
2. Если покупатель выбирает размер, а товар при этом не активен, появляется кнопочка "Товар не доступен".
И все бы хорошо. Но не могу убить кнопку Добавить в корзину.
Если я пишу что-то такое if (условие){form['submit'] = array(ит.д.)} - то кнопка вообще никак не реагирует.
Если пишу if(условие){form['что угодно']=array(и т.д.)} - то к форме добавляется еще один инпут.
Так как же убрать эту форм сабмит? и почему она так себя ведет

function modulename_form_commerce_cart_add_to_cart_form_alter(&$form) {
  if (условие) {
    $form['submit']['#value'] => t('Product not available');
  }
}

Спас! Все работает. Хотелось бы еще выводить сообщение об успешном добавлении товара в корзину =)

Код может конфликтовать с dev версией Commerce Cart Ajax, потому что модуль достаточно кривой.

В чем заключается кривость ?

Нужно добавить

$form['submit']['#id'] = 'edit-submit--' . $form['product_id']['#value'];

в modulename_form_commerce_cart_add_to_cart_form_alter(), потому-что возникают конфликты на страницах, где есть другие формы, например форма авторизации. У кнопки авторизации такой же id, как у кнопки "Add to cart" (id="edit-submit").

P.S. недавно вышел модуль https://drupal.org/project/commerce_ajax_basket_link

Здравствуйте, подскажите куда этот код нужно добавить или заменить ?

Гость
20.02.2014, 14:17

Делаю, чтобы после добавления товара картинка улетала в корзину:

Добавил в modulename_form_commerce_cart_add_to_cart_form_alter:

 drupal_add_js(drupal_get_path('module', 'modulename') . '/modulename.js');

в js файле:

(function ($) {
Drupal.behaviors.modulename= {
  attach: function(context, settings) {  
    $('input#edit-submit.form-submit.ajax-processed', context).bind('ajaxSuccess', function(data, status, xhr) {
         //здесь код улёта картинки   
    });
  }
};  
})(jQuery);

Всё прекрасно работает, но, к сожалению, не только когда жму по кнопке "в корзину", но и когда, например, меняю размер - тоже срабатывает ajax.

Не соображу как определить, при ajax, что я нажимал кнопку а не select ?

Гость
22.02.2014, 13:11

пошел другим путем - просто создал свою Drupal.ajax.prototype.commands - в ней и прописал свой js

Дерек
11.03.2014, 16:16

Хотелось бы еще выводить сообщение об успешном добавлении товара в корзину =)
ответ
@Don удалите drupal_get_messages();
удаление этой функции с последующим обновлением кеша, не выводит на экран инфу об успехе операции. Не подскажите в чем может быть причина?
п.с. зато если под админом добавить товар, и перейти на редактирование, то надпись о добавлении товара выводится в форме редактирования товара, аномалия какая то...

Не подскажите в чем может быть причина?

нужно добавить вторую ajax команду для вывода сообщения с помощью theme('status_messages')

Дерек
11.03.2014, 17:15

нужно добавить вторую ajax команду для вывода сообщения с помощью theme('status_messages')
получается так?:

    return array(
        '#type' => 'ajax',
        '#commands' => array(
            // Возможно придётся изменить селектор, если у вас кастомный шаблон для блока корзины
            ajax_command_html('#block-commerce-cart-cart .content', render($cart_block['content'])),
            ajax_command_html('.status', theme('status_messages')),
        ),
    );

что то не пашет =(

Дерек
11.03.2014, 17:18

опечатка была. все работает, спасибо!

смею предположить, что .status не существует

Алексей
23.03.2014, 19:45

Откуда можно вызвать событие Rules? Вопрос в пересчете цен - после добавления товара в корзину рулесом пересчитывается цена заказа и меняются цены опт/розница. Правила на статике (с обновлением страницы) работают прекрасно. Было желание вызывать правило перед отрисовкой содержимого корзины. С Аяксом очень туго выходит ... подробности ниже:
Оформил само событие в модуле, на это на которое повесил Rules:

 /**
* implements hook_rules_event_info().
*/
function modulename_rules_event_info() {
 	return array(
		'mymodulename_cart_update' => array(
			'label' => t('When cart updates'),
			'group' => t('test'),
			'module' => 'mymodulename',
			'variables' => array(
				'label' => 'mymodulename_cart_update',
				'type' => t('mymodulename_cart_update'),
			),
		),
	);
}

Однако вызов не могу нигде поставить... вываливает сайт в белый экран.

rules_invoke_event('mymodulename_cart_update');

Соббсно пробовал и на hook_form_alter() вешать, и...
Раскопал из песочницы Ваш commerce_simplecartblock. Там тоже для меня весьма большая туманность...

Гость
12.07.2014, 13:42

>> Дерек
>> опечатка была. все работает, спасибо!
В чем была опечатка?

>> Дерек
>> опечатка была. все работает, спасибо!
В чем была опечатка?

в id

Василий
01.07.2015, 13:32

С чем может быть связано такое поведение:
Добавляю товар в корзину с главной - нормально (AJAX).
Перехожу в корзину
Возвращаюсь на главную
Добавляю этот же товар - страница перезагружается, иногда с сообщением о добавлении товара, иногда без него.
После этого товар опять по AJAX нормально добавляется

Василий
01.07.2015, 14:06

Тоже самое происходит и с вашим модулем Commerce Fast Ajax Add to Cart

Василий
01.07.2015, 15:22

Заметил, что такое поведение возникает только если тизер-товара выводится views
В чем может быть причина?

Василий
01.07.2015, 15:45

Причина была в том, что в настройках представления для блока стояло кешировать все глобально

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