Getting product variant ID from product.options

Highlighted
New Member
2 0 0

Photos below!

 

So I'm working on creating a little bit of code to dynamically generate add to cart buttons and corresponding variant menus within the Debut theme so customers visiting our shop can add items to cart from the collections pages without needing to select an individual collection.  I found the most basic code for this on the forums here, but I wanted to go a little further with it and add a drop-down selection menu for all the various options each variant of one of our collections has.  I've managed to achieve most of this with the following code, which loops through each product for unique options and then adds items to a selection menu based off potential unique choices found within each option:
 

<form method="post" action="/cart/add">
      {% if product.variants.size > 1 %}
            {% for option in product.options %}
            	<label for="SingleOptionSelector-{{forloop.index0}}"> {{ option }} </label>
            	<select id="SingleOptionSelector-{{forloop.index0}}" class="single-option-selector single-option-selector-product-template product-form__input" data-index="option{{forloop.index}}" name="id">
    				{% capture option_index %}option{{ forloop.index }}{% endcapture %} 
    				{% assign option_values = product.variants | map: option_index | uniq %}
                    {% for choice in option_values %}
                 		<option value="{{ choice }}"> {{ choice }} </option>
                  	{% endfor %}
            	</select>
            {% endfor %}
            {% endif %}
            
            <input min="1" type="number" id="quantity" name="quantity" value="1"/>
  			<input type="submit" value="Add to cart" class="btn" />
</form>

 

However, the problem I'm running into is that I lack the ability to take the selections from these different drop-down menus and tie them to a specific variant ID, resulting in them being unable to add to cart due to the error of "array contains unpermitted members: id," which I've pinpointed to being a lack of proper variant or product id tied to the selection upon submission.  I have a much simpler solution that only has one drop-down menu for each individual variant title, but this is suboptimal for my use case as we have bundle packages that require multiple different selections, and results in drop-down menus that are 20 or more items long of mostly redundant items.  I've attached this code as well though, as it might help someone who only has one-option variants:

 

<form method="post" action="/cart/add">
 {% if product.variants.size > 1 %}
            	<label for="SingleOptionSelector-0">Select a size</label>
					<select id="SingleOptionSelector-0" class="single-option-selector single-option-selector-product-template product-form__input" data-index="option1" name="id">
  						{%for variant in product.variants %}
                     		<option value="{{ variant.id }}"> {{ variant.title }} </option>
                      	{% endfor %}
				</select>
            <input min="1" type="number" id="quantity" name="quantity" value="1"/>
  			<input type="submit" value="Add to cart" class="btn" />
</form>


Alternatively if someone out there knows how to dynamically generate these kinds of drop-down menus in the collections page while also creating the <select id="ProductSelect-product-template" class="product-form__variants no-js" name="id" data-productid="{{product.id}}"> hidden menu that appears in the individual collection selection page, I'd love some help with this.

I've attached a photo with my dynamically-generated menus, each menu inherits the Option name from the product ID and displays it as a label, all of the different selections within that option tree are also pulled and added as selections to the menuI've attached a photo with my dynamically-generated menus, each menu inherits the Option name from the product ID and displays it as a label, all of the different selections within that option tree are also pulled and added as selections to the menu

 

 

This is a demonstration of the second snippet of code which will add the item to cart properly, but unfortunately results in these exorbantly long menus that are just awful to work with, so I'd like to avoid it if possibleThis is a demonstration of the second snippet of code which will add the item to cart properly, but unfortunately results in these exorbantly long menus that are just awful to work with, so I'd like to avoid it if possible

0 Likes
Highlighted
New Member
2 0 0

ALRIGHT I figured it out myself.  For anybody interested in dynamically-generated drop down menus for variant selection in their collections screen, the entire code is:

          <form method="post" action="/cart/add">
            {% if product.variants.size > 1 %}
                {% for option in product.options %}
            	<label for="SingleOptionSelector-{{forloop.index0}}"> {{ option }} </label>
            	<select id="SingleOptionSelector-{{forloop.index0}}" class="single-option-selector single-option-selector-product-template product-form__input" data-index="option{{forloop.index}}" name="id">
    				{% capture option_index %}option{{ forloop.index }}{% endcapture %} 
    				{% assign option_values = product.variants | map: option_index | uniq %}
                    {% for choice in option_values %}
                 		<option value="{{ choice }}"> {{ choice }} </option>
                  	{% endfor %}
            	</select>
            
            	{% endfor %}
            	<select id="ProductSelect-product-template" class="product-form__variants no-js" name="id" data-productid="{{product.id}}">
                  	{% for option in product.variants %}
                 		 <option value="{{option.id}}"> {{option.title}}</option>
                  	{% endfor %}
            	</select>
            {% endif %}
            
            <input min="1" type="number" id="quantity" name="quantity" value="1"/>
  			<input type="submit" value="Add to cart" class="btn" />
		</form>

The second <select></select> is the key to retrieving the proper variant ID to feed into the submission, which basically loops through every possible variant in each product in the stack and builds a hidden option from the variant id and the title.

0 Likes
Highlighted
Tourist
7 0 1

Hi there,

Thank you, this is very useful as I'm trying to do this for my store too!  May I ask where you inserted this code?

0 Likes
Highlighted
New Member
1 0 0

I am having the same issue and tried to implement your code and I am still having the issue that only the last dropdown with the actual variants is being reflected into the cart after add. If I choose different options from my first 2 drop downs (size and color) those sizes and colors don't get added to the cart. Are you having this issue? It's very frustrating that shopify has made it so hard to loop through unique variants.

0 Likes
Highlighted

Hi @ViteEris 

Thanks, the trick for the 2nd hidden drop-down list is useful. I am also making a special collection page to show all products with variant options. The user can select the variant and add to cart.

However, I have a question regarding performance. For a collection, it will show all options and all variants of all products. Did you do any pagination? Will the rendering become slow if the collection has more than a hundred products?

SPO - SEO App to research keywords & edit social link preview
0 Likes