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

Drupal → AJAX удаление товаров из корзины Drupal Commerce

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

Работающий, но проблемный код:

/**
 * 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'); // Проблема 1
  if (!empty($form['edit_delete'])) {
    foreach(element_children($form['edit_delete']) as $key) {
      if (!empty($form['edit_delete'][$key]['#line_item_id'])) {
        $form['edit_delete'][$key]['#ajax'] = array(
          'callback' => 'MODULENAME_remove_ajax',
        );
      }
    }
  }
}
 
/**
 * "Remove" button ajax callback.
 */
function MODULENAME_remove_ajax($form, &$form_state) {
  drupal_get_messages();
  $_POST = array(); // Проблема 2
  $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),
    ),
  );
}

Проблема 1: при обновлении всей формы через AJAX, у формы обнуляется #action и она всегда сабмитится на главную. Из-за этого приходится хардкодить $form['#action'] = url('cart');. Issue на drupal.org.

Проблема 2: при попытке отрендерить форму в ajax-callback этой же формы, форма пытается отправиться второй раз. Это особенность работы Form API. Поэтому перед рендерингом приходится очищать $_POST.

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

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

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

Проблема 1: Я думаю, надо посмотреть в сторону #limit_validation_errors.

с валидацией проблем нет, ошибок не возникает

А почему dc_cart_ajax не используете ?

он кривой

Мне удалось найти еще одну тему касающуюся ajax и обсуждения dc_cart_ajax.

Вы не писали автору модуля по поводу кривости на drupal.org ?

Не могли бы вы здесь описать, что там сделано криво, хотя бы коротко ?

не писал. криво - всё

Если бы мы организовали сбор средств для разработки не кривого модуля,
во сколько бы вы оценили его ?

Стали бы вообще заниматься этим ?

Вам это под силу ?

рабочий код модуля в посте

Внутри view-commerce-cart-block кнопка удаления не работает.

Notice: Undefined index: #ajax in ajax_form_callback() (line 379 of includes\ajax.inc).

Вроде удалось переопределить и в блоке:

/**
 * Implements hook_form_FORM_ID_alter(): views_form_commerce_cart_form_default.
 */
function custommodule_form_views_form_commerce_cart_block_default_alter(&$form, &$form_state) {
  $form['#action'] = 'cart'; // Проблема 1
  if (!empty($form['edit_delete'])) {
    foreach(element_children($form['edit_delete']) as $key) {
      if (!empty($form['edit_delete'][$key]['#line_item_id'])) {
        $form['edit_delete'][$key]['#ajax'] = array('callback' => 'custommodule_remove_ajax');
      }
    }
  }
}

Проблема с использованием в блоке и форме одновременно.
По отдельности в форме или в блоке работает.
Либо #1, либо #2.
Если использовать вместе, то отваливаются модальные окна в ctools.
Вместо перехвата клика по ссылке ctools_link, происходит переход.

/**
 * "Remove" button ajax callback.
 */
function custommodule_remove_ajax($form, &$form_state) {
  drupal_get_messages();
  $_POST = array();
  $order_id = commerce_cart_order_id($GLOBALS['user']->uid);
 
  $cart_form = commerce_embed_view('commerce_cart_form', 'default', array($order_id));  // #1
  $cart_block = commerce_embed_view('commerce_cart_block', 'default', array($order_id)); // #2
 
//  Были попытки сделать как у groker в модуле:
//  $block = block_load('commerce_cart', 'cart');
//  $block_content = _block_render_blocks(array($block));
//  $build = _block_get_renderable_array($block_content);
//  $cart_block = drupal_render($build);
 
//  Есть мысль обновлять не весь блок целиком, а лишь часть "content".
//  $cart_block['content']
 
  $commands = array();
  $commands[] = ajax_command_replace('.view-commerce-cart-form', $cart_form);  // #1
  $commands[] = ajax_command_replace('.view-commerce-cart-block', $cart_block); // #2
 
  return array(
    '#type' => 'ajax',
    '#commands' => $commands
  );
}

Не хватает одного условия.
Подскажите пожалуйста, как правильно получить текущий адрес страницы находясь внутри MODULENAME_remove_ajax ?

не знаю

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

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

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