<p>It's definitely possible and doesn't really need any custom back end code to be done in general.  </p>

<p>Ultimately all add to cart options in Commerce are just a simple case of POSTing the variant id and the quantity of that variant.</p>

<p>Generally I would do this all in twig &amp; a bit of JS.  </p>

<p>E.g. In twig I wouldt loop through all variants (checking for stock as I go) and build up a JSON array of all the combinations of colour &amp; size, and their availability due to stock.  I'd then 'pass this into' my form as a <code>data-variants</code> attribute.</p>

<p>Actually building the selects is slightly trickier because one will depend on the other but basically you'd probably want some JS that listens to your selects and looks at your passed in array to see if a particular size and colour combination was in stock - if a chosen combination is not, some sort of visual indication and disable the add to cart button, otherwise if it is in stock the form just posts the variant id and the qty and away you go.</p>

<p><strong>Updated with some sample  code:</strong></p>

<p>Here's some untested/pseudo code that should get you on the right track:</p>

<p>so the important thing to understand is that the descriptive data of a variant is really a completely separate concern to the sku of the variant - which in turn is not actually all that relevant to commerce - the variant <code>id</code> is really all that matters in the end in terms of addToCart.  For specifiying the variant data you can do it any way you like really but in this case if it's just say 3 colours and 3 sizes, then a simple approach would be a dropdown for each of those, with handles <code>colour</code> and <code>size</code> say.  </p>

<p>You then just make the 9 variants, choose the colour and size for each, and enter the sku for each. </p>

<p>Then, you want to make the JSON for use in the JS.  (It's hard for me to see how you'd have a good UX without JS here, to be honest).</p>

<p>Here the <code>|jsonencode</code> filter is handy.  Something along the lines of:</p>

<pre><code>{% set stockArray = [] %}
{% for variant in product.variants %}
    {% set stockArray = stockArray|merge([{variantId:variant.id, 
                                          variantColourAndSize :variant.colour ~ "-" ~ variant.size,
                                          variantIsUnlimited:variant.unlimitedStock,
                                          variantStock:variant.stock, 
                                          }]) %}
{% endfor %}
</code></pre>

<p>Then you output your form and pass this consolidated data in to it so it's accessible in the JS:</p>

<pre><code>&lt;form id="OrderForm" 
    data-stockarray="{{ stockArray|json_encode() }}"
    data-action="/actions/multiAdd/multiAdd"
    data-redirect="/cart"
    etc

&gt;
&lt;selects here&gt;
</code></pre>

<p>The rest is really just JS operating on that json data - this is thoroughly pseudo code since it's Friday night :) - but should be enough to get the idea:</p>

<pre><code>var $form = document.getElementById('OrderForm');
var stockArray = $form.dataset.stockarray;
// Listen to your selects and look up in this array whether the matching colour/size variant is in stock/has unlimited stock
var variantKey = $select1.val() + "-" + $select2.val();
if(stockArray[variantKey].variantIsUnlimited || stockArray[variantKey].variantStock &gt; 0 ){
// Enable/Disable your add to cart button accordingly
    $addToCartButton.show();
}
else {
    $addToCartButton.hide();
}
</code></pre>

CC BY-SA 3.0
2016-05-20T08:45:10.547Z
Any code examples to go along with your explanation?
Luke Pearce
CC BY-SA 3.0
2016-05-20T09:01:06.587Z
If @jamescgarrett needs them, I'll be happy to help him along, here or in Slack.  When it comes to Commerce I'm pretty much always here or there :)
Jeremy Daalder
CC BY-SA 3.0
2016-05-20T16:37:26.817Z
This put me on the right track and I have it working! Thank you very much! Just being curious do you see any issue with the way I'm looping through the variant options?

{% for variant in product.variants[0].color.options %}<option value="{{variant.value}}">{{variant.label}}</option>{% endfor %}
jamescgarrett
CC BY-SA 3.0
2016-05-21T00:11:57.010Z
That should be fine I think, you're just grabbing the options from the first variant so I can't see any reason not to do that really.
Jeremy Daalder
CC BY-SA 3.0
2017-05-17T01:10:15.807Z
@JeremyDaalder, you're direction here has been really helpful for me too. I'm noticing though with the stockArray, using merge just overwrites the previous variant since all the keys are the same so I only get the last variant back in the JSON string. Is there a way to append this instead?
Tim Knight
CC BY-SA 3.0
2017-05-17T03:48:29.263Z
Hey Tim - yeah, I forgot the square brackets in the merge, added now above.  Each time `|merge` is called (with the appropriate brackets!) - it's now merging in an array (and for each variant the array will be different)
Jeremy Daalder
CC BY-SA 3.0
2016-05-19T23:46:25.847Z
2017-05-17T03:47:02.850Z
2017-05-17T03:47:02.850Z
Jeremy Daalder
<p>Is it possible to have separate variant option fields on a front end add to cart form?</p>

