htmx
htmx copied to clipboard
Using the same `name` attribute on multiple HTML form elements results in only first value being sent
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>
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?
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.
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
Resolved by #1559
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.
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.