Does anyone know of a method to display the price within the Add to Cart form?

I would like to display the price between the attribute fields and the quantity field, as I feel this best ensures people see the unit price reflective of price changes brought about by changing the attributes.

Any ideas?

Comments

davidwhthomas’s picture

Subscribing.

davidwhthomas’s picture

Status: Fixed » Active

OK, I needed this too and did it with hook_form_alter, perhaps there's a better way, but it works.

/**
 * hook_form_alter
 */
function example_form_alter(&$form, &$form_state, $form_id) {
  // e.g form id: commerce_cart_add_to_cart_form_u6onPJSgS7pOgw0Tlo7zHy42LTQzbV913taANkYQKTo
  if (strpos($form_id, 'commerce_cart_add_to_cart_form') !== FALSE){
    // Adjust add to cart form
    example_commerce_add_to_cart_form_alter($form, $form_state);
  }

}

/**
 * Custom function to alter add to cart form
 */
function example_commerce_add_to_cart_form_alter(&$form, &$form_state){
  // Add read only price field to add to cart form
  if (isset($form_state['default_product']->commerce_price)){
    $form['display_price'] = array(
      '#title' => t('Price'),
      '#type' => 'item',
      '#markup' => commerce_currency_amount_to_decimal($form_state['default_product']->commerce_price[LANGUAGE_NONE][0]['amount'], $form_state['default_product']->commerce_price[LANGUAGE_NONE][0]['currency_code']),
      '#field_suffix' => $form_state['default_product']->commerce_price[LANGUAGE_NONE][0]['currency_code'],
    );
  }

}

I hope that helps.

cheers,

DT

P.S Commerce rocks :-)

davidwhthomas’s picture

Status: Active » Fixed
rszrama’s picture

Status: Active » Fixed

Thanks for posting a solution, David! : )

essbee’s picture

Brilliant.

Only issues I see are:

  • it doesnt pick up currency formatting provided by other modules, rather it has the currency code hard coded as a suffix.
  • it doesnt get the formatted price inclusive of any displayed taxes.

I'll work on the above two and repost adjusted solution.
Thanks again David, agree Commerce rocks!

Sam

rtdean93’s picture

Thanks for posting this. Worked great.

Question... how do I format the price.

Current display is "30 USD"

I'd like to format is as "$30.00"

essbee’s picture

I have the formatting fixed, just need to change a line in the code, I'm working through proper handling to ensure the calculated sell price is used rather than the stored product price (ie to include taxes etc).

If all you want is the currency properly formatted, replace the function "commerce_currency_amount_to_decimal" with "commerce_currency_format", same variables are accepted.

Correct procedure though should be using commerce_product_calculate_sell_price to ensure it is compatible with other modules that alter the price (discounts, taxes etc).

Hopefully will post soon.

essbee’s picture

Status: Fixed » Needs review

Ok the following works and utilises the calculate price, and current currency formatting settings, but its a bit inelegant. Would appreciate someone suggesting the correct way to display the formatted, calculated price.

/**
 * hook_form_alter
 */
function example_form_alter(&$form, &$form_state, $form_id) {
  // e.g form id: commerce_cart_add_to_cart_form_u6onPJSgS7pOgw0Tlo7zHy42LTQzbV913taANkYQKTo
  if (strpos($form_id, 'commerce_cart_add_to_cart_form') !== FALSE){
    // Adjust add to cart form
    example_commerce_add_to_cart_form_alter($form, $form_state);
  }

}

/**
 * Custom function to alter add to cart form
 */
function example_commerce_add_to_cart_form_alter(&$form, &$form_state){
  // Add read only price field to add to cart form
  if (isset($form_state['default_product']->commerce_price)){
    $price = commerce_product_calculate_sell_price($form_state['default_product']);
    $form['display_price'] = array(
      '#title' => t('Price'),
      '#type' => 'item',
      '#markup' => commerce_currency_format($price['amount'], $price['currency_code']),
    );
  }

}
davidwhthomas’s picture

Thanks essbee, nice adjusted solution :-)

DT

essbee’s picture

No worries, thank you for doing the hard part.

Also I added a div wrapper to allow me to style the label and price.

/**
 * hook_form_alter
 */
function example_form_alter(&$form, &$form_state, $form_id) {
  // e.g form id: commerce_cart_add_to_cart_form_u6onPJSgS7pOgw0Tlo7zHy42LTQzbV913taANkYQKTo
  if (strpos($form_id, 'commerce_cart_add_to_cart_form') !== FALSE){
    // Adjust add to cart form
    example_commerce_add_to_cart_form_alter($form, $form_state);
  }
}

