Discuss and resolve questions on Liquid, JavaScript, themes, sales channels, and site speed enhancements.
Hey there I want to display multiple option selectors ( one for color options / one for material etc. ) on the collection page in dawn theme with an add to cart button. I have implemented the code for the option selectors and the add to cart button but anyways its not working. I think I am missing a js function, but can't figure out how it should look.
When I have selected a prefered variant and click on add to cart it throws me the error "Required parameter missing or invalid: items"
This is the code of my custom-card-product.liquid file:
{% assign image_test = card_product.featured_media %}
<div class="custom-card-product-folder">
<!---<div class="custom-card-product-folder-2" id="folder-{{ card_product.id }}"></div>--->
<a href="{{ card_product.url }}" class="custom-card-product-product-image" style="background-image: url({{ card_product.featured_media| image_url: master}})"></a>
<h6 class="custom-card-product-product-title" >{{ card_product.title | escape }}</h6>
<div class="custom-card-product-product-price {% unless card_product.selected_or_first_available_variant.compare_at_price == blank %}red{% else %}black{% endunless %}"><span class="grey line-through {% unless card_product.selected_or_first_available_variant.compare_at_price == blank %}margin-right-ten{% endunless %}">{% unless card_product.selected_or_first_available_variant.compare_at_price == blank %}{% if card_product.metafields.custom.mehrere_preise_ %}Ab:{% endif %} {% endunless %} {{ card_product.selected_or_first_available_variant.compare_at_price | money}}</span>{% if card_product.selected_or_first_available_variant.compare_at_price == blank %}{% if card_product.metafields.custom.mehrere_preise_ %}Ab:{% endif %}{% endif %} {{ card_product.selected_or_first_available_variant.price | money}}</div>
<form method="post" action="/cart/add" class="relaunch-collection-product-form" style="display: flex;flex-direction: column;gap: 10px;margin-top: 10px;width: 80%;">
{%- unless card_product.has_only_default_variant -%}
<variant-selects class="no-js-hidden" data-section="{{ card_product.id }}" data-url="{{ card_product.url }}">
{%- for option in card_product.options_with_values -%}
<div class="product-form__input product-form__input--dropdown">
<label class="form__label" for="Option-{{ card_product.id }}-{{ forloop.index0 }}">
{{ option.name }}
</label>
<div class="select">
<select id="Option-{{ card_product.id }}-{{ forloop.index0 }}"
class="select__select"
name="options[{{ option.name | escape }}]"
form="{{ product_form_id }}"
>
{% if option.name == "Groeße" %}
{%- for value in option.values -%}
<option value="{{ value | escape }}" {% if option.selected_value == "6mm" %}selected="selected"{% endif %}>
{{ value }}
</option>
{%- endfor -%}
{% else %}
{%- for value in option.values -%}
<option value="{{ value | escape }}" {% if option.selected_value == value %}selected="selected"{% endif %}>
{{ value }}
</option>
{%- endfor -%}
{% endif %}
</select>
{% render 'icon-caret' %}
</div>
</div>
{%- endfor -%}
<script type="application/json">
{{ card_product.variants | json }}
</script>
</variant-selects>
{%- endunless -%}
<noscript class="product-form__noscript-wrapper-{{ card_product.id }}">
<div class="product-form__input{% if card_product.has_only_default_variant %} hidden{% endif %}">
<label class="form__label" for="Variants-{{ card_product.id }}">{{ 'products.product.product_variants' | t }}</label>
<div class="select">
<select name="id" id="Variants-{{ card_product.id }}" class="select__select" form="{{ product_form_id }}">
{%- for variant in card_product.variants -%}
<option
{% if variant == card_product.selected_or_first_available_variant %}selected="selected"{% endif %}
{% if variant.available == false %}disabled{% endif %}
value="{{ variant.id }}"
>
{{ variant.title }}
{%- if variant.available == false %} - {{ 'products.product.sold_out' | t }}{% endif %}
- {{ variant.price | money | strip_html }}
</option>
{%- endfor -%}
</select>
{% render 'icon-caret' %}
</div>
</div>
</noscript>
{%- form 'product', card_product, id: product_form_id, class: 'form', novalidate: 'novalidate', data-type: 'add-to-cart-form' -%}
<input type="hidden" name="id" value="{{ card_product.selected_or_first_available_variant.id }}" disabled>
<div class="product-form__buttons">
<button
type="submit"
name="add"
class="product-form__submit button button--full-width button--primary"
{% if card_product.selected_or_first_available_variant.available == false %}disabled{% endif %}
>
<span>
{%- if card_product.selected_or_first_available_variant.available -%}
{{ 'products.product.add_to_cart' | t }}
{%- else -%}
{{ 'products.product.sold_out' | t }}
{%- endif -%}
</span>
<div class="loading-overlay__spinner hidden">
<svg aria-hidden="true" focusable="false" role="presentation" class="spinner" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg">
<circle class="path" fill="none" stroke-width="6" cx="33" cy="33" r="30"></circle>
</svg>
</div>
</button>
</div>
{%- endform -%}
</form>
{%- if card_product.available == false -%}
<span class="custom-sold-out-badge">Ausverkauft</span>
{% endif %}
</div>
Keep in mind the perf hit to liquid rendering and html dom size in not only looping over products in a collection but then those products variant options.
Any collection templates should have the total number of products they display dialed back.
Alo see UX warnings about cramming more into less in this post before bloating collection templates:
Fast glance looks like there is no input for the actually needed variant.id needed by the cart ajax api, nor do the selects set an id as they are using option names for values.
Make sure to make any related javascript is also actually reference the relevant product-card that has it's add-to-cart button press and not simply the first product-card on the page.
Contact paull.newton+shopifyforum@gmail.com for the solutions you need
Save time & money ,Ask Questions The Smart Way
Problem Solved? ✔Accept and Like solutions to help future merchants
Answers powered by coffee Thank Paul with a ☕ Coffee for more answers or donate to eff.org
Shopify and our financial partners regularly review and update verification requiremen...
By Jacqui Mar 14, 2025Unlock the potential of marketing on your business growth with Shopify Academy's late...
By Shopify Mar 12, 2025Learn how to increase conversion rates in every stage of the customer journey by enroll...
By Shopify Mar 5, 2025