xandeadx.ru Блог музицирующего веб-девелопера

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

Опубликовано в

Код, позволяющий добавлять товары в корзину с помощью 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
Похожие записи

Комментарии RSS

Дык ведь вроде тыщу лет как модуль выкладывал под это дело :) http://netspark.ru/useful/modules/uproshchennaya-korzina-dlya-drupal-com...
Там и вывод мессиджа аяксовый был.

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

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

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

Круто! Работает! Спасибо!

Здравствуйте. Может Вы мне поможете один вопрос решить.
Имеется магазин с товарами. На странице товара форма добавления в корзину.
В качестве атрибутов выводятся размеры товара.
Переделала функцию 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');
  }
}

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

@Don удалите drupal_get_messages();

Код может конфликтовать с 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

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

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

Добавил в 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 ?

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

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

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

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

нужно добавить вторую 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')),
        ),
    );

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

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

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

почти ;P

Откуда можно вызвать событие 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. Там тоже для меня весьма большая туманность...

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

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

в id

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

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

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

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

Оставить комментарий

Содержимое этого поля является приватным и не будет отображаться публично. Если у вас есть аккаунт в Gravatar, привязанный к этому e-mail адресу, то он будет использован для отображения аватара.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Доступные HTML теги: <a> <i> <b> <strong> <code> <ul> <ol> <li> <blockquote> <em> <s>
  • Строки и параграфы переносятся автоматически.
  • Подсветка кода осуществляется с помощью тегов: <code>, <css>, <html>, <ini>, <javascript>, <sql>, <php>. Поддерживаемые стили выделения кода: <foo>, [foo].

Подробнее о форматировании