In vanilla JS, the .elements property of the HTMLFormElement interface is a convenient way to reference the fields inside a <form> element.

Given the following HTML for a contact form:

<form id="contact-form">
<p>
<label for="name">Name</label>
<input type="text" name="name" id="name" required />
</p>

<p>
<label for="email">Email</label>
<input type="email" name="email" id="email" required />
</p>

<p>
<label for="message">Message</label>
<textarea
name="message"
id="message"
cols="30"
rows="10"
required
>
</textarea>
</p>

<p>
<button type="submit">Submit</button>
</p>
</form>

Reference by name or ID

We can reference the fields by name or ID:

const contactForm = document.querySelector("#contact-form");

// Reference by name or ID
const nameInput = contactForm.elements.name;
const emailInput = contactForm.elements.email;
const messageTextArea = contactForm.elements.message;

Reference by index

We can also reference the fields by index. This lets us reference fields that don't have a name or ID, such as the submit button:

const contactForm = document.querySelector("#contact-form");

// Reference by index
const nameInput = contactForm.elements[0];
const emailInput = contactForm.elements[1];
const messageTextArea = contactForm.elements[2];
const submitButton = contactForm.elements[3];

Included elements

The following elements are included by the .elements property:

  • <button>
  • <fieldset>
  • <input> (but not type="image" 🤷)
  • <object>
  • <output>
  • <select>
  • <textarea>

Caveats

Image inputs

Image inputs aren't included for some weird historical reasons; you can still select these using the .querySelector() method:

const contactForm = document.querySelector("#contact-form");
const imageInput = contactForm.querySelector("[type='image']");

The HTMLFormControlsCollection interface

The HTMLFormElement.elements property returns an HTMLFormControlsCollection. If you need to use any array methods on it, you'll need to convert it to an array. I've used the Array.from() method below, but you could also use spread syntax:

const contactForm = document.querySelector("#contact-form");

// or [ ...contactForm.elements ]
const formFieldsArray = Array.from(contactForm.elements);

Browser support

The HTMLFormElement.elements property is supported all the way back to IE 5.5!