completefrontend
Open lab My progress
THE JAVASCRIPT FIELD GUIDE

Form properties & elements

Access forms and form controls with document.forms, form.elements, input values, checkboxes, radios, selects, and options.

By the end, you can
  • 01
    Find the controls in a formGet a form with document.forms, then find each control by name with form.elements.
  • 02
    Read what each control holdsPick the right property: .value for text, .valueAsNumber for numbers, .checked for checkboxes, and the group's .value for radio buttons.
  • 03
    Work with choicesRead and change checkboxes, radio buttons, menus, and their options, including menus where you can choose more than one.

Reading a form with JavaScript

A form is the part of a page where people type or choose things. A login box, a checkout page, and a search box are all forms. Each thing in a form that you can type in or click is called a control. Common controls are:

  • Text boxes and number boxes, made with <input>.
  • Checkboxes and radio buttons, also made with <input>.
  • Drop-down menus, made with <select>.
  • Big boxes for many lines of text, made with <textarea>.
  • Buttons, made with <button>.

JavaScript reads a form in three steps:

  1. Get the form.
  2. Use form.elements to find one control by its name.
  3. Read the property that fits that kind of control.

Which property you read depends on the control:

  • Text boxes and number boxes: value.
  • Checkboxes: checked.
  • A group of radio buttons: one shared value for the whole group.
  • Menus: value, selectedIndex, options, and selectedOptions.
Real-life analogyA clipboard with an index

Picture a clipboard at a front desk. The sheet has blanks with labels, like Email and Plan. A small index on the side says where each blank is, so you can jump straight to Email.

In real life: The whole clipboard
In JavaScript: The form element
In real life: A labeled blank, like Email
In JavaScript: A control with a name, like name="email"
In real life: The clipboard's index
In JavaScript: form.elements
In real life: Looking up the Email blank
In JavaScript: form.elements.email or form.elements.namedItem("email")

For this lesson, you should know DOM objects and their properties. Some values look like numbers but are really text; the Type conversion lesson helps with those. The next lesson, Form events, shows how to react when someone changes a field. This lesson is only about reading the fields.

form.elements: the list of controls

INTERACTIVE

First, get the form. document.forms is a list of every form on the page. You can pick a form in two ways:

  • By position: document.forms[0] is the first form.
  • By its name attribute: document.forms.signup is the form with name="signup".

Once you have the form, form.elements is the list of controls inside that form. You can pick a control by its name, like form.elements.email. You can also pick it by position, like form.elements[0]. form.elements.namedItem("email") does the same as form.elements.email.

Find a form, then one control in itPop out in the code editor (opens in a new tab)JavaScript
const form = document.forms.signup;
const email = form.elements.email;
console.log(form.name);
console.log(email.value);

Line 1 gets the form named signup. Line 2 gets the control named email from that form's own list, so a control in another form can't get mixed in. Line 3 prints the form's name, signup. Line 4 prints what is in the email box, ada@example.com.

Left: document.forms.signup is the signup form, a cart that holds two controls, email and age. An arrow labelled find email leads right to form.elements.email.value, a card that says "ada@example.com".document.forms.signupemailagesignupthe formfind emailform.elements.email.value"ada@example.com"what is typed now
First get the form. Then form.elements.email finds the email box inside it, and .value reads what is typed there.

The browser calls this list an HTMLFormControlsCollection. A collection is an object that works like a list: it has a length and numbered items, but it is not a real array. These tags go in the list: button, fieldset, input, object, output, select, and textarea. Two details:

  • An image button, <input type="image">, is not in the list.
  • A disabled control is still in the list. Disabled means greyed out: the user can't change it. The browser only leaves it out when it sends the form.
Use form.elements, not the form itself

You can also write form.email. It works, but it can clash with the form's own properties. The form already has a submit method and an action property. A control named submit hides the submit method. A control named action hides the action property. form.elements.email only looks in the list of controls, so it can't clash.

