Commit e2c9c715 authored by Anton's avatar Anton
Browse files

Edit price view field

parent 62e638df
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@ INTRODUCTION
------------
When a user changes items quantity in Cart popup,
this module refreshes total sums w/o refreshing a page.
In Cart popup outputs currency symbol, not it's code.


REQUIREMENTS
@@ -33,6 +34,7 @@ Add block "Commerce ajax cart block"
Install my fork of module dc_ajax_add_cart from 
install  igrowl from 
add libraries unpack animate.tar and igrowl.tar from module dc_ajax_add_cart to /libraries
add edit price field at view commerce_products


To customize cart block markup see commerce_ajax/templates/commerce-ajax-cart-block.html.twig
+8 −63
Original line number Diff line number Diff line
<?php
function commerce_ajax_update_cart($form, \Drupal\Core\Form\FormStateInterface $form_state) {
  $triggering_element = $form_state->getTriggeringElement();
  $order_id = $triggering_element['#order_id'];
  $view = reset($form_state->getBuildInfo()['args']);
  $quantities = $form_state->getValue('edit_quantity', []);
  $order = \Drupal::entityTypeManager()->getStorage('commerce_order')->load($order_id);
  $cartManager = \Drupal::service('commerce_cart.cart_manager');
  foreach ($quantities as $row_index => $quantity) {
    /** @var \Drupal\commerce_order\Entity\OrderItemInterface $order_item */
    $order_item = $view->result[$row_index]->_relationship_entities['order_items'];
    if ($order_item->getQuantity() != $quantity) {
      $order_item->setQuantity($quantity);
      $order = $order_item->getOrder();
      $cartManager->updateOrderItem($order, $order_item, FALSE);
      // Tells commerce_cart_order_item_views_form_submit() to save the order.
      $form_state->set('quantity_updated', TRUE);
      $form_state->setValue(['edit_quantity', $row_index], $quantity);
//      $form['edit_quantity'][$row_index]['#value']
    }
  }
  /** @var \Drupal\commerce_order\Entity\OrderInterface $order */
  $order->save();
  return $form;
//  return Drupal::service('commerce_ajax.refresh_page_elements_helper')
//    ->updatePageElements($form)
//    ->getResponse();
}

/**
 * Implements hook_form_alter().
 * Implements hook_views_data_alter().
 */
