Give Your Buttons a Type
— 2 minute read
I fixed a bug at work today where hitting the “Enter” key from a text input in
an accordion form, in addition to submitting the form via a keydown
listener1, would collapse the current section of the accordion, open the
next section, and open a dropdown attached to a button in that section. If a
user hit Enter a second time quickly enough, instead of submitting the text they
entered in the first section of the form, the empty second section would be
submitted, taking the user to an entirely different page.
This is an obvious usability problem with a less obvious, but also
usability-related solution, and it’s something I had actually come across
before. It’s typical to use an HTML button
to submit a form, and occasionally
another button
to reset the form:
<form>
<input type="text" name="name" value="Jesse B. Hannah" />
<button type="reset">Reset</button>
<button type="submit">Submit</button>
</form>
But buttons have other purposes too; if your form is in a modal, you might have a “Cancel” button that closes the modal instead of just a “Reset” button:
<form>
<input type="text" name="name" value="Jesse B. Hannah" />
<button onclick="dismissModal()">Cancel</button> <button type="submit">Submit</button>
</form>
If the user is like me, and likes to use the keyboard to navigate and submit
forms, they might just type in their name and hit enter, and then be completely
baffled when the modal closes without submitting the form. This happens because
buttons have a default type
of submit
, so the first button
in the form
catches the enter keypress and, in this case, closes the modal. Solve this by
remembering to explicitly give every button a type
:
<form>
<input type="text" name="name" value="Jesse B. Hannah" />
<button type="button" onclick="dismissModal()">Cancel</button> <button type="submit">Submit</button>
</form>
In terms of both semantics and usability, it’s generally a good idea to not
always rely on the default type
of an element. I tend to be more explicit
about attributes as a matter of personal preference, but also because of edge
cases like this where the default behavior might not be what you expect. For
buttons specifically, any button that is not the submit or reset button of the
form should be given type="button"
. Remember to do that upfront, and it will
save you from a lot of weird and tricky-to-spot bugs later.
-
I know, but it’s a weird form where “Enter” is supposed to do different things in different inputs. Namely, in some inputs it fills in the current autocomplete value, where in others it submits the form immediately even if an autocomplete value is selected. Generally speaking, you should use a
↩<button type="submit" />
to handle submitting forms on “Enter.”