Form X-ray
The code the X-ray runsPop out in the code editor (opens in a new tab)JavaScript
const form = document.forms.signup;const email = form.elements.email;const age = form.elements.age;const plan = form.elements.plan;const snacks = form.elements.snacks; email.value;          // always a stringage.valueAsNumber;    // number, or NaN when emptyplan.value;           // checked radio value, or ""snacks.selectedOptions;
Signup formreal form
Account
Choices
form.elements.length
0
form.elements.email.value
""
password.value.length
0
age.value / valueAsNumber
"" /
birthday.valueAsDate
textarea.value
""
checkboxes: checked
terms false, newsletter false
form.elements.plan.value
""
snack.value / selectedIndex
/ -1
snack.selectedOptions
interests: chosen values
coupon.value (disabled)
fieldset.elements / element.form
0 / false
Try it yourself

Change any field. The list on the right reads the real form again each time.

This is a real form on this page. The X-ray only reads its properties; it never changes them.

Two more links between forms and controls:

  • Every control has an element.form property. It points back to the form the control belongs to.
  • A <fieldset> puts some controls in a group. It has its own smaller list, fieldset.elements, with only the controls in that group.

Input values are text

STEP THROUGH

Here is the most important rule: input.value is always a string. A string is text. Even a number box gives text. If a number box shows 4, then input.value is "4". If you add 1 to that text, JavaScript joins the two and gives "41".

A model of a number boxPop out in the code editor (opens in a new tab)JavaScript
function readNumberInput(rawValue) {  const value = String(rawValue);  const plusOne = value + 1;  const valueAsNumber = value === "" ? NaN : Number(value);  const fixed = valueAsNumber + 1;  return { value, plusOne, valueAsNumber, fixed };} const result = readNumberInput("4");console.log(result.plusOne);console.log(result.fixed);

This code doesn't use a real page. It copies what a number box does, so you can step through it. In plain words, line by line:

  • Line 2 turns the input into text, like input.value does.
  • Line 3 adds 1 to the text, so it gets "41".
  • Line 4 makes a number from the text, like input.valueAsNumber does. An empty box gives NaN.
  • Line 5 adds 1 to the number, so it gets 5.
  • Lines 10 and 11 print 41 and then 5.
Left: value + 1. The text "4" plus 1 gives the text "41", joined as text. Right: valueAsNumber + 1. The number 4 plus 1 gives 5, added as numbers.value + 1"4"+1"41"joined as textvalueAsNumber + 14+15added as numbers
The same box, read two ways. value is the text "4", so + 1 joins it into "41". valueAsNumber is the number 4, so + 1 gives 5.
Why does 4 + 1 give 41?
Step 0 of 7Ready
Your turn: follow the blue line

Guess first: will the box act like text or like a number? Then step through the run.

Running in
  1. script
Next: line 9
function readNumberInput(rawValue) {  const value = String(rawValue);  const plusOne = value + 1;  const valueAsNumber = value === "" ? NaN : Number(value);  const fixed = valueAsNumber + 1;  return { value, plusOne, valueAsNumber, fixed };} console.log(result.plusOne);console.log(result.fixed);
CallStoreChangeResultBlue line: runs next. Ran: already executed.
Recent returnsNothing yet. Start with the blue line.
Try 4 or 12. Delete everything to see NaN.
A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.

To get a number, read valueAsNumber. It works for number boxes (type="number") and sliders (type="range"). For an empty number box:

  • value is the empty string, "".
  • valueAsNumber is NaN, which means "not a number".

So check before you do math. Number.isNaN(x) gives true when x is NaN.

Date boxes (type="date") have valueAsDate. Their value is text like "2026-09-25". Their valueAsDate is a Date object, or null when the box is empty.

Two more words you will see on controls:

  • A disabled control can still be read with form.elements. But the browser doesn't send it with the form.
  • A readonly control can't be edited either. But the browser does send it with the form.
A textarea's value changes; its HTML text doesn'tPop out in the code editor (opens in a new tab)JavaScript
const form = document.forms.signup;
const bio = form.elements.bio;
bio.value = "Current note";
console.log(bio.value);
console.log(bio.textContent);

A <textarea> is a big box for many lines of text. Read what is in it now with its value property. Its textContent is the text written between its HTML tags, and typing doesn't change it. Line 3 sets the value to Current note. Line 4 prints Current note. Line 5 still prints Original HTML, the text from the HTML.