/**
 * Custom function to alter add to cart form
 */
function example_commerce_add_to_cart_form_alter(&$form, &$form_state){
  // Add read only price field to add to cart form
  if (isset($form_state['default_product']->commerce_price)){
    $price = commerce_product_calculate_sell_price($form_state['default_product']);
    $form['display_price'] = array(
      '#title' => t('Price'),
      '#type' => 'item',
      '#markup' => commerce_currency_format($price['amount'], $price['currency_code']),
      '#prefix' => '<div class="display-price">',
      '#suffix' => '</div>',
    );
  }
}
rtdean93’s picture

This works great. Thanks for the fast and efficient fixes.

jessicakoh’s picture

How do I use the code? Where do I paste?

essbee’s picture

You'll need to create a module.
I suggest you start here: http://drupal.org/node/361112

The code provided is the content for the .module file, you will also need to create a .info file. You will need to rename the two functions replacing the word "example" with the name of your module.

davidwhthomas’s picture

@jessicakoh While a module is the best place to put the code, in D7 you may also be able to add to template.php, changing "example" to your theme name.
The example was tested from a module.
DT

jessicakoh’s picture

@davidwhthomas Thank you for the tips. Save my time, I can quickly test out a code.

timodwhit’s picture

Just out of curiosity: With this module/code as a base would it be possible to invoke rules to calculate a price based on "Term Selection" on the line item using rules, prior to adding to cart? If so sign me up! :-)

Thanks for the code!

paulguy’s picture

Thanks for the code too !

But in case of multiple products with attributes (like sizes, colors etc) and when I change one of them the form is reloaded but not the price. And I can figure why the hook_alter is not called on form refresh ...

How could I display the price of the current product (mixes of attributes) displayed and refresh it on change ?
Same question with a quantity select field ...

Thanks by advance !

davidwhthomas’s picture

@paulguy,

Not sure what you did there, but the code will refresh and show the price of the current selected product, based on attribute combination. At least, it does for me.

rszrama’s picture

Version: 7.x-1.0 » 7.x-1.x-dev
Category: support » feature
Status: Needs review » Active

I'm not entirely sure why this is still marked as "needs review", but since that status is specifically for patch review, I'm just going to make this an open feature request. Would be great to be able to get this into core if possible, but it'll need a patch and tests to ensure it accommodates the necessary use cases.

murz’s picture

Using full hook_form_alter() will slow down site, because this function launches on each form on page, so if we have 10 forms, this function will be called 10 times.
So be better to use hook_form_BASE_FORM_ID_alter(), for this form it will be
mymodulename_form_commerce_cart_add_to_cart_form_alter(), so instead of 2 functions you will need only one:

function example_form_commerce_cart_add_to_cart_form_alter(&$form, &$form_state){
  // Add read only price field to add to cart form
  if (isset($form_state['default_product']->commerce_price)){
    $price = commerce_product_calculate_sell_price($form_state['default_product']);
    $form['display_price'] = array(
      '#title' => t('Price'),
      '#type' => 'item',
      '#markup' => commerce_currency_format($price['amount'], $price['currency_code']),
      '#prefix' => '<div class="display-price">',
      '#suffix' => '</div>',
    );
  }
}
rszrama’s picture

You can use hook_form_alter() just the same and wrap your code in an if statement on the $form_id parameter. No performance hit there either. The hook's still going to be invoked whether you implement it or not, and your code will still only be executed once.

rtdean93’s picture

I am using a price formatter to show discounts applied to the price... the formatters work fine in views, but are not working with this form alter. How would I place the formatted price in this form?

murz’s picture

When using hook_form_BASE_FORM_ID_alter(), function is invoked only on BASE_FORM_ID forms, so if page have 10 other forms and 1 commerce form, this function will called only once.
But if we use hook_form_alter(), function will called 11 times.

If function do only one "if statement", php each time will spend cpu time and memory for calling this function, passing $form and $form_state objects into it, parsing if statement, etc, so we will lost small piece of performance (not so big, but not zero) on this operations.

If each module will add his hook_form_alter() to each form, this many small pieces at all can slow down site.
So, I think, better is to use hook_form_BASE_FORM_ID_alter().

rszrama’s picture

Heh, fair enough. The performance hit is really trivial, but yes, may as well use the specific hook. My comment was a bit of cross-talk from another issue where the question was about loading cached entities or something.

stijn.blomme’s picture

