Totally Confused when trying to set up a single add to cart product

I’ve set up a product matrix to add a product with variants to the cart - easy.

I cannot figure out how to add a single simple product to the cart as I’m confused by the following - especially ‘this should be made dynamic’ (for info I think this is why I gave up on Commerce last time)…

#Single Products Form

With the single products form only one product can be added to the cart per request. As the structure of the form is a little easier than the multiple products form, it is easier to use this when providing different products as variations in your catalog.

The form includes:

  • an add_to_cart hidden input with value 1, this is used to trigger the add to cart logic.
  • the product ID in a hidden product input. This should be made dynamic, for example with the commerce.get_resource_product_id snippet, a TV holding the product ID(s) (like the Commerce Products TV), or a different way that you establish a products’ ID.
  • the quantity in a quantity input
<form method="post" action="[[~[[++commerce.cart_resource]]]]">
    <input type="hidden" name="add_to_cart" value="1">
    <input type="hidden" name="product" value="123">
    
    <label for="add-quantity">Quantity:</label>
    <input type="number" name="quantity" value="1">
    
    <input type="submit" value="[[%commerce.add_to_cart? &namespace=`commerce` &topic=`frontend`]]">
</form>

The following works but for a single product it looks odd putting it in a select box…

    <input type="hidden" name="add_to_cart" value="1">
    <input type="hidden" name="link" value="[[*id]]">
    
    <div class="product-variation">
        <label for="choose-variation">Product</label>
        <select id="choose-variation" name="product">
            [[!commerce.get_products? 
                &products=`[[*products]]`
                &tpl=`product_as_select`
            ]]
        </select>
    </div>
    <div class="product-quantity">
        <label for="add-quantity">Quantity</label>
        <input type="number" id="add-quantity" name="quantity" value="1">
    </div>
    
    <input type="submit" value="Add to Cart">
</form>```

You’ll need to submit the product id in a product field, along with add_to_cart = 1.

Commerce doesn’t care if that comes from a hidden input, a select, or even the result of some complex custom javascript app. All it wants is a product value submitted to the cart, where the value matches a valid product ID. Plus the add_to_cart field with value 1 to indicate you’re trying to add a product.

This works the same with a matrix. Each cell in the matrix is a distinct product, with its own ID, that gets selected and submitted when adding to the cart.

In the basic example you quoted, it is meant to go in the hidden input:

                             v field name "product"
<input type="hidden" name="product" value="123">
                                            ^ the product id to add

If you use a Product List TV to manage products associated with a specific resource, the TV value contains a comma-separated list of product IDs that were added to the TV.

If you configure the TV to allow just one product, you could just put in your TV value directly:

<input type="hidden" name="product" value="[[*products]]">
                                             ^ right here!

However, that wont work if you have multiple products selected.

With multiple products in the TV, you would use the commerce.get_products snippet to iterate over each product in your TV, and to output that in such a way that the customer can choose the product, for example as a select like you’re doing in your second post, or as a set of radio buttons. This section shows examples for each of those – looks like you found those.

If regardless of the number of products in the TV you just want the first product to be used in this particular form, you could use the commerce.get_product snippet. You can provide that the comma-separated list of products from the TV: &product=`[[*products]]`; and it will only use the first product in the list. You then have options to either use &toPlaceholders to make [[+product.id]] available, or render the product with a &tpl chunk to render the product information for that first product only.

If you want to conditionally do one or multiple products in the same template, you’ll need to mix in some conditional filters or snippets.

Regardless of how many products or where you have them stored, you need to POST an add_to_cart field with value 1, and product field with the ID of the product to add to the cart. That’s the key thing to understand.

1 Like

Thank you Mark - got it. I honestly think something needs changing in the docs or there needs to be a simple working example for 1 simple product. I understood the matrix straight away but couldn’t get my head round this at all.

I’m open to suggestions on clarifying that part of the docs. I’ll also take a look at the docs later and see if I can come up with any improvements there to make it easier to understand the first time.

This form is a fully functional example for adding a single simple product, though. As long as you have a product with ID 123 in your installation, this works just fine:

<form method="post" action="[[~[[++commerce.cart_resource]]]]">
    <input type="hidden" name="add_to_cart" value="1">
    <input type="hidden" name="product" value="123">
    
    <label for="add-quantity">Quantity:</label>
    <input type="number" name="quantity" value="1">
    
    <input type="submit" value="[[%commerce.add_to_cart? &namespace=`commerce` &topic=`frontend`]]">
</form>

Depending on the integration path you choose for products (list tv, matrix tv, or resource), the way you make that ID dynamic is different, so each integration path has its own examples too, with the dynamic part filled in.

I could change the ID in the generic example to 1 to increase the odds of that product actually existing, however I’m worried that would then stand out less as needing to be changed to match the actual product ID compared to 123.

Really appreciate your help Mark - thank you. I’m afraid I have more questions on the way!

1 Like

Bring it on! :wink: