Form input inconsistencies
The <input> element and the <select> element submit different values to the backend, depending on how you use 'em.
Here's a question for you: imagine that you've got an HTML form something like this:
<form action="/" method="POST"> <label for="name">Your name</label> <input name="name" type="text" /> <!-- This select purposely left blank --> <label for="favourite_food">Your favourite food</label> <select name="favourite_food"></select> <button type="submit">Save preferences</button> </form>
Now imagine that a user clicks the Save preferences button and submits the form. What does the network payload look like? I thought that it would look something like
name=&favourite_food=—that is to say, that the
favourite_food variables would be submitted as empty strings—but that's not the case.
It submits instead
firstname=, and that's it. The empty
<select> is ignored. Same goes for if you pull the ol' select placeholder trick:
<!-- Won't be submitted either --> <select name="favourite_food"> <option selected disabled hidden>Choose a food...</option> </select>
Can't seem to find anything about it on MDN—hopefully this helps someone else struggling to find their data on the backend!
Update: As Šime Vidas points out on Twitter, this is because "only non-disabled, selected <option> element values are added to the form’s 'entry list'", according to the HTML spec. Which means that the following won't be submitted either either:
<select name="favourite_food" value="Cake"></select>
So the actual value of the select comes from the
<option>, not the
<select> itself. I love to find out that HTML elements fit together like that. And it also means, given the above select:
const select = document.querySelector('[name="favourite_food"]'); console.log(select.value) // => ""