Drupal → AJAX кнопка обновления корзины + пересчёт цены при изменении количества в Commerce 1

01.03.2015

Задача — аяксифицировать кнопку "Update cart" и поля ввода количества товара.

Кнопка обновления корзины будет работать на немного изменённом коде из поста AJAX удаление товаров из корзины Drupal Commerce. А поля "Количество" будут эмулировать нажатие кнопки "Update cart" с помощью свойства trigger_as:

/**
 * Implements hook_form_FORM_ID_alter(): views_form_commerce_cart_form_default.
 */
function MODULENAME_form_views_form_commerce_cart_form_default_alter(&$form, &$form_state) {
  $form['#action'] = url('cart');

  // AJAX button "Update cart"
  $form['actions']['submit']['#name'] = 'update-cart';
  $form['actions']['submit']['#ajax'] = array(
    'callback' => 'MODULENAME_cart_form_ajax_update',
  );

  // AJAX quantity inputs
  foreach (element_children($form['edit_quantity']) as $key) {
    $form['edit_quantity'][$key]['#ajax'] = array(
      'callback' => '',
      'event' => 'change',
      'progress' => 'none',
      'trigger_as' => array(
        'name' => 'update-cart',
      )
    );
  }
}

/**
 * AJAX update cart.
 */
function MODULENAME_cart_form_ajax_update($form, &$form_state) {
  drupal_get_messages();
  $_POST = array();
  $view = $form_state['build_info']['args'][0];
  $order_id = commerce_cart_order_id($GLOBALS['user']->uid);
  $cart_view_output = commerce_embed_view($view->name, $view->current_display, array($order_id));

  return array(
    '#type' => 'ajax',
    '#commands' => array(
      ajax_command_replace('.view-commerce-cart-form', $cart_view_output),
    ),
  );
}

Как это выглядит:

Доработанный и оформленный в виде рабочего модуля код можно забрать в моей песочнице — Commerce Ajax Cart Form.

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

Комментарии

Гость
06.03.2015, 12:19

решение хорошее, но что при удалении и что при обновлении Вы не учитываете еще блок корзины )) смысл менять значение в форме если в блоке корзины значения не меняются.
нужно еще немного доработать

не вижу смысла в блоке корзины на странице корзины

Гость
09.04.2015, 21:38

может и смысла нету, хотя я много проектов делал что блок корзины в шапке был и не скрывался на странице корзины, но если ввести 0 количество товар удалится и ничего не будет выведено ((
скорее всего это проблема стандартной вьюхи

Гость
09.04.2015, 22:05

предлагаю решить эту проблему так:

function MODULENAME_cart_form_ajax_update($form, &$form_state) {
drupal_get_messages();
$_POST = array();
$order = MODULENAME_order_data();
// Default to displaying an empty message.
$cart = theme('commerce_cart_empty_page');
if ($order && $order['quantity'] > 0) {
$cart = commerce_embed_view('commerce_cart_form', 'default', array($order['order_id']));
}
return array(
'#type' => 'ajax',
'#commands' => array(
ajax_command_replace('.view-commerce-cart-form', $cart),
),
);
}

/**
* Get's current basket / cart order data.
*/
function MODULENAME_order_data() {
global $user;
$order_id = commerce_cart_order_load($user->uid);
if ($order_id) {
$order_wrapper = entity_metadata_wrapper('commerce_order', $order_id);
$line_items = $order_wrapper->commerce_line_items;
$quantity = commerce_line_items_quantity($line_items, commerce_product_line_item_types());
return array(
'order_id' => $order_id,
'quantity' => $quantity
);
}
return FALSE;
}

у меня так работает, буду рад замечаниям ))

Добрый день! А как быть с изменением, если стоит модуль commerce_extra ?

Сергей
01.09.2015, 16:48

Согласен с предыдущим комментарием! Решение прекрасное, но есть два нюанса. Первый - как заставить этот модуль работать с commerce_extra который добавляет полезнейшие плюс и минус?
Второе - если указывать количество вручную а не через commerce_extra, то промежуток времени для ввода слишком маленький. Я буквально не успеваю ввести двухзначную цифру количества. Ajax запрос срабатывает уже на первой.

Гость
11.09.2015, 01:14

а можно не привязываться к пути? что бы аякс срабатывал и на страничке - сек-аута(если вывести там форму)?

как заставить этот модуль работать с commerce_extra который добавляет полезнейшие плюс и минус

у меня стоит этот модуль и при добавлении +- обновление корзины происходит лишь после нажатия Update cart

Второе - если указывать количество вручную

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

Спасибо за решение!

Чугуевский Евгений
18.04.2016, 12:02

Вы не могли бы уточнить, в какой файл нужно это импортировать в обычном drupal commerce?
А то там не все так очевидно. у меня в форме корзины (/cart) стоят такие классы
В вырезке не сплошной код, старался вырезать лишнее

<div class="panel-pane pane-page-content">
<div class="contextual-links-wrapper contextual-links-processed"><a>Настроить</a><ul class="contextual-links" ><li class="views-ui-edit first last"><a href="/admin/structure/views/view/commerce_cart_form/edit/default?destination=cart">Редактировать представление</a></li>
</ul></div>
<div class="commerce-line-item-views-form"><form class="views-form-commerce-cart-form-default" action="/cart" method="post" id="views-form-commerce-cart-form-default" accept-charset="UTF-8"><div><input type="hidden" name="form_build_id" >
<input type="hidden" name="form_id" value="views_form_commerce_cart_form_default">
<table class="views-table cols-6">
    <tbody>
      <tr>
