cf.completefrontendCode editorOpen lab
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 controls safelyUse document.forms, form.elements, fieldset.elements, and element.form without name collisions.
  • 02
    Read real valuesChoose between .value, .valueAsNumber, .valueAsDate, .checked, and radio-list .value.
  • 03
    Handle choicesRead and change checkboxes, radio groups, selects, options, and multiple selections.

Forms as clipboards

Forms are where page data becomes user data. A login box, checkout page, search panel, survey, settings screen, or newsletter signup is a collection of controls: text inputs, checkboxes, radio buttons, menus, textareas, buttons, and sometimes grouped fieldsets. JavaScript does not need to guess where those controls are. Every form exposes a built-in index.

The central idea is: get the form, use form.elements to find controls, then read the property that matches each control. Text-like controls use value. Checkboxes use checked. Radio groups have one shared value. Selects have value, selectedIndex, options, and selectedOptions.

Real-life analogyA form is a clipboard with a field index

Imagine a clipboard at a front desk. The sheet has labeled blanks, and the receptionist uses an index to jump to “Email” or “Plan.” form.elements is that index for the browser.

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

Where the analogy stops: A paper clipboard cannot have a field named submit that hides a built-in method, and it cannot turn one label into a radio group. Real forms can, so prefer form.elements.name over form.name.

This lesson follows Attributes & properties and links back to Type conversion when strings pretend to be numbers. The next lesson, Form events, will react to changes and submissions; this one focuses on reading the controls accurately.

form.elements

INTERACTIVE

Start with the form. document.forms is a collection of forms in the document. You can read by index, such as document.forms[0], or by a form name, such as document.forms.signup. Once you have the form, form.elements gives the controls that belong to that form.

form.elements is an HTMLFormControlsCollection. It includes button, fieldset, input, object, output, select, and textarea. It does not include <input type="image">. A disabled control still appears in the collection; it is excluded later when the browser builds submitted form data.

Prefer the controls collection

Named access like form.email works in browsers, but a field named submit can shadow form.submit, and a field named action can shadow form.action. form.elements.email says “look in the controls” and avoids that trap.

Form X-ray
The reads behind the X-rayPop 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 formlive DOM
Account
Choices
form.elements.length
0
form.elements.email.value
""
password length
0
age.value / valueAsNumber
"" /
birthday.valueAsDate
textarea.value
""
checkboxes
terms false, newsletter false
form.elements.plan.value
""
select value / index
/ -1
selectedOptions
multiple selected
disabled field value
fieldset.elements / element.form
0 / false
Try it yourself

Change any field. The panel reads the real form through DOM APIs.

This is a React-rendered uncontrolled form. The experiment only reads DOM properties, so React and the DOM API stay in their lanes.

Notice the back-reference too: a control’s element.form points to the form it belongs to. A fieldset also has its own fieldset.elements, a smaller index for the controls inside that group.

Input values

STEP THROUGH

The most important value rule is simple but surprising: input.value is always a string. A number input that visually contains 4 has input.value === "4". If you add 1 to that string, JavaScript concatenates and gives "41".

Pure model for the number replayPop 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);
Where did my number go?
Step 0 of 7Ready
Your turn: follow the blue line

Predict whether the input behaves like text or a number, then step through the recorded run.

Running in
  1. script
Next: line 9
Click the blue line to take the next stepPop 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 };} console.log(result.plusOne);console.log(result.fixed);
CallStoreChangeResultRun = next line. Ran = already executed.
Recent returnsNothing yet. Start with the blue line.
Use 4, 12, or 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.

Use valueAsNumber when the control has a numeric interpretation, such as type="number" or type="range". Empty number inputs read as "" through value and NaN through valueAsNumber. Use Number.isNaN before doing math.

Date-like inputs have valueAsDate where supported. The string value might be "2026-09-25", while valueAsDate is a Date object, or null when the field is empty. A disabled control can still be read from form.elements, but it will be skipped by submission; a readonly control is included in submission.

Checkboxes & radios

INTERACTIVE
Real-life analogyRadio presets and light switches

A radio group answers “choose one.” A checkbox answers “is this switch on?” Read radio groups through the group value; read checkboxes through checked.

In real life: Old car radio preset buttons
In JavaScript: Radio inputs sharing one name
In real life: Pressing one preset pops the others out
In JavaScript: Only one same-name radio can be checked
In real life: Independent light switches
In JavaScript: Separate checkboxes with separate checked booleans

Where the analogy stops: Radio exclusivity depends on the same form and same name. Checkboxes can share a name for submission, but they still do not become exclusive.