function commerce_ajax_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  if ($form_state->getFormObject() instanceof \Drupal\views\Form\ViewsForm) {
    /** @var \Drupal\views\ViewExecutable $view */
    $view = reset($form_state->getBuildInfo()['args']);
    $tag = $view->storage->get('tag');
    $view_has_content = !empty($view->result);
    if ($tag == 'commerce_cart_block' && $view_has_content) {
      foreach ($form['edit_quantity'] as $key => $v) {
        if(is_int($key)) {
          $form['edit_quantity'][$key]['#ajax'] = [
            'callback' => 'commerce_ajax_update_cart',
            'wrapper' => 'commerce_cart_block-cart-ajax-wrapper',
            'event' => 'change',
function commerce_ajax_views_data_alter(array &$data) {
  $data['commerce_product_variation']['edit_price']['field'] = [
    'title' => t('Price text field'),
    'help' => t('Adds a text field for editing the price.'),
    'id' => 'commerce_ajax_edit_price',
  ];
          $form['edit_quantity'][$key]['#order_id'] = $view->argument['order_id']->value[0];
        }
      }
      foreach ($form['remove_button'] as $key => $v) {
        if(is_int($key)) {
//          $form['remove_button'][$key]['#ajax'] = [
//            'callback' => 'commerce_ajax_update_cart',
//            'wrapper' => 'commerce_cart_block-cart-ajax-wrapper',
//          ];
//          $form['remove_button'][$key]['#attributes'] = [
//            'class' => ['use-ajax-submit'],
//          ];
//          $form['remove_button'][$key]['#order_id'] = $view->argument['order_id']->value[0];
        }
      }
      $form['#prefix'] = '<div id="commerce_cart_block-cart-ajax-wrapper"><div class="views-form">';
      $form['#suffix'] = '</div></div>';
    }
  }
}

/**
+2 −0
Original line number Diff line number Diff line
views.field.commerce_ajax_edit_price:
  type: views.field.field
+0 −1
Original line number Diff line number Diff line
@@ -219,7 +219,6 @@
  width: 42px;
  height: 42px;
  background: #b7b7b7;
  margin: 0.8em 0 0;
  border-radius: 50%;
  border: none;
  position: relative; }
+141 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\commerce_ajax\Plugin\views\field;

use Drupal\Core\Form\FormStateInterface;
use Drupal\views\Plugin\views\field\FieldPluginBase;
use Drupal\views\Plugin\views\field\UncacheableFieldHandlerTrait;
use Drupal\views\ResultRow;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Defines a form element for editing the order item quantity.
 *
 * @ViewsField("commerce_ajax_edit_price")
 */
class EditPrice extends FieldPluginBase {

  use UncacheableFieldHandlerTrait;

  /**
   * Constructs a new EditPrice object.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin ID for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition
    );
  }

  /**
   * {@inheritdoc}
   */
  public function clickSortable() {
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  protected function defineOptions() {
    $options = parent::defineOptions();
    return $options;
  }

  /**
   * {@inheritdoc}
   */
  public function buildOptionsForm(&$form, FormStateInterface $form_state) {
    parent::buildOptionsForm($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  public function getValue(ResultRow $row, $field = NULL) {
    return '<!--form-item-' . $this->options['id'] . '--' . $row->index . '-->';
  }

  /**
   * Form constructor for the views form.
   *
   * @param array $form
   *   An associative array containing the structure of the form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   */
  public function viewsForm(array &$form, FormStateInterface $form_state) {
    // Make sure we do not accidentally cache this form.
    $form['#cache']['max-age'] = 0;
    // The view is empty, abort.
    if (empty($this->view->result)) {
      return;
    }
    $form[$this->options['id']]['#tree'] = TRUE;
    foreach ($this->view->result as $row_index => $row) {
      /** @var \Drupal\commerce_product\Entity\ProductVariationInterface $product_variation */
      $product_variation = $this->getEntity($row);

      $form[$this->options['id']][$row_index] = [
        '#type' => 'textfield',
        '#title' => $this->t('Price'),
        '#title_display' => 'invisible',
        '#default_value' => number_format($product_variation->getPrice()->getNumber(), 2, '.', ''),
        '#size' => 9,
        '#ajax' => [
          'callback' => 'Drupal\commerce_ajax\Plugin\views\field\EditPrice::viewsFormSubmit',
          'wrapper' => '#not-exist-element',
          'event' => 'change',
        ],
        '#suffix' => '<span class="currency">'.$product_variation->getPrice()->getCurrencyCode().'</span>',
      ];
    }
  }

  /**
   * Submit handler for the views form.
   *
   * @param array $form
   *   An associative array containing the structure of the form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   */
  public function viewsFormSubmit(array &$form, FormStateInterface $form_state) {
    $triggering_element = $form_state->getTriggeringElement();
    $view = reset($form_state->getBuildInfo()['args']);
    $price_list = $form_state->getValue($triggering_element['#parents'][0], []);
    foreach ($price_list as $row_index => $price) {
      /** @var \Drupal\commerce_product\Entity\ProductVariationInterface $product_variation */
      $view_result = $view->result[$row_index];
      $product_variation = $view_result->_relationship_entities['variations'];
      if ($product_variation->getPrice()->getNumber() != $price) {
        $product_variation->setPrice(new \Drupal\commerce_price\Price($price, $product_variation->getPrice()->getCurrencyCode()));
        $product_variation->save();
      }
    }
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function query() {
    // Do nothing.
  }

}
Loading