Blocking "buy it now" button when I choose the variants

Topic summary

A developer modified their product variant picker code to display color options as swatches and size options as dropdowns. They removed the render tag for “product-variant-options” and rewrote the entire code directly in “product-variant-picker.liquid”.

Issue encountered:
After implementing these changes, the “Buy It Now” button becomes blocked or non-functional when selecting product variants.

Code shared:
The user provided their custom liquid code showing:

  • Logic for handling variant availability
  • Conditional rendering based on option names (Color vs other options)
  • Custom fieldset implementation for color swatches

Current status:
The discussion appears to be seeking troubleshooting help to resolve the button blocking issue. No solutions or responses have been provided yet. The problem likely stems from JavaScript event handling or variant selection logic in the custom implementation.

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

I made some changes in my code to show swatches if the variant option is colors and dropdown if its sizes. I removed the render tag for “product-variant-options” and wrote the entire code on the “product-variant-picker.liquid”.

{% comment %}
  Renders product variant-picker

  Accepts:
  - product: {Object} product object.
  - block: {Object} passing the block information.
  - product_form_id: {String} Id of the product form to which the variant picker is associated.
  - update_url: {Boolean} whether or not to update url when changing variants. If false, the url isn't updated. Default: true (optional).
  Usage:
  {% render 'product-variant-picker', product: product, block: block, product_form_id: product_form_id %}
{% endcomment %}

{%- liquid
  assign variants_available_arr = product.variants | map: 'available'
  assign variants_option1_arr = product.variants | map: 'option1'
  assign variants_option2_arr = product.variants | map: 'option2'
  assign variants_option3_arr = product.variants | map: 'option3'

  assign product_form_id = 'product-form-' | append: section.id
-%}

{% unless has_only_default_variant %}

  {% for option in product.options_with_values %}
    {% if option.name == 'Color' %}
      <variant-radios id="variant-radios-{{ section.id }}" class="no-js-hidden" data-section="{{ section.id }}" data-url="{{ product.url }}" {% if update_url == false %}data-update-url="false"{% endif %} {{ block.shopify_attributes }}>
        <fieldset class="js product-form__input">
          <legend class="form__label">{{ option.name }}</legend>
            {% for value in option.values %}
              {%- liquid
              assign option_disabled = true
          
              for option1_name in variants_option1_arr
                case option.position
                  when 1
                    if variants_option1_arr[forloop.index0] == value and variants_available_arr[forloop.index0]
                      assign option_disabled = false
                    endif
                  when 2
                    if option1_name == product.selected_or_first_available_variant.option1 and variants_option2_arr[forloop.index0] == value and variants_available_arr[forloop.index0]
                      assign option_disabled = false
                    endif
                  when 3
                    if option1_name == product.selected_or_first_available_variant.option1 and variants_option2_arr[forloop.index0] == product.selected_or_first_available_variant.option2 and variants_option3_arr[forloop.index0] == value and variants_available_arr[forloop.index0]
                      assign option_disabled = false
                    endif
                endcase
              endfor
            -%}
            <input type="radio" id="{{ section.id }}-{{ option.position }}-{{ forloop.index0 }}" name="{{ option.name }}" form="{{ product_form_id }}" {% if option.selected_value == value %} checked {% endif %} {% if option_disabled %} class="disabled" {% endif %}>
            <label for="{{ section.id }}-{{option.position}}-{{forloop.index0}}">
              {{ value -}}
              <span class="visually-hidden">{{ 'products.product.variant_sold_out_or_unavailable' | t }}</span>
            </label>
            {% endfor %}
        </fieldset>
        <script type="application/json">
          {{ product.variants | json }}
        </script>
      </variant-radios>
    {% else %}
      <variant-selects id="variant-selects-{{ section.id }}" class="no-js-hidden" data-section="{{ section.id }}" data-url="{{ product.url }}" {% if update_url == false %}data-update-url="false"{% endif %} {{ block.shopify_attributes }}>
          <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 %}
                  {%- liquid
                    assign option_disabled = true

                    for option1_name in variants_option1_arr
                      case option.position
                        when 1
                          if variants_option1_arr[forloop.index0] == value and variants_available_arr[forloop.index0]
                            assign option_disabled = false
                          endif
                        when 2
                          if option1_name == product.selected_or_first_available_variant.option1 and variants_option2_arr[forloop.index0] == value and variants_available_arr[forloop.index0]
                            assign option_disabled = false
                          endif
                        when 3
                          if option1_name == product.selected_or_first_available_variant.option1 and variants_option2_arr[forloop.index0] == product.selected_or_first_available_variant.option2 and variants_option3_arr[forloop.index0] == value and variants_available_arr[forloop.index0]
                            assign option_disabled = false
                          endif
                      endcase
                    endfor
                  -%}
                  <option
                  value="{{ value | escape }}"
                  {% if option.selected_value == value %}
                    selected="selected"
                  {% endif %}
                  >
                  {% if option_disabled -%}
                    {{- 'products.product.value_unavailable' | t: option_value: value -}}
                  {%- else -%}
                    {{- value -}}
                  {%- endif %}
                </option>
                {% endfor %}
              </select>
              {% render 'icon-caret' %}
            </div>
        </div>
        <script type="application/json">
        {{ product.variants | json }}
        </script>
      </variant-selects>
    {% endif %}
  {% endfor %}
  
{% 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 }}"
          >
            {%- liquid
              echo variant.title
              echo variant.price | money | strip_html | prepend: ' - '
              if variant.available == false
                echo 'products.product.sold_out' | t | prepend: ' - '
              endif
              if variant.quantity_rule.increment > 1
                echo 'products.product.quantity.multiples_of' | t: quantity: variant.quantity_rule.increment | prepend: ' - '
              endif
              if variant.quantity_rule.min > 1
                echo 'products.product.quantity.minimum_of' | t: quantity: variant.quantity_rule.min | prepend: ' - '
              endif
              if variant.quantity_rule.max != null
                echo 'products.product.quantity.maximum_of' | t: quantity: variant.quantity_rule.max | prepend: ' - '
              endif
              # TODO: enable theme-check once `item_count_for_variant` is accepted as valid filter
              # theme-check-disable
              assign cart_quantity = cart | item_count_for_variant: variant.id
              # theme-check-enable
              if cart_quantity > 0
                echo 'products.product.quantity.in_cart_html' | t: quantity: cart_quantity | prepend: ' - '
              endif
            -%}
          </option>
        {%- endfor -%}
      </select>
      {% render 'icon-caret' %}
    </div>
  </div>
</noscript>