How to edit Dawn theme for different option selectors in product listing?

Topic summary

Issue: A user wants to customize the Dawn theme’s product listing to display the first option selector as pills and the second as a dropdown (due to many variants). Initial code modifications caused products to show as “unavailable” when options were selected.

Problem Details:

  • The two selector sections (radio buttons and dropdown) operate independently
  • Each section’s hidden fields override the other’s selections
  • Users appear to make selections, but the system only captures values from one option field at a time
  • This results in incorrect variants being added to cart

Attempted Solutions:

  • LitCommerce provided code that initially seemed to work but ultimately failed
  • Multiple users confirmed the code doesn’t properly synchronize both option selectors
  • One user suggested the issue may relate to Dawn version differences (Dawn 13 introduced changes to variant-selects)

Working Solution:

  • User jonasweibull provided a simple approach: Set Variant picker Style to “Dropdown” in theme settings, then edit the product-variant-picker.liquid snippet using forloop.first to render only the first option as pills
  • User maapaa02 shared code using JavaScript to synchronize radio inputs and select dropdowns with data-handle attributes and event listeners

Status: Solutions provided, though implementation requires technical customization of theme files.

Summarized with AI on November 3. AI used: claude-sonnet-4-5-20250929.

Hi,

I am trying to edit the Dawn theme such that the product listing has the first option selector as a pill and the second option selector as dropdown as I have many variants under the second option and the pill layout doesn’t look good with so many pills.

I have edited the main-product.liquid variant picker code as follows and while it looks right when rendered, as soon as I choose any option on the product page it says that the product is unavailable which is not correct. I think it is trying to verify the selection against the variants in the json file and failing, but this is a hunch. Can anyone help.

          {%- when 'variant_picker' -%}
            {%- unless product.has_only_default_variant -%}
                <variant-radios class="no-js-hidden" data-section="{{ section.id }}" data-url="{{ product.url }}" {{ block.shopify_attributes }}>
                  {%- for option in product.options_with_values -%}
                    {% if forloop.first %}
                      <fieldset class="js product-form__input">
                        <legend class="form__label">{{ option.name }}</legend>
                        {%- for value in option.values -%}
                          <input type="radio" id="{{ section.id }}-{{ option.position }}-{{ forloop.index0 }}"
                                name="{{ option.name }}"
                                value="{{ value | escape }}"
                                form="{{ product_form_id }}"
                                {% if option.selected_value == value %}checked{% endif %}
                                  {%- for variant in product.variants -%}
                                    {% if value == variant.title %}
                                      {% if variant.available == false %}class="outofstock"
                                        {% endif %}
                                    {% endif %}
                                  {%- endfor -%}
                          >
                          <label for="{{ section.id }}-{{ option.position }}-{{ forloop.index0 }}"
                                                    
                                  {%- for variant in product.variants -%}
                                    {% if value == variant.title %}
                                      {% if variant.available == false %}class="outofstock"
                                        {% endif %}
                                    {% endif %}
                                  {%- endfor -%}
              
                          >
                            {{ value }}
                          </label>
                        {%- endfor -%}
                      </fieldset>
                  {%- else -%}
                    <div class="product-form__input product-form__input--dropdown">
                      <label class="form__label" for="Option-{{ section.id }}-{{ forloop.index0 }}">
                        {{ option.name }}
                      </label>
                      <div class="select">
                        <select id="Option-{{ section.id }}-{{ forloop.index0 }}"
                          class="select__select"
                          name="options[{{ option.name | escape }}]"
                          form="{{ product_form_id }}"
                        >
                          {%- for value in option.values -%}
                            <option value="{{ value | escape }}" {% if option.selected_value == value %}selected="selected"{% endif %}>
                              {{ value }}
                            </option>
                          {%- endfor -%}
                        </select>
                        {% render 'icon-caret' %}
                      </div>
                    </div>                      
                  {%- endif -%}
                  {%- endfor -%}
                  <script type="application/json">
                    {{ product.variants | json }}
                  </script>
                </variant-radios>
            {%- endunless -%}

            <noscript class="product-form__noscript-wrapper-{{ section.id }}">
              <div class="product-form__input{% if product.has_only_default_variant %} hidden{% endif %}">
                <label class="form__label" for="Variants-{{ section.id }}">{{ 'products.product.product_variants' | t }}</label>
                <div class="select">
                  <select name="id" id="Variants-{{ section.id }}" class="select__select" form="{{ product_form_id }}">
                    {%- for variant in product.variants -%}
                      <option
                        {% if variant == 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>

Thanks,

Online_Seller

Hi @Online_Seller ,

Please change all code:

{%- when 'variant_picker' -%}
            {%- unless product.has_only_default_variant -%}
                
                
            {%- endunless -%}

            

Hope it helps!

2 Likes

Exactly what I was trying to achieve.

Thanks!!

Online_Seller

1 Like

Would love to know how this code works. It changes the first, but the other 2 options are drop downs. Would love to know so the first 2 options could be radio buttons and the last could be checkmarks.

@LitCommerce Soo…

It turns out that this doesn’t work after all.

Whilst it solves the ‘product is unavailable’ issue the variants that are returned are not correct.

The two sections are acting independently of each other. The radio/buttons/pill for the first section at acting independent of the dropdown.

Updating the field then makes that section override the selection, which means that the hidden fields in each section are overriding the selected field from the other section.

IE

changing option 1 makes option 2 change to default (but doesn’t appear to the user to be doing so)

AND

changing option 2 makes option 1 change to default (but doesn’t appear to the user to be doing so)

But in each case it appears to the user that their selections are chosen, but in reality it is taking either option 1 or option 2 value from the hidden field.

They don’t realise and then put this item in the basket.

EEK… HELP!

Online_Seller

1 Like

This code not properly work changes the value of option in dropdown but in radio it selected only first option

1 Like

Yes, I am also facing the same situation. Maybe the problem is with the Dawn version, not the code. Recently Dawn 13 has been released and it doesn’t have any “variant-radios”. Everything is within “variant-selects”. Now, this functionality can be achieved very easily.

use this code this works properly

{%- unless product.has_only_default_variant -%}
<variant-radios class=“no-js-hidden” data-section=“{{ section.id }}” data-url=“{{ product.url }}” {{ block.shopify_attributes }}>
{%- for option in product.options_with_values -%}

{{ option.name }} {%- for value in option.values -%} {{ value }} {%- endfor -%} {%- endfor -%} {%- for option in product.options_with_values -%}
{{ option.name }}
{% render 'icon-caret' %}
{%- endfor -%} {%- endunless -%}
{{ 'products.product.product_variants' | t }}
{% render 'icon-caret' %}

This must be a fairly common need, and I have had a hard time finding a solution that works by googling. Therefore, here is a simple solution that I have come up with, even though it has been two years since the question was asked:

I am using Dawn and solved it by, firstly, setting Variant picker Style to Dropdown and then, secondly, editing the product-variant-picker.liquid snippet, using forloop.first to render the first option as pills.