<p>For example… have a separate select field for <strong>Color</strong> and a separate select field for <strong>Size</strong>?</p>

<plugin-craftcommerce>
Is it possible to separate variant options on a front end add to cart form?
# Is it possible to separate variant options on a front end add to cart form?

(Asked by: username_0 on 2016-05-18)

Is it possible to have separate variant option fields on a front end add to cart form?

For example… have a separate select field for **Color** and a separate select field for **Size**?

**Tags:** plugin-craftcommerce


---

## 1 answers

### Answer by username_1 on 2016-05-19. Score: 5 | Accepted answer

It's definitely possible and doesn't really need any custom back end code to be done in general.  
Ultimately all add to cart options in Commerce are just a simple case of POSTing the variant id and the quantity of that variant.
Generally I would do this all in twig & a bit of JS.  
E.g. In twig I wouldt loop through all variants (checking for stock as I go) and build up a JSON array of all the combinations of colour & size, and their availability due to stock.  I'd then 'pass this into' my form as a data-variants attribute.
Actually building the selects is slightly trickier because one will depend on the other but basically you'd probably want some JS that listens to your selects and looks at your passed in array to see if a particular size and colour combination was in stock - if a chosen combination is not, some sort of visual indication and disable the add to cart button, otherwise if it is in stock the form just posts the variant id and the qty and away you go.
Updated with some sample  code:
Here's some untested/pseudo code that should get you on the right track:
so the important thing to understand is that the descriptive data of a variant is really a completely separate concern to the sku of the variant - which in turn is not actually all that relevant to commerce - the variant id is really all that matters in the end in terms of addToCart.  For specifiying the variant data you can do it any way you like really but in this case if it's just say 3 colours and 3 sizes, then a simple approach would be a dropdown for each of those, with handles colour and size say.  
You then just make the 9 variants, choose the colour and size for each, and enter the sku for each. 
Then, you want to make the JSON for use in the JS.  (It's hard for me to see how you'd have a good UX without JS here, to be honest).
Here the |jsonencode filter is handy.  Something along the lines of:
{% set stockArray = [] %}
{% for variant in product.variants %}
    {% set stockArray = stockArray|merge([{variantId:variant.id, 
                                          variantColourAndSize :variant.colour ~ "-" ~ variant.size,
                                          variantIsUnlimited:variant.unlimitedStock,
                                          variantStock:variant.stock, 
                                          }]) %}
{% endfor %}

Then you output your form and pass this consolidated data in to it so it's accessible in the JS:



The rest is really just JS operating on that json data - this is thoroughly pseudo code since it's Friday night :) - but should be enough to get the idea:
var $form = document.getElementById('OrderForm');
var stockArray = $form.dataset.stockarray;
// Listen to your selects and look up in this array whether the matching colour/size variant is in stock/has unlimited stock
var variantKey = $select1.val() + "-" + $select2.val();
if(stockArray[variantKey].variantIsUnlimited || stockArray[variantKey].variantStock > 0 ){
// Enable/Disable your add to cart button accordingly
    $addToCartButton.show();
}
else {
    $addToCartButton.hide();
}

> **Comments:**
> **username_2**: Any code examples to go along with your explanation?  
> **username_1**: If @username_0 needs them, I'll be happy to help him along, here or in Slack.  When it comes to Commerce I'm pretty much always here or there :)  
> **username_0**: This put me on the right track and I have it working! Thank you very much! Just being curious do you see any issue with the way I'm looping through the variant options?  {% for variant in product.variants[0].color.options %}<option value="{{variant.value}}">{{variant.label}}</option>{% endfor %}  
> **username_1**: That should be fine I think, you're just grabbing the options from the first variant so I can't see any reason not to do that really.  
> **username_3**: @JeremyDaalder, you're direction here has been really helpful for me too. I'm noticing though with the stockArray, using merge just overwrites the previous variant since all the keys are the same so I only get the last variant back in the JSON string. Is there a way to append this instead?  
> **username_1**: Hey Tim - yeah, I forgot the square brackets in the merge, added now above.  Each time `|merge` is called (with the appropriate brackets!) - it's now merging in an array (and for each variant the array will be different)  

---

