HTML & CSS ·

HTML Forms in JavaScript: Submit, Checkboxes, Selects

By Manu Mathew · Last updated 4 October 2026

Forms are where websites and older web applications do their real work, and the same small tasks come up again and again. This page brings together several short notes I wrote between 2013 and 2016. I have rewritten them in one place, with tested examples and current advice, so you don’t have to piece the answer together from fragments. The examples use plain JavaScript, with the jQuery version alongside where the old note used jQuery.

Quick answer

Get a form with document.forms['name'], change action and method as properties, and send it with requestSubmit() so validation still runs. Use querySelectorAll for groups of checkboxes or fields, selectedOptions for multi-selects, and setCustomValidity() for your own validation messages, cleared again when the user types.

I tested every example with jsdom 24 under Node.js 20, which follows the same web standards as current browsers.

How do I submit a form, or change its action and method, from JavaScript?

Set form.action and form.method, then call form.requestSubmit().

const form = document.forms['signup'];   // or document.getElementById('signup')

form.action = '/subscribe';              // change where the form is sent
form.method = 'post';                    // 'get' or 'post'

form.requestSubmit();                    // runs validation and the submit event, like clicking Submit
// form.submit();                        // sends straight away and skips both

The older notes used submit(). It still works, but it skips the browser’s validation (such as required fields) and doesn’t fire the form’s submit event, so other scripts listening for it never run. requestSubmit() behaves like a real click on the submit button.

How do I post a form to a new window?

Open a named window, set the form’s target to that name, then submit.

function submitInNewWindow(form) {
  window.open('', 'report_window', 'width=800,height=600');   // open (or reuse) a named window
  form.target = 'report_window';                              // send the form's response there
  form.submit();
}

// <form id="report" method="post" action="/report">…</form>
// <button type="button" onclick="submitInNewWindow(document.forms.report)">Open report</button>

Call this from a click handler: browsers block pop-ups that aren’t triggered by the user. If you just want a new tab, <form target="_blank"> needs no JavaScript at all.

How do I make a “select all” checkbox?

Listen for change on the “select all” box and copy its checked value to every checkbox in the group.

// <label><input type="checkbox" id="select-all"> Select all</label>
// <input type="checkbox" name="item" value="1"> … (more checkboxes named "item")
const selectAll = document.getElementById('select-all');

selectAll.addEventListener('change', () => {
  document.querySelectorAll('input[name="item"]').forEach((box) => {
    box.checked = selectAll.checked;
  });
});

How do I select all options, or read the selected ones, in a multi-select box?

Loop over select.options to change them, and use select.selectedOptions to read what is chosen.

// <select id="countries" multiple> … </select>
const list = document.getElementById('countries');

function setAllOptions(select, selected) {
  for (const option of select.options) {
    option.selected = selected;          // true selects all, false clears all
  }
}

function selectedValues(select) {
  return Array.from(select.selectedOptions, (option) => option.value);
}

function selectedTexts(select) {
  return Array.from(select.selectedOptions, (option) => option.text);
}

selectedOptions is supported in all current browsers and saves you from checking options[i].selected one by one.

select.value gives the value; select.options[select.selectedIndex].text gives the visible text.

// <select id="city"><option value="kzd">Kozhikode</option> … </select>
const city = document.getElementById('city');
const text = city.options[city.selectedIndex].text;    // "Kozhikode"
const value = city.value;                               // "kzd"

// With jQuery:
// $('#city option:selected').text();

How do I collect the values of fields with the same class?

Turn querySelectorAll('.class') into an array and map each field to its value.

// <input class="code" value="99213"> <input class="code" value="99214">
const codes = Array.from(document.querySelectorAll('.code'), (input) => input.value);
// ["99213", "99214"]

// With jQuery:
// const codes = $('.code').map(function () { return $(this).val(); }).get();

This also avoids a bug in the old note, which used a counter variable that was never set before the loop.

How do I check that an email address looks valid?

Use <input type="email"> and ask the browser with checkValidity().

// <input type="email" id="email" required>
const email = document.getElementById('email');

function emailLooksValid(input) {
  return input.value !== '' && input.checkValidity();   // uses the browser's own email rules
}

The regular expression in the old note rejected many real addresses, such as those on newer top-level domains longer than four letters. The browser’s rule is the one in the HTML standard, and it is good enough for a first check. Validate again on the server, and confirm the address by sending an email if it matters.

How do I set a custom message for a required field?

Call setCustomValidity() when the field is invalid, and clear it with an empty string when the user types.

// <input type="text" id="username" required>
const username = document.getElementById('username');

username.addEventListener('invalid', () => {
  if (username.validity.valueMissing) {
    username.setCustomValidity('Please enter a username.');
  }
});
username.addEventListener('input', () => {
  username.setCustomValidity('');        // clear it, or the field stays invalid
});

The old one-line version set the message but never cleared it, so the field stayed invalid even after the user filled it in. Clearing it on input fixes that.

If your WordPress site’s forms need fixing or rebuilding, see WordPress websites for small businesses.

Sources: MDN: HTMLFormElement.requestSubmit(); MDN: HTMLSelectElement.selectedOptions; MDN: setCustomValidity(); HTML standard: valid email address; jQuery: .map().

Back to the blog