Forms: reading what people type

Buttons are fun, but most useful pages need the user to type something: a name, a score, a search. In HTML that is an <input>, and JavaScript reads what is in it through its .value property:

<input id="name" placeholder="Your name">
<button id="hi">Say hi</button>
<p id="out"></p>
const nameBox = document.querySelector("#name");
document.querySelector("#hi").addEventListener("click", () => {
  out.textContent = "Hi " + nameBox.value + "!";
});

Read .value inside the handler, at the moment of the click. If you read it once at the top of the script, you get whatever was in the box when the page loaded, which is nothing.

Text is always text

.value is always a string, even in <input type="number">. So "2" + "3" gives "23", the same trap as Python's input(). Convert first with Number(box.value). If the text is not a number, Number gives NaN ("not a number"), which you can check with Number.isNaN(x).

Reacting while they type

The "input" event fires on every keystroke, which is how live character counters and search-as-you-type work:

nameBox.addEventListener("input", () => {
  count.textContent = nameBox.value.length;
});

Forms and submit

Wrap inputs in a <form> and pressing Enter submits it, which by default reloads the page and wipes your work. Listen for "submit" on the form and call event.preventDefault() first to stop that:

form.addEventListener("submit", (event) => {
  event.preventDefault();
  // read the inputs and update the page here
});

Try it yourself

Edit it. Break it. Run it again.
<form id="calc">
  <input id="a" value="4" size="4"> +
  <input id="b" value="5" size="4">
  <button>Add</button>
</form>
<p id="sum"></p>
<p><input id="msg" placeholder="Type something"> <span id="chars">0</span> characters</p>
<script>
  const form = document.querySelector("#calc");
  const sum = document.querySelector("#sum");

  form.addEventListener("submit", (event) => {
    event.preventDefault();
    const a = Number(document.querySelector("#a").value);
    const b = Number(document.querySelector("#b").value);
    sum.textContent = a + " + " + b + " = " + (a + b);
    console.log("as text it would be", document.querySelector("#a").value + document.querySelector("#b").value);
  });

  const msg = document.querySelector("#msg");
  msg.addEventListener("input", () => {
    document.querySelector("#chars").textContent = msg.value.length;
  });
</script>
Ctrl/Cmd + Enter runs. Esc, then Tab, leaves the editor.

Your turn

Type it yourself. That is the whole trick.

1Greeter

When #go is clicked, show Hi NAME! in #out, where NAME is whatever is typed in #name. Right now it always says the same thing.

<input id="name" placeholder="Your name">
<button id="go">Greet me</button>
<p id="out"></p>
<script>
  const nameBox = document.querySelector("#name");
  const out = document.querySelector("#out");
  document.querySelector("#go").addEventListener("click", () => {
    out.textContent = "Hi there!";
  });
</script>
Ctrl/Cmd + Enter runs. Esc, then Tab, leaves the editor.

2Score doubler

When the form is submitted, show double the number typed in #score inside #result. Two bugs: the page reloads, and "4" doubles to "44". Fix both.

<form id="f">
  <input id="score" value="4">
  <button>Double it</button>
</form>
<p id="result"></p>
<script>
  const form = document.querySelector("#f");
  form.addEventListener("submit", (event) => {
    const score = document.querySelector("#score").value;
    document.querySelector("#result").textContent = score + score;
  });
</script>
Ctrl/Cmd + Enter runs. Esc, then Tab, leaves the editor.

Code editor. Press Control or Command plus Enter to run the code. Tab indents; to move focus out of the editor, press Escape and then Tab.