I've had a go at modifying the add to cart form to resolve a few outstanding issues. Since it's a substantial patch and the fixes are complementary, I thought I'd create a new issue. Realistically I wouldn't expect this to be mainlined because there are some significant changes (though I've tried to keep the form structure largely unchanged), but perhaps it may be useful for the D8/DC2 branch or perhaps added to contrib.
Patch is vs dev., and I applied it with no problems locally.
The issues I'm tackling with this patch (that I'm aware of) are:
Issue #1286244 - Allow dependent attributes to preserve their default options if a matching product exists on an Add to Cart form
Issue #1226466 - Possibility to show price difference/total price in attributes Select List / Radio Buttons
Issue #1782080 - Add support for the Add to Cart form to work without JS
Here's a brief (and incomplete) summary of what I did:
Option Selection
- Rejigged the process of selecting valid options to use set operations in the context of the current product. It preserves existing attribute values to the extent possible. There's documentation in the patch explaining how it works.
- Created an option product map, associating each valid option with a product. This map is stored with the form so that the validation function can identify the new product based on which attribute has changed.
Pricing
- Added pricing for each valid attribute option using the option product map (one or more attributes supported).
- Added pricing for 'product_select' and 'product_id' form elements.
- Each product is passed through Rules to calculate the price.
- For now I'm just displaying the product price, not the differential (though that would be fairly straightforward). And for now there's no UI to control pricing behaviour.
- In my testing so far with < 10 products and only the vanilla pricing rule, this is acceptably performant. For a greater number of products or more resource-intensive rules, performance could become an issue. And using pre-calculated prices is actually worse at the moment because each call to commerce_product_calculate_sell_price() involves a db query.
Graceful Degradation
- added an update button (hidden to users with js enabled); all product-deterministic form elements trigger as this button for ajax purposes
- setting the product id now happens in the form validation function so users can now add non-default products to the cart
- for product fields and the cart to reflect the same product on form rebuild, I had to make slight change to commerce_product_reference_entity_view() to get the current product from the form.
Anyways, this isn't ready for production by any means but I thought I'd put it out there for review. Feedback is most welcome!
| Comment | File | Size | Author |
|---|---|---|---|
| commerce_cart-reworked_add_to_cart_form.patch | 43.76 KB | mesch |
Comments
Comment #1
wqmeng commentedHello mesch
I have tried your patch, and get a blank page of error,
What I use, commerce 1.7, Commerce Customizable Products, with Field collections.
Comment #2
mesch commentedThanks for taking a look wqmeng. The patch is against -dev, so applying it against the 1.7 probably won't work.
Comment #3
loparr commentedHi,
Just came across same problem regarding javascript turned off and always default product in cart.
However, I found out that if a product has only one atribute type for example color and atribute field settings is turned off in product types, adding to cart works also with js disabled. Am I missing any needed functionality by unchecking that?
Comment #4
deadhead commentedWorks great. Thanks for this, would have had to consider abandoning Drupal Commerce otherwise. Applied against 1.10 release.
Did receive "Fatal error: Can't use method return value in write context" on line 1814. Changed line to (removing !empty):
$current_pid = $line_item_wrapper->commerce_product->raw() ? $line_item_wrapper->commerce_product->raw() : key($products);and it seems to work.
Comment #5
mesch commentedRe: #4, thanks for the feedback. The patch was made against -dev so that's probably why you're getting the error when applied against 1.10.
Just to re-iterate the OP, I wouldn't use this on a production site. This is more of a proof of concept that hasn't yet been thoroughly tested.
Comment #6
nelslynn commentedSame error as #4 using new Dev version of Jan16, 2015.