htmx icon indicating copy to clipboard operation
htmx copied to clipboard

Using the same `name` attribute on multiple HTML form elements results in only first value being sent

Open vrzh opened this issue 2 years ago • 3 comments

Greatly enjoying using htmx!

I have an issue with HTML forms. I have multiple form elements that share the same value for name. If an ordinary HTML POST is done, I receive all values. But, if htmx is used, then I receive only the first value.

I provide a contrived minimal example below, where I want to send a default "action" value that can be "overridden" by different submit buttons. A similar trick can be used to send a "default" value when a checkbox is not checked. Or, if you just want to send a list of values to the server.

If you click on button "C" of the "HTML" form, the server receives something like [('action', 'A'), ('action', 'C')], as expected.

However, if you click on button "C" of the "htmx" form, the server receives only [('action', 'A')].

Printing out evt.detail.parameters when the htmx:configRequest event occurs also shows a single value.

Is this a bug? Or is there some way to hook into htmx to get the same behaviour?

Example:

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
  </head>
  <body>

    <h3>HTML</h3>
    <form action="/submit-html" method="POST">
        <input type="hidden" name="action" value="A">
        <button type="submit">A</button>
        <button type="submit">A</button>
        <button type="submit" name="action" value="B">B</button>
        <button type="submit" name="action" value="C">C</button>
    </form>

    <h3>htmx</h3>
    <form hx-post="/submit-htmx" method="POST">
        <input type="hidden" name="action" value="A">
        <button type="submit">A</button>
        <button type="submit">A</button>
        <button type="submit" name="action" value="B">B</button>
        <button type="submit" name="action" value="C">C</button>
    </form>

    <script src="https://unpkg.com/[email protected]"></script>

    <script>
        document.body.addEventListener('htmx:configRequest', function(evt) {
            console.log(evt.detail.parameters);
        });
    </script>

  </body>
</html>

vrzh avatar Jul 05 '23 15:07 vrzh

I would say that not behaving as a form element does by default, is a bug "by definition", but I may be wrong. I think it's due to this line that explicitly ignores any value attached to a button The comment here says

// ignore "submitter" types (see jQuery src/serialize.js)

So it seems to be voluntary? May I invoke you @1cg there? As it could be related to the "philosophy" of the lib maybe?

Telroshan avatar Jul 05 '23 15:07 Telroshan

I think it's due to this line that explicitly ignores any value attached to a button

This seems to work fine:

<form hx-post="/submit-htmx" method="POST">
    <button type="submit" name="action" value="A">A</button>
    <button type="submit" name="action" value="A">A</button>
    <button type="submit" name="action" value="B">B</button>
    <button type="submit" name="action" value="C">C</button>
</form>

I get the single value for action depending on what button is clicked. Issue occurs when the hidden element is added which acts the "default" value.

vrzh avatar Jul 06 '23 06:07 vrzh

Oh you're right, looked further into it

  • This if statement first includes the clicked button's value in the generated payload
  • But then this following statement merges the clicked button's value + any hx-include value, with the form values, the latter overriding other values as said in the comment here

// form values take precedence, overriding the regular values

So in your case, it works without the hidden element because the value isn't overridden, as no other input declares the same name But with the hidden input, it overrides the value from the clicked button

It seems to me we should simply move that if statement (with the button check & value retrieval), to be after the merge call, to have that value precisely stack over any form value. But again, I may be missing something there

Telroshan avatar Jul 06 '23 07:07 Telroshan

Resolved by #1559

alexpetros avatar Sep 20 '23 22:09 alexpetros

Seems to us the problem is resolved only partially, specifically for the submit button. In our case having the hx-trigger on input or change and hx-include': "#user_config" where the user_config is the id of a div with a bunch of forms where each input has the same name only a single value is obtained for a single name.

I'll try to update this comment with a minimal example ASAP, this week for sure.

Huge avatar Jul 30 '24 08:07 Huge

That might be an hx-include bug? In either case when you have a repo, feel free to open a new bug and link it here.

alexpetros avatar Aug 09 '24 15:08 alexpetros