Hot to change Broadcast theme dropdown to native select

Anyone changed the variantpicker in Broadcast to a native select or styled it to have the same behavior? Need some input for what way to go here. The default one works fine for a few variants but when having 30+ it gets really messy as you need to scroll alot.

Thanks

1 Like

Just to confirm – you have Theme settings=> Product Form=> Show as boxes turned off?

To me this looks pretty similar to native select .

@rek1 please open the product page in customize settings and please check for the option to change it to normal drop down? you can check the settings given by @tim_1 or if you find it difficult then I can check it for you

Thank you both but yes that is the one I use (not boxes) , and it gets really messy with alot of variants as it’s limited in space and dosen’t show the selected one in the list when you open but starts with the first. But maybe just css and small script will fix it that instead of replacing it

Hi @rek1

Replace Broadcast Variant Picker With a Native <select> (Easiest + Most Stable)

This is the most straightforward solution.

Why do this?

  • Native dropdown handles unlimited options cleanly.
  • Works perfectly with Shopify’s variant-change JS in Broadcast.
  • Accessible, fast, and mobile-friendly.

How to implement

In snippets/product-variant-picker.liquid (or similar depending on Broadcast version):

Find the code that renders swatches/buttons, usually something like:

{% when 'button' %}
  <fieldset class="product-form__input">
    ...

Replace button/swatches rendering with:

<select
  name="options[{{ option.name }}]"
  class="product-form__select"
  data-option-position="{{ option.position }}"
>
  {% for value in option.values %}
    <option
      value="{{ value | escape }}"
      {% if option.selected_value == value %}selected{% endif %}
    >
      {{ value }}
    </option>
  {% endfor %}
</select>

Ensure Broadcast’s variant-change script still works
Broadcast uses an event listener on [name^="options"].

Because <select> still has:

name="options[Option Name]"

…it works automatically.
No JS edits required unless the theme is heavily modified already.

Best regards,
Devcoder :laptop:

Hey!
If you want something closer to a native select in Broadcast, the first thing to check is the theme settings.

Go to:
Theme settings → Product form → Show variants as boxes
Make sure that option is turned off.
When it’s off, the selector behaves almost exactly like a normal dropdown, even if you have a lot of variants.

If you already tried this and it still feels messy with 30+ options, you might need a small code change to force a native <select> element — Broadcast lets you customize that in the product-form snippet.

If you want, share your theme version and I can point you to the exact file.

1 Like

Thank you, it does render the select but it dosen’t work, keeps reseting to default values when changing. on a non js modified 8.0

1 Like

Hi, yes please! I use 8.0 (the boxes are turned off)

Yes, some Javascript is needed to scroll currently selected optoin into view.

Go to Customize=> Product page and add a “Custom Code” section.
Paste this code:

<style>
  /* make selected option more visible */
  .select-popout__item[selected] { 
    background: var(--COLOR-BG-ACCENT);
  }
  /* make drop-down higher. default is 300xp */
  popout-select.product-form__input .select-popout__list {
    max-height: min(500px, calc(100svh - 40px));
  }
</style>

<script>
(()=>{
  const mo = new MutationObserver( records => {
    let selected = records
      .map( r => r.target )
      .filter( t => t.classList.contains('select-popout__toggle') 
                    && t.ariaExpanded=='true' )
      .map( b => b.nextElementSibling?.querySelector('[selected]') );
    
    for (const p of selected) {
        let top = p.offsetTop;
        let height = p.parentElement.offsetHeight;
        if ( top > height ) p.parentElement.scrollTo(0, top);
    }
  });
  
  mo.observe( 
    document, 
    { attributes: true, subtree: true, attributeFilter: ['aria-expanded'] }
  );
})();
</script>

if my post is helpful, please like it ♡ and mark as a solution -- this will help others find it