Check for NaN before you add

An empty number box gives NaN. A number box with something that isn't a number also gives NaN. Check with Number.isNaN() before you show a total. Don't use parseInt as a shortcut: it keeps only the whole-number part, so 12.5 becomes 12.

Checkboxes and radio buttons

INTERACTIVE
Real-life analogyCar radio buttons and light switches

Old car radios had a row of buttons, one for each station. Press one, and the button that was down pops back up, so only one is down at a time. Light switches are different. Each switch is on or off by itself.

In real life: The row of station buttons on an old car radio
In JavaScript: Radio buttons that share one name
In real life: Press one button and the others pop up
In JavaScript: Only one radio button with that name can be checked
In real life: Light switches, each on or off by itself
In JavaScript: Checkboxes, each with its own checked

A radio button is a round button for choosing one answer. Radio buttons with the same name form one group, and only one button in the group can be checked. For a group named plan, form.elements.plan gives a RadioNodeList: a list of all the radio buttons named plan. Its value is the value of the checked button, or "" when none is checked.

A checkbox is a square box that is on or off. Each checkbox works on its own. Its checked property is a boolean: true when it is on, false when it is off.

Left: the radio group plan, a cart that holds two radio buttons, free and pro. Pro is checked, so form.elements.plan.value is "pro". Right: the newsletter checkbox, a box that holds true. newsletter.checked is true, on its own.elements.plan.valuecheckedfreeproplanone value for the group: "pro"newsletter.checkedtruenewsletterits own on or off
Radio buttons with the same name share one answer: here the group's value is "pro". Each checkbox is on its own and has its own true or false.
Checkbox & radio lab
Set checked from codePop out in the code editor (opens in a new tab)JavaScript
const newsletter = document.querySelector("#newsletter");const pro = document.querySelector("#plan-pro");const selectAll = document.querySelector("#select-all"); newsletter.checked = true;     // no input/change event firespro.checked = true;            // same name: other radio pops outselectAll.indeterminate = true; // visual mixed stateselectAll.checked = false;
Real boxes0 events
newsletter.checked
false
form.elements.plan.value
"free"
free / pro checked
true / false
select-all: checked / indeterminate
false / false
change events counted
0
Try it yourself

Click the buttons. When code sets checked, the boxes change, but the event count stays the same.

The next lesson is about form events. Here you only see that changing a box from code sends no event.

An event is a signal the browser sends when something happens, like a click. When your code sets checked or value, the browser does not send an input or change event. That is useful: your code can fix a field without pretending the user did it. If you do want your event code to run, send the event yourself with dispatchEvent.

A "Select all" checkbox can show a third look, a dash, when only some of the boxes below it are checked. Set checkbox.indeterminate = true to show the dash. It only changes how the box looks. checked stays true or false.

Menus: select and option

INTERACTIVE
Real-life analogyA vending machine menu

A vending machine has a menu of snacks. Each snack has a code, like B7, and a place in the menu. You choose one snack. At a buffet, you can put several foods on your plate.

In real life: The whole menu of snacks
In JavaScript: select.options
In real life: The code of the snack you chose, like B7
In JavaScript: select.value
In real life: Where that snack is in the menu
In JavaScript: select.selectedIndex
In real life: A buffet plate with several foods
In JavaScript: A multiple menu and selectedOptions

A <select> is a drop-down menu. Each choice inside it is an <option>. A select has four useful properties:

  • value: the value of the chosen option, like "tea".
  • selectedIndex: the position of the chosen option. Counting starts at 0. It is -1 when nothing is chosen.
  • options: the list of all the options.
  • selectedOptions: the list of chosen options. A menu with the multiple attribute lets the user choose more than one.
Select lab
Add, choose, and remove optionsPop out in the code editor (opens in a new tab)JavaScript
const select = document.querySelector("select"); const tea = new Option("Tea", "tea", false, false);select.add(tea);select.value = "tea"; select.multiple = true;select.options[0].selected = true;const chosen = [...select.selectedOptions].map((option) => option.value);tea.remove();
Menu0 options
select.value
""
selectedIndex
-1
select.multiple
false
selectedOptions
Try it yourself

