JavaScript
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax and Types
-
Section 3: Strings and Numbers in Depth
-
Section 4: Control Flow
-
Section 5: Functions
-
Section 6: Objects and Arrays
-
Section 7: Maps, Sets, and Symbols
-
Section 8: Asynchronous JavaScript
-
Section 9: Object-Oriented and Prototypes
-
Section 10: The DOM
-
Section 11: Browser APIs
-
Section 12: Modern JavaScript (ES2015-ES2025)
-
Section 13: Functional Programming Patterns
-
Section 14: Error Handling and Debugging
-
Section 15: Testing
-
Section 16: Accessibility for JavaScript Developers
-
Section 17: Internationalization and Localization
-
Section 18: Performance
-
Section 19: Node.js Fundamentals
-
Section 20: Regular Expressions
-
Section 21: Design Patterns in JavaScript
-
Section 22: Security Basics
-
Section 23: Data Structures and Algorithms in JavaScript
-
Section 24: Practical Projects
-
Section 25: More Advanced Async Patterns
-
Section 26: More Object and Class Practice
-
Section 27: Working with Dates and Internationalization
-
Section 28: Web Components
-
Section 29: More DOM and Browser Practice
-
Section 30: Build Tooling for Vanilla JavaScript
-
Section 31: More Practice Projects
-
Section 32: Interview and Algorithm Practice
-
Section 33: Error Objects (MDN Reference)
-
Section 34: TypedArrays and Binary Data
-
Section 35: Reflection and Metaprogramming (MDN Reference)
-
Section 36: More Global Functions (MDN Reference)
84: Working with Forms and Validation
Let's build a signup form for a developer portfolio site. I want a simple setup: a username, an email, and a password. In a perfect world, the browser handles everything, but in reality, we need JavaScript to bridge the gap between "the user typed something" and "the data is actually usable."
The "Refresh" Headache
I'll start with some basic HTML and a script to handle the submission. Here is my first attempt:
<form id="signup-form">
<input type="text" name="username" placeholder="Username">
<input type="email" name="email" placeholder="Email">
<input type="password" name="password" placeholder="Password">
<button type="submit">Join</button>
</form>
<script>
const form = document.querySelector('#signup-form');
form.addEventListener('submit', (e) => {
console.log('Form submitted!');
});
</script>
If you run this and click "Join," you'll notice something annoying: the console log flashes for a millisecond, and then the page refreshes, clearing all the inputs. This is the default behavior of HTML forms—they try to send a GET or POST request to the current URL. Since we're building a modern app, we want to handle this with JS without the page blinking. I need to stop that default action.
form.addEventListener('submit', (e) => {
e.preventDefault();
console.log('Now we are in control.');
});
Grabbing Everything at Once
Now I need the data. My first instinct is usually to grab every input by its ID: document.getElementById('username').value, and so on. But if I add ten more fields, my code becomes a wall of repetitive selectors. It's tedious.
Instead, I'll use the FormData object. It's a built-in JS class that sucks up all the named inputs from a form automatically. Let's see what happens when I wrap the form element in it:
form.addEventListener('submit', (e) => {
e.preventDefault();
const data = new FormData(e.target);
console.log(data); // Wait, this just logs a FormData object, not the values.
});
That's a common "gotcha." FormData is an iterator, not a plain object. To actually see the data in a format I can use (like an object), I'll spread it into Object.fromEntries(). This is much cleaner:
const formData = new FormData(e.target);
const entries = Object.fromEntries(formData.entries());
console.log(entries); // { username: 'dev_jane', email: 'jane@example.com', password: '...' }
Beyond the HTML5 Basics
I've used type="email" in the HTML, which handles basic format checking. But what if I want a specific rule? For example, the password must be at least 8 characters. HTML's minlength attribute is okay, but it doesn't give me much control over how the error is displayed.
I'll try to implement a custom check. I'll create a simple validation function and call it during the submit event:
const validate = (data) => {
if (data.password.length < 8) {
return 'Password is too short!';
}
if (!data.username.includes('_')) {
return 'Username must contain an underscore.';
}
return null; // No errors
};
form.addEventListener('submit', (e) => {
e.preventDefault();
const data = Object.fromEntries(new FormData(e.target));
const error = validate(data);
if (error) {
alert(error); // This works, but alerts are terrible UX.
} else {
console.log('Success!');
}
});
Making it User-Friendly
Using alert() is lazy and interrupts the user. I want the error to appear right on the page. I'll add a small empty div to my HTML to act as an error container, then I'll manipulate its text and style based on the validation result.
<div id="error-msg" style="color: red;"></div>
<form id="signup-form">...</form>
<script>
const errorDiv = document.querySelector('#error-msg');
form.addEventListener('submit', (e) => {
e.preventDefault();
const data = Object.fromEntries(new FormData(e.target));
const error = validate(data);
if (error) {
errorDiv.textContent = error;
form.classList.add('shaking'); // I'd add a CSS animation here for flair
} else {
errorDiv.textContent = '';
console.log('Form submitted successfully');
}
});
</script>
By following this flow—preventing the refresh, using FormData for efficiency, and moving from alert() to DOM manipulation—we've built a validation pipeline that is flexible and doesn't annoy the user.
📋 Practical Task
The Secure Portfolio Registration Validator
Build a registration form for a portfolio site that includes the following fields: Username, Email, and Password.
- Prevent the form from refreshing the page on submission.
- Use
FormDataandObject.fromEntriesto capture the input values. - Implement a validation check that ensures:
- The username is at least 3 characters long.
- The password is at least 8 characters long.
- Instead of an alert, display the specific error message in a dedicated
<p>element located above the form. - If the validation passes, clear the error message and log "Registration Successful" to the console.
There are no comments for now.