1

the logical flow of choosing attributes is seeing price adjustments based on the attributes chosen before the buy button ... how can i display the price in the form itself so it appears BEFORE the add to cart button?

here is an example of what i am talking about ... you have attributes, then you have price calculations based on attributes selected and very last thing is the buy button ... this is logical and i can't figure it out.

i did try using jquery to append the price to a div inside the form .. but that is a mess. all sorts of problems with ajax etc and not the correct approach anyway.

3
  • When I view an "add to cart" widget and change a product variation, it automatically updates the price via AJAX before I press the buy button. So I'm pretty sure Commerce 2 works as you want it to, but maybe you don't have something configured correctly. Please try posting detailed steps about how you set up your variations + add to cart form. Commented Oct 13, 2017 at 17:27
  • @Patrick Kenny - thanks for reply. yes, it does the same for me. my issue is that i want the price to appear before the BUY button ... it does not as it is part of the product page and therefore outside of the add to cart form element which means there is no easy way to move the price display BEFORE the buy button. having price appear before add to cart form with attributes or after buy button is not very intuitive. Commented Oct 13, 2017 at 17:36
  • Please edit your question with new information, don't just add a bunch of comments. It's a lot easier to read if people see a question that is cleanly laid out with the relevant information in order. If people see a bunch of messy comments, they are less likely to read them and try to answer the question. Commented Oct 13, 2017 at 18:07

3 Answers 3

1

I also believe the default UX (price above variations, or below add to cart), is a mess.

There's an issue about Moving price before/above add-to-cart button, where I posted a workaround :

/**
 * Implements hook_form_FORM_ID_alter.
 */
function my_theme_form_commerce_order_item_add_to_cart_form_alter(
  array &$form,
  FormStateInterface $form_state
) {
  $form_data = $form_state->getStorage();

  if (!empty($form_data['selected_variation'])) {
    $selectedVariation = ProductVariation::load(
      $form_data['selected_variation']
    );
    $footer_price = $selectedVariation->price->view();
  }
  else {
    $parameter = \Drupal::routeMatch()->getParameter('commerce_product');
    $product = \Drupal\commerce_product\Entity\Product::load(
      (int) $parameter->id()
    );

    $entity_manager = \Drupal::entityTypeManager();

    $product_variation = $entity_manager->getStorage(
      'commerce_product_variation'
    )->load((int) $product->getVariationIds()[0]);

    $footer_price = $product_variation->get('price')->view();
  }

  $form['footer']['price'] = $footer_price;
}

So far it works, even if I think there might be a slimmer solution. Credits to Alen Simonyan.

0

I spent weeks on trying to find a clean solution using the commerce-product.html.twig template but to no avail. The problem is the fact that the variation fields and add-to-cart button are packed together into one component (product.variations) in a way that is difficult to decompose. I cannot think of a way to insert the price in there somewhere. Someone should create an issue about this.

Here is a hacky CSS-workaround.

First, create some space above the add-to-cart button:

.commerce-order-item-add-to-cart-form .form-actions {
   margin-top: 4em;
}

Now place the price div into the created space:

article .field--type-commerce-price {
   position: absolute;
   bottom: 2.5em;
}

This also works when the price is updated.

Still looking for a cleaner solution.

0

@kojo thanks for your answer. I just had to change it so it would also read my custom PriceResolver. I added 'default' as displayOption for the view so it's now using my calculated formatter.

 /**
 * Implements hook_form_FORM_ID_alter.
 * Show price in add to cart form
 */
function template_form_commerce_order_item_add_to_cart_form_alter(array &$form, FormStateInterface $form_state) {
  $form_data = $form_state->getStorage();
  if (!empty($form_data['selected_variation'])) {
    $selectedVariation = ProductVariation::load($form_data['selected_variation']);
  }
  else {
    /** @var \Drupal\commerce_product\Entity\Product $product */
    $product = \Drupal::routeMatch()->getParameter('commerce_product');
    $selectedVariation = $product->getDefaultVariation();
  }
  $form['footer']['price'] = $selectedVariation->price->view('default');
}
1
  • This looks more like a comment than an answer. You could rephrase the answer so that it's clear that this builds on the answer of someone else and highlight only the additional changes you had to make.
    – berliner
    Commented Oct 7, 2021 at 11:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.