Add Tea with new Option, let the menu take more than one choice, then remove a chosen option.

This menu is made with plain JavaScript, so the buttons add and remove real option elements.
A select menu with three options: 0 Coffee, 1 Cake, 2 Tea. An arrow from Tea points to value: "tea" and selectedIndex: 2.select0Coffee1Cake2Teavalue: "tea"selectedIndex: 2
The menu after the lab's "Add selected Tea" button. Tea is chosen, so value is "tea". It is at position 2, counting from 0, so selectedIndex is 2.

To make a new option, write new Option(text, value, defaultSelected, selected). The four parts are:

  • text: the words the user sees, like "Tea".
  • value: the value your code reads, like "tea".
  • defaultSelected: true makes it the starting choice, the one the menu goes back to when the form is reset.
  • selected: true chooses it right now.

Add the option to the menu with select.add(option). Take it out with option.remove().

selectedOptions is an HTMLCollection, not an array, so it has no map method. Spread it into an array first: [...select.selectedOptions].map(option => option.value).

What type is it?
  • input.value
  • checkbox.checked
  • numberInput.valueAsNumber
  • form.elements
  • form.elements.plan
  • select.selectedOptions
  • select.selectedIndex
  • form.elements.plan.value
Try it yourself
0 of 8 correct

Sort each form property by the kind of value it gives you.

Choose a category for every card. You can change an answer at any time; Reset clears them all.

Where you will use this

PRACTICAL

In real pages, you read a form before you check it, show a preview, turn a button on, save a draft, or send it to a server. The function below reads a signup form. Each line reads the property that fits its control.

Read a signup formPop out in the code editor (opens in a new tab)JavaScript
function readSignup(form) {  const elements = form.elements;  return {    email: elements.email.value.trim(),    age: elements.age.valueAsNumber,    plan: elements.plan.value,    toppings: [...elements.toppings.selectedOptions].map((option) => option.value),    acceptsTerms: elements.terms.checked,  };} function readSignupSubmission(form) {  return Object.fromEntries(new FormData(form));}

In plain words, line by line:

  • Line 2 keeps form.elements in a shorter name, elements.
  • Line 4 reads the email text. trim() removes spaces at the start and the end.
  • Line 5 reads the age as a number.
  • Line 6 reads the value of the checked radio button in the plan group.
  • Line 7 spreads the chosen toppings into an array, then keeps each option's value.
  • Line 8 reads the terms checkbox as true or false.
  • Lines 12 to 14 are a second, shorter reader that uses FormData, shown next.
Collect what the form would sendPop out in the code editor (opens in a new tab)JavaScript
const form = document.forms.signup;
const data = new FormData(form);
const signup = Object.fromEntries(data);
console.log(signup.email);
console.log(data.getAll("toppings").join(","));

new FormData(form) collects what the browser would send if the form were submitted. Line 3 turns it into a plain object with Object.fromEntries. Line 4 prints the email, ada@example.com.

That plain object keeps only one value for each name. But a menu with multiple can send the same name more than once, like toppings twice. Line 5 uses data.getAll("toppings") to keep every value, so it prints cheese,olives.

FormData leaves out checkboxes that are not checked, and it leaves out disabled controls. It keeps readonly controls.

The table below is a quick guide. Each row starts with a question you might ask about a form. Read across to see what to read and why.

Which property answers which question?
What you want to knowWhat to readWhy
What text is in the box now?input.valueIt is the current text, and it is always a string.
What number did the user type?input.valueAsNumberIt gives a number, or NaN. Check for NaN before math.
Is the checkbox on?checkbox.checkedIt is true when on and false when off.
Which radio button in the group is checked?form.elements.plan.valueThe group gives the value of its checked button.
Which menu choice is chosen?select.value and selectedIndexOne gives the option's value; the other gives its position.
Which choices are chosen in a multiple menu?[...select.selectedOptions]It gives the chosen option elements, spread into an array.
What will the form send?new FormData(form)It leaves out unchecked and disabled controls, and keeps every value of a repeated name.

Common misconceptions

