putyourlightson/craft-sprig

Handling duplicate form controls

russback opened this issue · 2 comments

I have an ecommerce category page which has a sort select controls at the top and at the bottom of the sprig component.

When they both have the same name attribute, the usual setting of the passed value works fine:

{% set sort_by = sort_by ?? null %}

<select name="sort_by" sprig>...</select>

But when there is a second on the page, sort_by is always null.

As a workaround, I tried having them named sort_by_1 and sort_by_2 and then this logic:

{% set sort_by = sort_by_1 ??? sort_by_2 ??? null %}

But that leads to unexpected UX in that you don't alway get what you expected.

I then tried looking at some kind of htmx solution, having the first control like this:

<select name="sort_by" id="sort_by" sprig>...</select>

And the second like this:

<select name="sort_by_2" s-on:change="document.getElementById('sort_by').value = this.value">...</select>

That does set the value of the first control, but doesn't trigger a change, but this does:

<select name="sort_by_2" s-on:change="document.getElementById('sort_by').value = this.value;document.getElementById('sort_by').dispatchEvent(new Event('change'));">...</select>

Is there a better way of doing this that though?

Tweaking your logic should work since the values can come in as blank strings. Something like this perhaps?

{% set sort_by_1 = sort_by_1 ?? null %}
{% set sort_by_2= sort_by_2 ?? null %}
{% set sort_by = sort_by_1 ?: sort_by_2 %}

Alternatively, using your second approach:

<select s-on:change="htmx.find('#sort_by').value = this.value; htmx.trigger(this, 'refresh');">...</select>

Thanks @bencroker - that htmx approach feels more in keeping with sprig/twig than than the vanilla JS solution.