<td class="views-field views-field-edit-delete">
          <input class="delete-line-item form-submit" type="submit" id="edit-edit-delete-0" name="delete-line-item-0" value="Удалить">        </td>
              <td class="views-field views-field-commerce-total price">
         </td>
          </tr>
    </tbody>
</table>
<div class="line-item-summary">
      <div class="line-item-total">
    <span class="line-item-total-label">Всего:</span> <span class="line-item-total-raw">123 000 руб.</span>
  </div>
    </div>
<div class="form-actions commerce-line-item-actions form-wrapper" id="edit-actions"><input type="submit" id="edit-submit" name="op" value="Обновить корзину" class="form-submit"><input type="submit" id="edit-checkout" name="op" value="Оформление заказа" class="form-submit"></div></div></form></div>    </div>
Чугуевский Евгений
18.04.2016, 12:29

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

Чугуевский Евгений
18.04.2016, 13:23

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

Чугуевский Евгений
18.04.2016, 13:26

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

Чугуевский Евгений
18.04.2016, 14:10

jquery.min.js:6 POST http://crimea-nature.by/system/ajax 500 (Service unavailable (with message))
send @ jquery.min.js:
6x.extend.ajax @ jquery.min.js:
6b.fn.ajaxSubmit @ js_EwK_ExIZHfJb3xEhMSAizdwoddGe6P8UutPHCrEmfU4.js:
68Drupal.ajax.eventResponse @ js_hF7AlNqPjxPCq-futMvrxzzkwyxQrrdE0rxZp3R1vOg.js:
1461(anonymous function) @ js_hF7AlNqPjxPCq-futMvrxzzkwyxQrrdE0rxZp3R1vOg.js:
1388x.event.dispatch @ jquery.min.js:5v.handle @ jquery.min.js:5

Чугуевский Евгений
18.04.2016, 14:12

это лог консоли.
номера строк послле : я случайно сдвинул на следующую строку.
Но смысл понятен

Александр
25.08.2016, 11:41

Здравствуйте! Сделал все идентично написанному, но при обновлении перезагружается страница, ajax-ом не обновляется в чем причина может быть? Я замучился искать уже((

Гость
26.09.2016, 12:23

Андед - респект. Все здорово и быстро работает. А как навесить аякс на кнопки удаления из корзины в блоке на страницах каталога? Подобное делает dc_cart_ajax, но очень медленно и после удаления последнего товара не обновляется корзина.

Гость
01.10.2016, 18:31

Модуль тормозит если для цен используется price table.
Например для товара есть две цены. при количестве от 1 до 19 цена 40 руб, при 20 шт. и более цена 30 руб. Так вот если ввести количество 20, то цена остается 40 рублей (а должна быть 30) Итоговая цена пересчитывается, но с неправильной ценой. Как можно решить проблему?

Василий
04.01.2017, 11:31

Подскажите а как можно использовать Ваш модуль не для страницы корзины (cart) а на странице чекаута (checkout/*)?
Можно ли там привязать корзину с динамическим изменением количества через spinner и автоматическим пересчетом цены?

В представлении commerce_cart_form создайте блок, выведите на странице чекаута.

Василий
05.01.2017, 13:50

Спасибо вывел. Но есть странность. При работе модуля, спиннер появляется лишь один раз при загрузке, меняешь количество все применяется, но и +/- исчезают

Спасибо за модуль! Только вот столкнулся с проблемой, после первой отработки ajax перестает работать модуль, пропадает спиннер и все прочее. После обновлении стр. обратно все появляется и так по кругу)
Подскажите в чем может быть проблема? Модуль скачал с песочницы.

Sergei, я починил ошибку, обновите модуль

Гость
05.07.2017, 17:47

Доброго времени суток. При использовании спиннеров и аякс изменении количества товара работает увеличение товаров при прокрутке колеса мыши, можно ли это отключить(т.е чтобы товар увеличивался только при нажатии вверх или вниз) ?

Спасибо за исправление в модуле!

Boolboost
06.02.2018, 18:51

Есть подобное решение для drupal 8?

Андрей
23.12.2018, 18:48

Доброго времени! Пробуем добавить зависимость шага спиннера от поля ноды количество, в Вашем модуле Ajax Cart Form. Добавили переменную field_qty, с дробными значениями работает только в пределах своего разряда (от 1 до 9.99, или от 10 до 99.99...), чтоб перейти в другой разряд, нужно ввести целое число! В чем может быть дело? Если ставить вручную дробный step, всё работает.

изменённая часть Вашей JS'ки

        if ($input.hasClass('quantity-input-spinner')) {

          var field_qty = $('td.views-field-field-qty').text().trim();
          console.log(field_qty);

          $input.spinner({
            min: field_qty,
            step: field_qty,
            stop: function(event, ui) {
              $(event.target).change();
              $(event.target).keyup();
            }
          })
        }

Буду признателен, если направите :)

Привет, xandeadx. Модуль работает, НО: что если на странице не один 1 корзины, а 2. Из 2-х разных дисплеев вьюхи commerce_cart_form. Например в одном блоке список товаров,а в другом общая стоимость (подобное в модуле dc_ajax_add_cart).
Тогда при ajax-ации содержимое 1-го блока дублируется во 2-й. По-моему так не должно быть.

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