Radio buttons with the same name form one group. In form.elements, that name returns a RadioNodeList. Its value is the checked radio’s value, or "" if none is checked. Checkboxes are independent; checkbox.checked is a boolean.

Checkbox & radio lab
Programmatic checked readsPop 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 controls0 events
newsletter.checked
false
radio group value
"free"
free / pro checked
true / false
select-all checked / indeterminate
false / false
change events observed
0
Try it yourself

Click the buttons. Programmatic property writes change state but do not increment the event counter.

The next lesson explains form events. Here we only prove the state/event distinction.

Setting checked or value from JavaScript does not fire input or change by itself. That is useful: scripts can repair state without accidentally pretending the user acted. If you want listeners to run, dispatch an event intentionally. A “select all” checkbox can use indeterminate to show a mixed visual state while some child checkboxes are selected.

select & option

INTERACTIVE
Real-life analogyA select is a vending machine menu

For a select, value is the chosen option’s code, selectedIndex is the option’s position, and options is the menu. Multiple selection changes the question from “which one?” to “which options?”

In real life: The whole menu
In JavaScript: select.options
In real life: Snack code B7
In JavaScript: select.value
In real life: Snack position in the menu
In JavaScript: select.selectedIndex
In real life: A buffet plate
In JavaScript: A multiple select and selectedOptions

Where the analogy stops: A vending machine gives one snack at a time, but a multiple select can hold several selected options. Also, option values are still strings.

Select lab
Select and option operationsPop 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, switch to multiple mode, then remove the selected option.

The select is created inside an empty ref container so option insertion and removal belong to the DOM API, not React.

Create options with new Option(text, value, defaultSelected, selected). Add them with select.add(option). Remove them with option.remove(). For multiple selects, selectedOptions is an HTMLCollection, so convert it before mapping: [...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 API 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 interfaces, you often read a form before validating, previewing, enabling a button, saving a draft, or building a request. The function below is deliberately boring: that is what good form-reading code should be. Each line chooses the property that matches the 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,    interests: [...elements.interests.selectedOptions].map((option) => option.value),    acceptsTerms: elements.terms.checked,  };}
Which property answers which question?
QuestionUseWhy
What text is in the field now?input.valueThe live value is always a string.
What number did the user enter?input.valueAsNumberIt gives a number or NaN; check before math.
Is the box on?checkbox.checkedThe on/off state is boolean.
Which radio in this group is checked?form.elements.plan.valueThe RadioNodeList summarizes the group.
Which menu item is selected?select.value and selectedIndexOne gives the option code; the other gives position.
Which multiple options are selected?[...select.selectedOptions]The result is a collection of option elements.

Common misconceptions

WATCH OUT
  • “A number input gives a number.” Its value is a string. Use valueAsNumber or convert explicitly.
  • “form.email is always safe.” It can collide with built-in form properties. Prefer form.elements.email.
  • “Disabled controls are not in form.elements.” They are in the collection; they are excluded from submission.
  • “A radio button is just a checkbox with a round shape.” Same-name radios form an exclusive group and can be read as a RadioNodeList.
  • “Changing checked from code fires change.” Programmatic property writes do not fire form events by themselves.
  • “selectedOptions is an array.” It is an HTMLCollection. Spread it into an array before using array methods.

Practice exercises

5 EXERCISES
Exercise 1 · Warm-upEmpty number input

Predict the boolean printed by line 4.

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-upRadio group value

    What value would form.elements.plan.value give when the Pro radio 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 · PracticeMultiple select values

      Predict the printed string for a multiple select with Tea and Cake selected.

      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 safe form reader

          Write a function that reads a profile form with email, age, radio group plan, multiple select interests, and 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 radios 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 statement 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 7For a single-select menu, what does selectedIndex mean?

              Choose an answer to see the explanation.

            7. Question 7 of 7Which constructor call creates and selects a new option?

              Choose an answer to see the explanation.

            Key takeaways

            • document.forms finds forms; form.elements finds the controls belonging to one form.
            • Prefer form.elements.name over form.name because control names can collide with form properties.
            • input.value is a string. Use valueAsNumber, valueAsDate, or explicit conversion when you need another type.
            • Checkboxes use checked; same-name radio groups expose a RadioNodeList.value.
            • Selects expose value, selectedIndex, options, and selectedOptions; create choices with new Option.

            Final definition: form element APIs are the DOM properties and collections that let JavaScript find controls and read their current values accurately.

            Up next: Form events.

            CompleteFrontend Clear concepts. Working examples.