Skip to content

Commerce Foundations is our pre-built Craft Commerce store. See what it includes

Craft CMS plugins

Variant Manager

A Craft CMS plugin that imports and exports Craft Commerce product variants from CSV files.

Variant filter

Filter variants based on a selection

Filter by all selected values#

Sprig#

{% set product = craft.products.id(productId).one() %}
{% set variantId = variantId ?? null %}
{% set selection={} %}

<h1>{{ product.title }}</h1>
<div>
  {% for attribute in craft.variantManager.getAttributeOptions(productId) %}
    {# Use _context to get a variable from a string #}
    {% set selected = _context['attributeValue_' ~ loop.index] ?? (selection[attribute.name] ?? null) %}

    {% if selected is not null and selected != '' %}
      {% set selection = selection|merge({(attribute.name): selected}) %}
    {% endif %}
    <div>
      <label>
        {{ attribute.name }} - {{ selected }}
        <select sprig name="attributeValue_{{ loop.index }}">
          <option value="" {{ selected is null or selected == '' ? 'selected' }}>Select an option</option>
          {% for value in attribute.values %}
            <option value="{{ value }}" {{ selected == value ? 'selected' }}>{{ value }}</option>
          {% endfor %}
        </select>
      </label>
    </div>
  {% endfor %}
</div>

<ul>
  {# 
    NOTE: The "variantAttributes" below in this example should be the handle of the
    Variant Attributes field you created and have added to your variant fields layout
  #}
  {% for variant in craft.variants().productId(productId).variantAttributes(selection).all() %}
    <li>
      {{ variant.sku }} - {{ variant.price|commerceCurrency }}
    </li>
  {% endfor %}
</ul>

Alpine.js#

{% set product = craft.products.id(productId).one() %}
{% set variantId = variantId ?? null %}
{% set selection={} %}

<h1>{{ product.title }}</h1>
<div>
  {% for attribute in craft.variantManager.getAttributeOptions(productId) %}
    {% set selected = craft.app.request.getParam('attributeValue_' ~ loop.index) ?? (selection[attribute.name] ?? null) %}

    {% if selected is not null and selected != '' %}
      {% set selection = selection|merge({(attribute.name): selected}) %}
    {% endif %}
    <div>
      <label>
        {{ attribute.name }} - {{ selected }}
        <select name="attributeValue_{{ loop.index }}" @change="attributeChanged">
          <option value="" {{ selected is null or selected == '' ? 'selected' }}>Select an option</option>
          {% for value in attribute.values %}
            <option value="{{ value }}" {{ selected == value ? 'selected' }}>{{ value }}</option>
          {% endfor %}
        </select>
      </label>
    </div>
  {% endfor %}
</div>

<ul>
  {# 
    NOTE: The "variantAttributes" below in this example should be the handle of the
    Variant Attributes field you created and have added to your variant fields layout
  #}
  {% for variant in craft.variants().productId(productId).variantAttributes(selection).all() %}
    <li>
      {{ variant.sku }} - {{ variant.price|commerceCurrency }}
    </li>
  {% endfor %}
</ul>

{% js %}
  function attributeChanged(e) {
    let queryParams = new URLSearchParams(window.location.search)

    queryParams.set(e.target.name, e.target.value);
    window.location.search = queryParams.toString()
  }
{% endjs %}

Filter by any of the selected values#

Note that the difference between the previous section and this section is that the selection is an array of objects instead of an object.

Sprig#

{% set product = craft.products.id(productId).one() %}
{% set selection=[] %}

<h1>{{ product.title }}</h1>
<div>
  {% for attribute in craft.variantManager.getAttributeOptions(productId) %}
    {% set selected = _context['attributeValue_' ~ loop.index] ?? (selection[attribute.name] ?? null) %}

    {% if selected is not null and selected != '' %}
      {% set selection = selection|merge([{(attribute.name): selected}]) %}
    {% endif %}
    <div>
      <label>
        {{ attribute.name }} - {{ selected }}
        <select sprig name="attributeValue_{{ loop.index }}">
          <option value="" {{ selected is null or selected == '' ? 'selected' }}>Select an option</option>
          {% for value in attribute.values %}
            <option value="{{ value }}" {{ selected == value ? 'selected' }}>{{ value }}</option>
          {% endfor %}
        </select>
      </label>
    </div>
  {% endfor %}
</div>

<ul>
  {# 
    NOTE: The "variantAttributes" below in this example should be the handle of the
    Variant Attributes field you created and have added to your variant fields layout
  #}
  {% for variant in craft.variants().productId(productId).variantAttributes(selection).all() %}
    <li>
      {{ variant.sku }} - {{ variant.price|commerceCurrency }}
    </li>
  {% endfor %}
</ul>

Alpine.js#

{% set product = craft.products.id(productId).one() %}
{% set selection=[] %}

<h1>{{ product.title }}</h1>
<div>
  {% for attribute in craft.variantManager.getAttributeOptions(productId) %}
    {% set selected = craft.app.request.getParam('attributeValue_' ~ loop.index) ?? (selection[attribute.name] ?? null) %}

    {% if selected is not null and selected != '' %}
      {% set selection = selection|merge([{(attribute.name): selected}]) %}
    {% endif %}
    <div>
      <label>
        {{ attribute.name }} - {{ selected }}
        <select name="attributeValue_{{ loop.index }}" @change="attributeChanged">
          <option value="" {{ selected is null or selected == '' ? 'selected' }}>Select an option</option>
          {% for value in attribute.values %}
            <option value="{{ value }}" {{ selected == value ? 'selected' }}>{{ value }}</option>
          {% endfor %}
        </select>
      </label>
    </div>
  {% endfor %}
</div>

<ul>
  {# 
    NOTE: The "variantAttributes" below in this example should be the handle of the
    Variant Attributes field you created and have added to your variant fields layout
  #}
  {% for variant in craft.variants().productId(productId).variantAttributes(selection).all() %}
    <li>
      {{ variant.sku }} - {{ variant.price|commerceCurrency }}
    </li>
  {% endfor %}
</ul>
{% js %}
  function attributeChanged(e) {
    let queryParams = new URLSearchParams(window.location.search)

    queryParams.set(e.target.name, e.target.value);
    window.location.search = queryParams.toString()
  }
{% endjs %}

We can take it from here.

We take on the Craft and Craft Commerce sites you built, so you can get back to building. Introduce a client who signs a management contract and you get a $3,000 partnership fee.

How the Dev Partnership Program works
See if we’re a fit