@rtdean93 I ran into the exact same problem.
I was able to fix it by using the field api to collect the renderable array for this field.
i'm using the commerce_price_savings_formatter to format the field.

edit: just noticed this only works if you have your price field set to visible in the display settings

function EXAMPLE_commerce_add_to_cart_form_alter(&$form, &$form_state){
   
  // Add read only price field to add to cart form
  if (isset($form_state['default_product']->commerce_price)){
      //get the selected formatter for the field
      $formatter = field_info_instance('commerce_product', 'commerce_price', $form_state['default_product']->type);
      
      //get the renderable array for this field
      $price_display = field_view_field('commerce_product', $form_state['default_product'], 'commerce_price', $formatter['display']['default']);
    
      //add the array to the add to cart form
      $form['display_price'] = $price_display;
  }
}

edit: if you set the field to hidden Drupal will not store the formatter connected to the field
It will still render if you insert the formatter hardcoded.

function EXAMPLE_commerce_add_to_cart_form_alter(&$form, &$form_state){
  // Add read only price field to add to cart form
  if (isset($form_state['default_product']->commerce_price)){
      //get the renderable array for this field
      $price_display = field_view_field('commerce_product', $form_state['default_product'], 'commerce_price', array(
          'type' => 'commerce_price_savings_formatter_inline',
          'label' => 'hidden',
          'settings' => array(
               'calculation' => TRUE,
              'prices' => Array('list', 'price'),
              'savings' => 'percentage',
              'show_labels' => FALSE
          )
      ));
    
      //add the array to the add to cart form
      $form['display_price'] = $price_display;
    
  }
}
willieseabrook’s picture

Hi everyone

Thanks for providing this, it was very close to what I needed and it pops up on the first couple of google results.

I needed to show the formatted price *with components* though as we have a legal requirement to show the tax component of an advertised price.

Code is below. Not sure if "commerce_price_field_formatter_view" is the right approach, but it does work. Also you'll need to be careful as this only works on node view pages - I use $node to get the language. We only need the form shown in this way on public node view pages and the site is multilingual.

function example_form_commerce_cart_add_to_cart_form_alter(&$form, &$form_state) {
  $product = $form_state['default_product'];

  if (isset($product->commerce_price)) {
    $field = field_info_field('commerce_price');
    $node = menu_get_object();
    $price_display = commerce_price_field_formatter_view('commerce_product', $product, $field, $product->commerce_price, $node->language, $product->commerce_price[$node->language], array('type' => 'commerce_price_formatted_components'));
    $form['display_price'] = array(
      '#title' => t('Price'),
      '#type' => 'item',
      '#markup' => $price_display[0]['#markup'],
      '#prefix' => '<div class="display-price">',
      '#suffix' => '</div>',
    );
  }
}
willieseabrook’s picture

Improvement on my previous example.

We probably shouldn't be using "commerce_price_field_formatter_view" directly? Instead using 'field_view_value'?

So I think this is is a better approach (although its pseudo and not tested):


  if (isset($product->commerce_price)) {
 //....
    $prices = field_get_items('commerce_product', $product, 'commerce_price');
    $output_price = field_view_value('commerce_product', $product, 'commerce_price', $prices[0], array(
      'type' => 'commerce_price_formatted_components'
    ),
    $node->language);
// ...
    $form['display_price'] = array(
      '#title' => t('Price'),
      '#type' => 'item',
      '#markup' => render($output_price),
      '#prefix' => '<div class="display-price">',
      '#suffix' => '</div>',
    );
// ...

joachim’s picture

What about the case when there is only a single attribute field in the add to cart form? I'd like to show the price in the actual attribute widget in this case.

I'm wondering whether this warrants a separate issue though, as it's going to be implemented totally differently.

lsolesen’s picture

@joachim That is a different issue, but I am looking for the same thing, so I started it here: #1823356: Show price in form element single attribute field. You are welcome to clarify.

nicolas bouteille’s picture

#20 worked for me.
I would be great if this functionnality could be added to the settings of the product reference field in the Manage display screen just as the quantity widget is. I personally don't know how to do this yet.

candelas’s picture

@Murz thanks
#20 worked for me.
i subscribe to the feature request petition.

jonhattan’s picture

Title: Show price in Add To Cart From » Show price in Add To Cart Form
sujith.nara’s picture

Issue summary: View changes

Commerce pricing attributes module updates price field dynamically. But the price field shown in commerce cart form doesn't change.
How to show this dynamic price field in cart form?

etiennechataignier’s picture