Like this:
Color
Red
Size
Medium
Price
$ 49,00
Add to cart
I tried:
- changing the field order in the product type and product variation type settings
- overriding commerce-product.html.twig
- adding some jQuery / Javascript code
- positioning the price div using CSS
- using hook_form_BASE_FORM_ID_alter() to alter the form
Solution #1 did not work out because the variation fields (color and size in this example) and the add-to-cart-button appear to be packed together as "Variations" in the product type settings.
Solution #2 has the same issue. The variation fields and add-to-cart-button are packed together in "product.variations" as one placeholder. I am not able to decompose it into seperate fields.
For solution #3 i tried moving the price div to the right location using jQuery, like this:
$("article .field--type-commerce-price").insertBefore(".commerce-order-item-add-to-cart-form .form-actions");
At first glance this works. However when the user starts changing variation fields the containing form gets removed along with the price. Commerce regenerates this form in order to update all the variation fields.
So far #4 gave the best results. I posted it on https://drupal.stackexchange.com/questions/248004/commerce-2-display-pri... but it is hacky. Using a top margin i created some space above the add-to-cart-button. Then i position the price div into that space. The CSS-code looks like this:
.commerce-order-item-add-to-cart-form .form-actions {
margin-top: 4em;
}
article .field--type-commerce-price {
position: absolute;
bottom: 2.5em;
}
For solution #5 i was able to insert custom text before the add-to-cart-button which looks promising:
function HOOK_form_commerce_order_item_add_to_cart_form_alter(&$form, FormStateInterface $form_state, $form_id) {
$form['test'] = array(
'#markup' => 'Here is where the price should go.',
'#weight' => 99
);
}
But then i cannot figure out how to obtain the actual price from there. Then i found a D7 solution at:
https://drupal.stackexchange.com/questions/105946/drupal-commerce-add-to...
It looks like this:
function mytheme_form_commerce_cart_add_to_cart_form_alter(&$form, &$form_state, $form_id) {
$product = $form_state['default_product'];
$view_mode = $form_state['context']['view_mode'];
$form['price'] = field_view_field('commerce_product', $product, 'commerce_price', $view_mode);
}
But i am not able to produce a D8 equivalent for this, in particular the last line.
function mytheme_form_commerce_order_item_add_to_cart_form_alter(&$form, FormStateInterface $form_state, $form_id) {
$product = $form_state->get('product'));
$view_mode = $form_state->get('form_display')->getMode();
// form['price'] = $product->get(???)
}
This is silly. I'm struggling for weeks now to get this working but I am getting nowhere. Does anyone have a better idea?
Comments
Comment #2
ishani.addweb CreditAttribution: ishani.addweb at AddWeb Solution Pvt. Ltd. commentedI hope below code helps you to find product price in D8:
Comment #3
Per CreditAttribution: Per commentedHi,
Any new ideas for a twig or any other easy solution for this problem, spend the last few days try to find something on google
Thanks
Comment #4
Per CreditAttribution: Per commentedComment #5
flamesquirrel CreditAttribution: flamesquirrel commentedIn the commerce-product.html.twig template you can do something like this:
Comment #6
hockey2112 CreditAttribution: hockey2112 commentedWhy should we have to use a twig, when there is a perfectly fine Drupal-based "Manage Display" tab? I just don't understand why we cannot position the price with the Drupal-based tools at our disposal without having to resort to a twig file. Any ideas on how we can do so? Blows my mind that I can't simply and easily control where my price is shown through the website's interface.
I don't mean to sound entitled, but I am just sort of shocked that this is a brick wall I am running into.
Comment #7
lamp5You can create pseudo field to make it working.
and clear cache
Comment #8
bisonbleu CreditAttribution: bisonbleu commentedI think this is a genuine bug, the feature request here makes no sense to me. Here's how to reproduce this bug. I'm using the Bartik theme in a Drupal 8.7.4 + Commerce 2.13.
Seems like the Add to cart formatter of the Product type is oddly flipping the order of the price and button without reason. As this is totally unexpected and cannot be fixed in the UI, I think it is fair to change this issue to a bug.
Perhaps Major is overkill so feel free to set back to Normal.
Comment #9
ec-adam CreditAttribution: ec-adam commentedThis was a tricky one for me without the simple Twig product template solution in #5—which I could not use because I'm using layout builder for my product type displays.
Ended up using a preprocess solution, on a field in my case, but could be done with anything as long as you can access the product you need the price of.
I'm then taking that calcPrice variable and using it a custom template for the product_id field that I have set below my product title in layout builder:
NOTE: This will print the price of the loaded variation of the product, but will not update when variant options are changed. To do that, use some jQuery to find the calculated price in the old place on the product (which I'm hiding with css) and update the price in the product_id field. Some simple jQuery math can also find the quantity input and multiple the calc-price times the quantity to show a user what they will actually be charged (excluding shipping, taxes, promotions, etc).
And yes, could have skipped the preprocess and Twig and just used jQuery to copy the calculated commerce-price and shove it where I want, but I felt this solution was more thorough and bullet proof in case of JS errors or something.
Comment #10
CaptainPinkey CreditAttribution: CaptainPinkey commentedThe commerce docs state to extend the original AddToCartForm for advanced modifications.
That has the advance of getting direct access to the product variation in there.
This places the price field directly over the add to cart button.
Edit:
It is necessary to call he buildEntity by hand method and use the returned object instead the instance once, because the instance once references to the default product variation instead of the currently selected one!
Comment #11
lalop CreditAttribution: lalop commentedI get this working by doing
Comment #12
b72077 CreditAttribution: b72077 commentedI solved my similar issue with the price or other variation fields appearing below the add to cart button.
I changed the file: commerce-product.html.twig (override in your theme) from the following:
to the following:
Comment #13
apadernoComment #14
SajithAthukorala CreditAttribution: SajithAthukorala commentedNone of these solutions are worked in my case . Anyone found better solution ? We can easily move the Price on top of the form , but not before the Add to cart button .
Comment #15
Kojo Unsui CreditAttribution: Kojo Unsui commentedI also believe the default UX (with the price above variations, or below add to cart), is a mess.
#11 does not work if you don't have at least 2 product variations, then
$form_data['selected_variation']
returns undefined.Here's a heavier solution, based on #11 and this answer on StackExchange. So far it seems to work in my config. Maybe it's too much for such a little trick but I don't have much more time to dig more into that, or look for a clean patch...
Comments welcome to improve / slim this :
Comment #16
ñull CreditAttribution: ñull commentedApparently the thread responders agree that this is a bug. I agree with them because imho the price should be always close (below) the fields that can change it, the attribute fields. The idea is that you have cause and result in the right order. Presently the price is under the title. When scrolled down people won't even see the price at all when there are many attribute fields.
Since this is a bug of Commerce, none of the above solutions work for me, because they either require custom module or a custom theme. None of these fix the issue, they work around it. The change should be in Commerce itself. What is the error exactly? How do we fix it with a Commerce patch? And why is this issue 3 years old? I would say this is a mayor issue because it causes all shop interfaces to fail. It is even critical because it can cause sales to go down.
Comment #17
lunk rat CreditAttribution: lunk rat commentedThe outrage and frustration expressed here is totally justified in my opinion. For example, #6 by @hockey2112
Commerce has such a powerful model for customizing everything through the Drupal UI. Yet in this case we can't consistently control where the price appears on the product page. The price! Probably the most important piece of data on a product page in an online store. Think about that.
I agree with @ñull in #16:
Changing priority to Major. Commerce module is an amazing gift to us all; let's not allow stuff like this to hinder its adoption.
Comment #18
nattyweb CreditAttribution: nattyweb commentedThis has been causing me a major headache. Now solved with #5 by flamesquirrel. Thank you so much - exactly what I needed.
Comment #19
tonytheferg CreditAttribution: tonytheferg as a volunteer commentedI agree. The price field, edit quantity widget and the add to cart button should be separate fields on one display so that they can be adjustable against one another. As it is right now you have to chase around 3 displays/display forms to try and figure out a workable solution.
Also I can confirm #8. At
/admin/commerce/config/product-variation-types/MY_VARIATION _TYPE/edit/display
, if no fields are above price, the price prints above the entire add to cart form. if any field is above price, the price prints below the entire add to cart form,.Comment #20
Chris Matthews CreditAttribution: Chris Matthews commentedYikes, I spent a long time trying to figure out what in the world I was doing wrong in the UI before I found this issue. All I wanted to do was move the product variation price field being injected into the rendered product directly above the Add to cart form for a better customer UX. By chance, has anyone pinged any of the Centarro folks on Slack re: this issue to see if it can be looked into further?
Comment #21
zenimagine CreditAttribution: zenimagine commentedhttps://drupal.stackexchange.com/questions/303452/how-to-organize-the-di...
It's amazing that there is no solution in the Drupal interface, without using custom code.
This problem is more than 3 years old :-(
It's a shame to have a powerful Commerce module that has this basic problem.
Is there a cotrib module that corrects this problem?
Comment #22
tonytheferg CreditAttribution: tonytheferg as a volunteer commented@Chris Matthews, I just pinged Ryan on this regarding desired improvements for 3.x
Comment #23
shaunole CreditAttribution: shaunole at LIA - The Laser Institute commentedFollowing up on @Kojo Unsui, I switched out the static calls to use service injection and to pull from a specific view mode (in my example, I have created a custom view mode: Add to Cart Form - machine_id:
add_to_cart_form
). I've added support for the 'Price' and 'List Price' fields, but theoretically, you could add any fields that exist in the product variations by retrieving their render array via->view()
on the field and saving that value to the$form
array. It would be ideal if the visible fields in the variation configuration could easily be queried and inserted into the form, respecting their weights, label, format, etc. settings.If you want to use the default view mode, you'll need to remove the string 'add_to_cart_form' from the
->view()
declarations.The above should function as a work-around until this issue is addressed officially.
Comment #24
leeksoup CreditAttribution: leeksoup as a volunteer commentedI have been trying to figure out the solution to this same problem and found this post via Drupal Stack Exchange. Thanks for OP for documenting.
Surprised this is still open after 4 years. I see several solutions ... is one of these the recommended solution more than others?
Comment #25
leeksoup CreditAttribution: leeksoup as a volunteer commentedThe easiest fix for me was to add an image field to the product and upload a tiny 5x5 pixel transparent png. Place it just above "variations" field. Thank you to all.
Comment #26
slawomir CreditAttribution: slawomir as a volunteer commentedUfff, spent the last three hours figuring out what's going on... and yeah, experiencing the same issue. My only field in the Product Variation Type seems to always float below the item that precedes it.
I intend to override the displays with Entity View Attachment and a custom View. Keeping an eye out for a core fix, just in case some day I decide not to use EVA.
Comment #27
hockey2112 CreditAttribution: hockey2112 commented@slawomir if you are going to use Views to display the price, make sure that the Views-produced price updates when you select attributes that would change the product price. That was an issue I ran into when using a Viewfield to display the price.
Comment #28
slawomir CreditAttribution: slawomir as a volunteer commented@hockey2112 Thanks! Curious if you solved the updating problem - what the issue was... did you resolve, or find a way around it?
Comment #29
imclean CreditAttribution: imclean commentedComment #30
niki v CreditAttribution: niki v as a volunteer commentedIt works as designed: the intermingling comes from having product-type display fields numbered 0,1,2,3... and also having product-variation or attribute fields numbered 0,1,2,3.... Number each field in each display as you want them to appear in the product page display. As the variation fields containing price, stock, weight, etc are injected into the product-type display, you use "show row weights" and number them in the product-variation display as you want them in the product-type display.
I put a simple example here:
Product display
image - 0
body - 1
Product variation
price - 2
stock level - 3
Product display
add to cart form - 4
categories - 5
tags - 6