DEV Community

loading...
Cover image for Vanilla JavaScript get all elements in a form

Vanilla JavaScript get all elements in a form

dailydevtips1 profile image Chris Bongers Originally published at daily-dev-tips.com ・2 min read

If you ever made your own validation you will understand the struggle of getting all the form elements.

I've made code that would loop over each type of input as such:

types = ['input', 'select', 'texture'];
// Manually loop and get all those
Enter fullscreen mode Exit fullscreen mode

That will work, but it's very easy to miss one, and not really maintainable.

Did you know there is a simpler way to retrieve all the elements inside a form?

Vanilla JavaScript get a form's elements

So let's say we have a form with all kinds of inputs like this:

<form id="form">
  <div class="container">
    <div class="row">
      <label for="firstname">Firstname</label>
      <input type="text" name="firstname" id="firstname" />
    </div>
    <div class="row">
      <label for="email">Email</label>
      <input type="email" name="email" id="email" />
    </div>
    <div class="row">
      <label for="select">Select</label>
      <select name="select" id="select">
        <option value="1">Option 1</option>
        <option value="2">Option 2</option>
      </select>
    </div>
    <div class="row">
      <p>Do you agree?</p>
      <label>
        <input type="radio" name="agree" value="yes">
        Yes
      </label>
      <label>
        <input type="radio" name="agree" value="no">
        No
      </label>
    </div>
    <div class="row">
      <p>Your favorite animal?</p>
      <label>
        <input type="checkbox" name="agree" value="penguin">
        🐧
      </label>
      <label>
        <input type="checkbox" name="agree" value="dog">
        🐶
      </label>
    </div>
  </div>
  </div>
</form>
Enter fullscreen mode Exit fullscreen mode

This is a typical form, it has some regular inputs, some select elements, checkboxes, and radio groups.

It also has random markup in between to style your form, see the divs and labels.

So how can we distinguish these elements?

First, let's define a variable that will get our form.

const form = document.getElementById('form');
Enter fullscreen mode Exit fullscreen mode

Now it is literally as simple as calling .elements on this const.

console.log(form.elements);
Enter fullscreen mode Exit fullscreen mode

This will give us an HTMLFormControlsCollection which looks as follows.

HTML form controls collection

As you can see these holds are our form elements, which is already super useful.

You can then loop over them using a forEach loop for instance.

[...form.elements].forEach(item => {
  console.log(item);
});
Enter fullscreen mode Exit fullscreen mode

Now it's up to you to create your own validation with this.

You can find this full demo on the following Codepen.

Thank you for reading, and let's connect!

Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter

Discussion (7)

pic
Editor guide
Collapse
adam_cyclones profile image
Adam Crockett • Edited
document.querySelectorAll('#form > *');
Enter fullscreen mode Exit fullscreen mode

That's what I would have done but actually forms have a serialization API built in so I am not sure why you would do this anymore?
Also forms have a validation api which also encourages better accessibility through symantics.

Collapse
dailydevtips1 profile image
Chris Bongers Author • Edited

Hey Adam,

That will give you literally all the elements including divs etc.
In my example, it will only give you form-based elements.

In cases where you need to either detect input change with JS I use this.
Or where you want custom validation (error messages etc)

Don't think the form validation API does any of that

For instance, see this angular example where I need to manually push change event after third-party plugin form film
Angular form detect

Collapse
tunaxor profile image
Angel D. Munoz

just for reference, the validation API does allow you to set a custom message
developer.mozilla.org/en-US/docs/W...

although, it's quite clunky some times, a better example can be found here
developer.mozilla.org/en-US/docs/W...

Thread Thread
adam_cyclones profile image
Adam Crockett

Exactly, a good starting point. If it where me, I would just add no validate to the form and use the sited API adding messages to a div. I like that you can though, good info.

Thread Thread
dailydevtips1 profile image
Chris Bongers Author

Ah pretty cool I would indeed opt for custom validation since designers love inline validation or some custom view to it.

Pretty neat however we can use it to set custom validation as well!
Going to spend some time on this and see what I can find out about this validation API and custom errors.

Thread Thread
dailydevtips1 profile image
Chris Bongers Author

Just found this explanation:
css-tricks.com/form-validation-par...

Just looking at the last description he still uses the javascript method to get all the forms elements.
Just trying to say even with the validation API it still seems to have it's use-cases to get all a form's elements?

Collapse
adam_cyclones profile image
Adam Crockett

I agree it gives you all the elements so I probably meant to take the time to write elements which hold value but I am on my phone so... None the less such css selector is no more painful to write (if on a keyboard).

For the custom messages, everyone gets the wrong end of the stick when I spout this commonly sited answer. To them I usually say "Add novalidate to your html form element and build a minimal custom validation messaging UI but retain the native validation methods." - it never goes well.