Most real interactivity involves letting the user type something. Let's build a few input-driven features.
Reading an input's value
Text boxes are <input> elements, and their current text lives in the .value property:
<input id="name-input" type="text" placeholder="Type your name" />
<button id="greet-btn">Greet me</button>
<p id="greeting"></p>
const nameInput = document.querySelector("#name-input");
const greetButton = document.querySelector("#greet-btn");
const greeting = document.querySelector("#greeting");
greetButton.addEventListener("click", () => {
const name = nameInput.value.trim();
if (name === "") {
greeting.textContent = "Please type your name first! 🙏";
return;
}
greeting.textContent = `Welcome, ${name}! 👋`;
nameInput.value = ""; // clear the box for next time
});
Notice that we trim() the input (users love accidentally typing spaces), check that it isn't empty (a guard clause, from Grade 6), and use textContent (not innerHTML!) to display it safely.
Just like prompt, the .value of an input is always a string, even if it's an <input type="number">. If you want to do math with it, convert it first with Number(input.value). Otherwise, "5" + "5" will give you "55". (Type coercion strikes again!)
Live updates with the input event
The input event fires every single time the text changes. That's perfect for things that should update as you type, like a character counter:
<textarea id="tweet" maxlength="140" placeholder="What's happening?"></textarea>
<p id="counter">140 characters left</p>
const tweet = document.querySelector("#tweet");
const counter = document.querySelector("#counter");
tweet.addEventListener("input", () => {
const remaining = 140 - tweet.value.length;
counter.textContent = `${remaining} characters left`;
counter.style.color = remaining < 20 ? "red" : "black";
});
Type in the box and watch the counter tick down, turning red as you get close to the limit.
Forms and preventDefault
When you have several inputs together (like a sign-up form), you should wrap them in a <form> element. Forms are great: they let users press Enter to submit, and they work well with screen readers and password managers.
But forms have one old-fashioned habit: when submitted, they reload the whole page (or send the user to another page). That would wipe out everything your JavaScript was doing! To stop this, call event.preventDefault() in your submit listener:
<form id="signup">
<input id="email" type="email" placeholder="Email" required />
<input id="password" type="password" placeholder="Password" />
<button type="submit">Sign up</button>
</form>
<p id="feedback"></p>
const form = document.querySelector("#signup");
const emailInput = document.querySelector("#email");
const passwordInput = document.querySelector("#password");
const feedback = document.querySelector("#feedback");
form.addEventListener("submit", (event) => {
event.preventDefault(); // stop the page from reloading!
const email = emailInput.value.trim();
const password = passwordInput.value;
if (password.length < 8) {
feedback.textContent = "❌ Password must be at least 8 characters.";
return;
}
feedback.textContent = `✅ Welcome aboard, ${email}!`;
form.reset(); // clear all the inputs
});
Notice that we listen for submit on the form, not click on the button. That way it works whether the user clicks the button or presses Enter.
preventDefault() works on other events too. It stops the browser's default behavior for that event, like a link opening a new page, or a right-click opening the context menu.
The required attribute and type="email" in the HTML give you some free validation: the browser won't submit the form if the email box is empty or doesn't look like an email. That's nice, but in real apps, the server must always check the data too. Anyone can open DevTools and mess with your page, so never trust the browser alone for anything important, like payments or passwords.