The Product variation title widget shows you the different product variations, but not the prices which might be different.

Comments

joachim created an issue. See original summary.

waspper’s picture

Not sure about what you mean. Anyway, you can to setup a Product variation view mode, and show up needed fields there :).

Cheers.

joachim’s picture

Suppose I have a product, and it has 2 product variations, which have different titles and different prices.

I configure the Add to Cart form display for the Order Item type (at admin/commerce/config/order-item-types/default/edit/form-display/add_to_cart) to show the 'Product variation title' widget.

But on the add to cart form on the product, this shows me just a select element with the title.

The price shows on the product (controlled by the ' Inject product variation fields into the rendered product' setting on the product type) and that updates with AJAX, but the customer can't see both prices at once to compare. They have to work the select field to keep changing the product variation.

flocondetoile’s picture

Just for info, to get this feature, I create a custom FieldWidget which extends ProductVariationWidgetAttributes, and I override the getAttributeValues() method with this piece of code (just added the price logic)

protected function getAttributeValues(array $variations, $field_name, callable $callback = NULL) {
    $values = [];
    foreach ($variations as $variation) {
      $price = $variation->getPrice();
      $number = $price->getNumber();
      $currency = $this->currencyStorage->load($price->getCurrencyCode());
      $price_formatted = $price->isZero() ? $this->t('Free') : $this->numberFormatter->formatCurrency($number, $currency);
      if (is_null($callback) || call_user_func($callback, $variation)) {
        $attribute_value = $variation->getAttributeValue($field_name);
        if ($attribute_value) {
          $values[$attribute_value->id()] = $attribute_value->label() . '<span class="price">' . $price_formatted . '</span>';
        }
        else {
          $values['_none'] = '';
        }
      }
    }

    return $values;
  }

Same can be done of course on the ProductVariationTitleWidget widget.

I believe this is a common feature request on e-commerce site. this could be done :

1. by providing another two widgets (ProductVariationTitlePrice, ProductVariationAttributesPrice)
2. by a setting on the two existing widget.

The rendered result wanted can look like below

joachim’s picture

Status: Active » Needs review
StatusFileSize
new5.27 KB

Thanks for the code!

However, it's worth noting that that approach only works if you're using product attributes.

In my case, I'm not -- I just have two variations that have different titles and prices.

Here's a patch which adds an option to the widget settings.

Status: Needs review » Needs work
joachim’s picture

Needs a reroll -- the base class has an extra service injected which we need to pass along in the constructor.

joachim’s picture

Also, this should probably offer to show calculated prices, but #2805549: Expand the "Calculated price" formatter with the ability to show prices with promotions/taxes/fees adds that functionality to the Order module, and this widget is in Product, which doesn't depend on Order.

Any ideas on how to resolve that?

lisastreeter’s picture

@joachim Could it be handled in the same way it was handled in #2805549: Expand the "Calculated price" formatter with the ability to show prices with promotions/taxes/fees?

The new commerce_order formatter (PriceCalculatedFormatter) was created without a plugin annotation. Then in commerce_order.module, hook_field_formatter_info_alter was created to "swap out" the existing commerce_price formatter (commerce_price_calculated) with the commerce_order version.

function commerce_order_field_formatter_info_alter(array &$info) {
  $info['commerce_price_calculated']['class'] = 'Drupal\commerce_order\Plugin\Field\FieldFormatter\PriceCalculatedFormatter';
  $info['commerce_price_calculated']['provider'] = 'commerce_order';
}

So that would require a new widget in commerce_order, one that replaces this widget whenever the Order module is installed...

joachim’s picture

Yup, that would work. Thanks!

Given that that issue is still waiting for RTBC, it might be an idea to just reroll this patch and do it as it currently stands, and add the calculated price version in a follow-up once that other issue gets in.

dieuwe’s picture

Status: Needs work » Needs review
StatusFileSize
new6.78 KB

Re-roll of the original patch, with the extra service passed through and also two extra "separator" text fields which makes the prefix and suffix configurable.

E.g. "title - price" vs "title (price)".

I was hoping it would also handle the user case that @flocondetoile had, which was to wrap the price in an HTML element, but that might require some selective sanitation. (Perhaps a third textfield/select option for HTML an element wrapper?) Since I do not have such a need, I decided to leave that out. That screenshot also shows radios, which sounds like another good config that can be added without requiring people to override the whole widget. These two extra suggestions might be considered overkill to the core commerce experience though, so I am just leaving them as comments rather than pursuing implementation.

Status: Needs review » Needs work
longwave’s picture

Status: Needs work » Needs review
StatusFileSize
new6.76 KB

Rerolled against latest 8.x-2.x.

Status: Needs review » Needs work

The last submitted patch, 13: 2930046-13.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

kristofferrom’s picture

#13 works for me despite the failed tests in #14

kristofferrom’s picture

Would it be possible to add support for rendering the calculated price to enable support for products matching a promotion/being on sale? My use case is having promotions like "X amount off normal price" in a sale period. But using this patch only renders the normal price, not the reduced one.

damienmckenna’s picture

FYI I used Entity Extra Field to create an "extra" field that output the variation's price - not as clean as having a dedicated formatter, but it worked.