WATCH OUT
  • "A number box gives a number." Its value is a string. Read valueAsNumber, or change the text to a number yourself.
  • "form.email is always safe." It can clash with the form's own properties, like submit. Use form.elements.email.
  • "Disabled controls are not in form.elements." They are in the list. They are only left out when the form is sent.
  • "A radio button is just a round checkbox." Radio buttons with the same name form a group, and only one can be checked. Read the group's value with form.elements.plan.value.
  • "Setting checked from code sends a change event." Setting a property from code does not send any form event.
  • "selectedOptions is an array." It is an HTMLCollection. Spread it into an array before you use array methods like map.

Practice exercises

5 EXERCISES
Exercise 1 · Warm-upAn empty number box

This code copies an empty number box. What does line 4 print?

Starter codePop out in the code editor (opens in a new tab)JavaScript
const value = "";
const valueAsNumber = value === "" ? NaN : Number(value);
console.log(value);
console.log(Number.isNaN(valueAsNumber));

Answer, then press Check. Spacing and letter case don’t matter.

    Exercise 2 · Warm-upThe value of a radio group

    What does form.elements.plan.value give when the Pro radio button is checked?

    Starter codePop out in the code editor (opens in a new tab)JavaScript
    const plan = { value: "pro" };
    console.log(plan.value);

    Answer, then press Check. Spacing and letter case don’t matter.

      Exercise 3 · PracticeThe values of a multiple menu

      A multiple menu has Tea and Cake chosen. What does the code print?

      Starter codePop out in the code editor (opens in a new tab)JavaScript
      const selectedOptions = [{ value: "tea" }, { value: "cake" }];
      console.log(selectedOptions.map((option) => option.value).join(","));

      Answer, then press Check. Spacing and letter case don’t matter.

        Exercise 4 · PracticeFind the missing event

        What does the first console.log print?

        Starter codePop out in the code editor (opens in a new tab)JavaScript
        const events = [];
        const checkbox = { checked: false };
        checkbox.checked = true;
        console.log(events.length);
        events.push("change");
        console.log(events.length);

        Answer, then press Check. Spacing and letter case don’t matter.

          Exercise 5 · ChallengeWrite a form reader

          Write a function that reads a profile form. The form has a text box email, a number box age, a radio group plan, a multiple menu interests, and a checkbox terms.

          Starter codePop out in the code editor (opens in a new tab)JavaScript
          function readProfile(form) {
            // return email, age, plan, topics, and subscribed
          }

            Quiz

            7 QUESTIONS
            Form properties & elements quiz · 7 questionsScore: first tries count
            1. Question 1 of 7Why is form.elements.email usually better than form.email?

              Choose an answer to see the explanation.

            2. Question 2 of 7What does this print?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              const value = "4";
              console.log(value + 1);
              console.log(Number(value) + 1);

              Choose an answer to see the explanation.

            3. Question 3 of 7A form has three radio buttons with name="plan", and none is checked. What is form.elements.plan.value?

              Choose an answer to see the explanation.

            4. Question 4 of 7Which sentence about checkboxes is true?

              Choose an answer to see the explanation.

            5. Question 5 of 7What does this program print?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              const events = [];
              const box = { checked: false };
              box.checked = true;
              console.log(events.length);

              Choose an answer to see the explanation.

            6. Question 6 of 7In a menu where you can choose one thing, what does selectedIndex mean?

              Choose an answer to see the explanation.

            7. Question 7 of 7Which call makes a new option and chooses it right now?

              Choose an answer to see the explanation.

            Key takeaways

            • document.forms finds forms. form.elements finds the controls inside one form.
            • Use form.elements.name, not form.name, because a control's name can clash with the form's own properties.
            • input.value is always a string. Use valueAsNumber, valueAsDate, or your own conversion when you need another type.
            • Checkboxes use checked. A radio group gives the value of its checked button through form.elements.plan.value.
            • Menus have value, selectedIndex, options, and selectedOptions. Make new choices with new Option.

            In one line: form properties let JavaScript find each control in a form and read what it holds right now.

            Up next: Form events.

            CompleteFrontend Clear concepts. Working examples.