0

I have a form with two submit buttons with the same name but different values. If I submit the form with a GET action, no JS, the name and value of the the button triggering the submission are included in the URL parameters. However, when I listen to the submit event, the value of the submit button does not seem accessible in the same way other inputs are.

Why is the submit button value not included in the form data when accessing it from JS?

Reason

I have a page where I want to make a form where I let the browser do the most of the work. So, I don't want to have to attach click event listeners to each button when the form can emit a submit event, which it does.

Snippets

MCVE:

const form = document.querySelector('form')
const output = document.querySelector('ul')

form.addEventListener('submit', function (event) {
  event.preventDefault()
  const item = document.createElement('li')
  item.innerText = `Pressed button "${form.foo.value}": text field contains "${form.bar.value}"`
  output.appendChild(item)
})
<form>
  <input type="text" name="bar" value="sample input" />
  <button type="submit" name="foo" value="a">Action a</button>
  <button type="submit" name="foo" value="b">Action b</button>
</form>

<ul>

</ul>

MCVE but with FormData:

const form = document.querySelector('form')
const output = document.querySelector('ul')

form.addEventListener('submit', function (event) {
  event.preventDefault()
  const fd = new FormData(form)
  const item = document.createElement('li')
  item.innerText = `Pressed button "${fd.getAll('foo')}": text field contains "${fd.getAll('bar')}"`
  output.appendChild(item)
})
<form>
  <input type="text" name="bar" value="sample input" />
  <button type="submit" name="foo" value="a">Action a</button>
  <button type="submit" name="foo" value="b">Action b</button>
</form>

<ul>

</ul>
LarsW
  • 1,514
  • 1
  • 13
  • 25
  • 1
    There are two form elements with the name of `foo`....? – Taplar Apr 16 '20 at 22:11
  • @Taplar yep, that's the way radio buttons work too (and that's what suggested in a bunch of different questions) – LarsW Apr 16 '20 at 22:43
  • I know that is how radio buttons work, however `form.foo.value` seems suspect because there is no a single element in the form with the name of foo, so how is that supposed to work? – Taplar Apr 17 '20 at 14:34
  • @Taplar the `button` elements have the `name` of `foo` and that works fine when the form is submitted as a GET action – LarsW Apr 17 '20 at 15:06
  • I'm not talking about a form submit. I'm talking about your javascript trying to access a unique `foo` variable in a form, when there are multiple – Taplar Apr 17 '20 at 15:07
  • @Taplar I don't think I really get what you mean, that's exactly how it works with radio buttons (multiple `input` elements with the same `name`) and the same was suggested for `button` elements (https://stackoverflow.com/a/21778226/5095300) – LarsW Apr 17 '20 at 17:32
  • These are not radio buttons. They are normal buttons. – Taplar Apr 17 '20 at 17:32
  • So trying this out in a runnable fiddle, `console.log(form.foo)` returns a "RadioNodeList", not a single element. So that is how the browser handles two buttons having the same name. Which doing `.value` off of the list wouldn't make sense. You would `.value` off of one of the elements in the node list. – Taplar Apr 17 '20 at 17:35
  • @Tapar `.value` of the list is precisely how you get the value of a RadioNodeList, that's how it's defined in the spec. However, apparently that property is only set for radio button inputs so that's the problem. https://html.spec.whatwg.org/#the-htmlformcontrolscollection-interface – LarsW Apr 18 '20 at 11:10

0 Answers0