Form Validation to Dynamic UIs: The JavaScript forms Handbook
Published: Jan 1, 2024
Forms are the backbone of user interaction on websites and web applications. Normally when a user registers for an account, checks out on an e-commerce store, fills out a contact form, or interacts with a web app, they are working with HTML forms.
Some examples of common forms include:
- User registration and login forms
- Contact forms
- Shopping cart checkout forms
- Survey and poll forms
- Search forms
- And countless custom forms for web apps
With JavaScript, we can customize and enhance these form experiences in all kinds of powerful ways: ✅ Real-time form validation for providing feedback ✅ Dynamically updating forms as the user types ✅ Improving overall usability and user experience
The key is tapping into form events triggered by user interactions. Let’s explore the most essential events to be aware of when coding forms with JavaScript.
Events Inside Forms
All HTML form elements have special events that are triggered when users interact with them. Being able to listen for these events is the foundation for handling form submissions and providing a great experience.
Here are some of the most common form events you’ll work with:
Submit Event
Here is how you can listen for the submit event:
// Get form reference
const form = document.querySelector('form');
// Listen for submit
form.addEventListener('submit', function(e) {
// Form submit logic
});
Now code can be executed each time a submit occurs, before the data is actually sent to the server.
Change Event
Inputs like text fields, select dropdowns, and checkboxes all trigger a “change” event when their value changes. For example:
<input type="text" id="username">
const username = document.querySelector('#username');
username.addEventListener('change', function(e) {
// Runs whenever the value changes
});
Input Event
Very similar to the change event, but input elements also fire this one on every keystroke. This enables handling logic in real-time as the user types.
Reset Event
Fires when a reset button is clicked, allowing you to clear or reset form values using JavaScript.
And more form elements have additional events as well like click, focus, blur, and more. We can handle all user interactions inside forms through events!
Submit Events
The submit event is one of the most important events in form handling. It fires whenever a user attempts to submit a form.
This includes:
- Clicking a button with
type="submit"
- Pressing Enter in a text input field
- Submitting the form through JavaScript code
Some key things we can do on submit:
- Validate form data before sending it
- Modify form values on the fly
- Prevent the default submission behavior
- Display a “Submitting…” message
Here’s an example submit handler:
form.addEventListener('submit', function(e) {
// Validate form
// If valid, show loading spinner
e.preventDefault(); // Prevent default submit
// Collect data
// Make AJAX request to submit data
});
The default behavior reloads the page after a form submits. We often want more control and to send the data asynchronously instead.
Stopping the default action with event.preventDefault()
gives us more flexibility to handle submissions as we please.
Regular Expressions
Regular expressions (or “RegEx”) are pattern matching tools built into JavaScript. They give us an extremely flexible way to: ✅ Validate text formats like emails, phone numbers and more ✅ Replace matched text through search/replace ✅ Extract parts of a string
For example, this regular expression checks if a string is a valid email address:
const emailRegex = /^[^s@]+@[^s@]+.[^s@]+$/;
// Use it like:
if (emailRegex.test(someEmail)) {
// Valid email format
}
The patterns look complicated at first glance, but after some practice they become intuitive!
RegEx is perfect for:
- Form validation
- Making robust input sanitizers
- Improving search algorithms
Testing RegEx Patterns
When first learning regular expressions, testing and debugging patterns is crucial before relying on them. There are a few handy online tools that make RegEx testing easy:
RegExr
RegExr allows you to visualize your expressions by highlighting matches in test strings.
It also explains each part of your pattern in plain English, which is super helpful for breaking it down.
RegEx 101
RegEx 101 is another great playground with various modes like explainers, cheat sheets, and support for different code languages.
These online regex testers are indispensable when debugging a complex validation pattern or learning the syntax.
Unit Testing
For validation functions in your projects, unit test them against various valid and invalid input values:
test('validates phone numbers', () => {
// True
expect(validatePhone('201-555-0134')).toBe(true);
// False
expect(validatePhone('hello world')).toBe(false);
});
Basic Form Validation
Now that we know how to listen for form events and leverage RegEx for matching patterns let’s put them together for form validation.
Here is a simple example with a registration form:
// Get form and inputs
const form = document.querySelector('#register-form');
const emailInput = document.querySelector('#email');
// Valid email pattern
const emailRegex = //...
// Listen for submit
form.addEventListener('submit', e => {
// Validate email
if (emailRegex.test(emailInput.value)) {
// Valid email
} else {
// Show error
e.preventDefault(); // Prevent submit
}
});
We can have as many validations as needed for each input before allowing the form submission. Key principles:
✅ Prevent the default action on invalid
✅ Display clear error messages
✅ Use good UX design
Keyboard Events
In addition to element-specific events like “change” and “submit”, we can also listen for keyboard presses.
Some common keyboard events:
- keydown - User presses a key
- keyup - User releases a key
- keypress - After a full keypress
Here’s an example giving visual feedback as the user types into a text field:
const input = document.querySelector('input');
// Listen for keyup
input.addEventListener('keyup', function(e) {
// Check if key is alphanumeric
if (e.keyCode >= 48 && e.keyCode <= 90) {
// Show icon for valid alphanumeric key
showValidIcon();
} else {
// Invalid key, user should fix
showInvalidWarning();
}
});
We get the pressed key code from event.keyCode
. Useful for validation, interactions, mobile optimization, and more!
Advanced Form Interactions
With a solid grasp on form events and validation, let’s explore some advanced UI interactions to enhance the user experience.
Conditional Logic
We can use JavaScript to conditionally show or hide certain inputs based on previous selections.
For example, toggle additional address fields if a “See my billing address” checkbox is unchecked in checkout. Minimize cognitive load for users by only showing what’s relevant at the moment.
Dynamic Updates
Make forms feel responsive by dynamically updating values or full sections based on input. A few ideas:
- Update form field placeholders based on context
- Show password strength meters as user types
- Pre-fill suggested values from a database
- Add or remove options from selects
This creates a smooth, app-like experience while retaining ease of use.
Form Steppers
Guide users through multi-step forms while breaking down complex processes. Track step progress, move forward/backward as needed, and persist data across sessions.
Advanced form UX principles paired with JavaScript events opens the door for all kinds of possibilities to improve the user experience!
Accessibility Considerations
When building forms, we must ensure they are usable and accessible for all users. Some key areas to focus on:
Semantic Structure
Use proper HTML form element tags like <form>
, <input>
, <select>
, and associated ARIA roles. Screen readers announce them appropriately so users understand it’s a form.
Labels
Every input must have an associated <label>
. It links them programmatically for screen readers and allows clicking the labels to focus the inputs.
Keyboard Navigation
Test only using keyboard - no mouse. All form controls should receive focus as expected. Submit on Enter press, escape closes modals, etc.
Color Contrast
Inputs and error text must meet minimum color contrast ratios so visually impaired users can read them.
Error Messaging
On validation errors, include descriptive error messages associated with inputs. Explain exactly what needs fixing rather than generic alerts.
Form Security
When dealing with sensitive user data, security is paramount. JavaScript introduces some key web vulnerabilities to be aware of when coding forms.
Cross-Site Scripting (XSS)
XSS attacks inject malicious client-side code. Common if you display input data without sanitizing it first.
For example displaying a comment or username straight from POST data. Encode special chars or strip dangerous tags like <script>
from data.
Cross-Site Request Forgery (CSRF)
CSRF tricks users into unknowingly submitting a forged request appearing to come from your site. Protect against it by adding security tokens.
These are just a few basics - security deserves its own thorough discussion! The key is rigorously validating, sanitizing, and encoding all form data server-side before doing anything sensitive with it.
Security Concern | Description | Potential Solutions |
---|---|---|
Cross-Site Scripting (XSS) | Injecting client-side scripts into web apps through insufficiently validated user input that could be displayed and executed in victims' browsers | - Validate and sanitize all user input before displaying - Encode special characters on output - Implement CSP policies restricting sources |
Cross-Site Request Forgery (CSRF) | Tricking users into unknowingly submitting unauthorized commands | - Add CSRF tokens to forms - Validate SameSite cookie protections - Require re-authentication for sensitive operations |
Insecure Direct Object References | Gaining unauthorized access to data by manipulating ID parameters predicting other records | - Indirect reference maps - Permissions checks on server backend |
SQL Injection | Inserting malicious SQL into input fields to gain access or corrupt/delete data | - Parameterized queries - Input validation - Least privilege DB permissions |
HttpOnly Cookie Theft | Stealing session cookies via XSS to impersonate users | - Set cookie HttpOnly flag - Regenerate session on privilege change |
Password Brute Forcing | Guessing weak login passwords through automatic rapid attempts | - Password complexity rules - Account lockouts - Multi-factor authentication |
This visual association of risks and solutions helps quickly identify and mitigate common attack vectors when building secure forms. OWASP is one great resource for more in-depth web security guidance.
Best Practices
When working with JavaScript-powered forms, keep these high-level best practices in mind:
Validate Early, Validate Often
The earlier invalid data can be caught, the better the user experience. Validate on the client side and again on the server. Provide helpful validation messages tailored to each input.
Practice Progressive Enhancement
Forms should function properly without JavaScript. Progressive enhancement means gracefully adding JavaScript to augment default form flows rather than fully overriding them.
Structure for Simplicity
Break bigger forms into composable sections grouped by context. Manage state in a single source of truth object. Structure data for easy serialization/submission.
User Experience Comes First
At every stage, consider the user’s perspective. Is this input clear? Does this validation message help guide to the solution? Remove friction through thoughtful interactions.
Plan for Extensibility
Requirements change over time. Build reusable frameworks for form generation based on configuration. Decouple dependencies to simplify maintenance as forms grow.
Following best practices leads to pleasant, productive form experiences for both users and developers long-term.
Conclusion
We’ve explored many of the fundamentals around working with JavaScript forms and form events - but this only scratches the surface of possibilities.
As a next step, practice building UI interactions leveraging techniques we’ve covered like conditional logic or toggling visibility. See implementing form validation in a real production signup flow.
From there, you could dive deeper into individual topics like:
- Form accessibility practices
- Creative custom input components
- Security hardening forms
- Optimizing performance
- And much more!
Learning forms is like learning the grammar of a language. Master forms in JavaScript, and you can give users delightful, responsive experiences on the modern web.
Help Improve This Page
Spot an error or have a suggestion? This page is a Markdown file, making it easy to contribute:
- Click the "Edit on GitHub" button below
- Look for the pencil icon in the GitHub interface
- Make your changes and submit a pull request
Can't edit directly? Share your feedback or report issues in the comments below. We appreciate your input!