Form Basics

Difficulty: Intermediate

The <form> element is the container for all interactive controls that allow users to submit data to a server. It is one of the most important elements in HTML because nearly every web application -- from login pages to search bars to checkout flows -- relies on forms to collect user input. Understanding how forms work at the HTML level is essential even when using modern frontend frameworks.

The action attribute specifies the URL where the form data should be sent when submitted. If omitted, the form submits to the current page URL. The method attribute determines the HTTP method used for submission. The two primary methods are GET and POST. GET appends form data to the URL as query parameters (e.g., /search?q=javascript) and is suitable for non-sensitive, idempotent requests like search queries. POST sends data in the request body, making it suitable for sensitive data (passwords, personal info) and operations that modify server state (creating accounts, placing orders).

The enctype attribute specifies how form data is encoded before being sent to the server. The default value is application/x-www-form-urlencoded, which encodes data as key=value pairs separated by ampersands. When the form includes file uploads, you must use multipart/form-data, which sends each field as a separate part of the request body. A third option, text/plain, sends data with minimal encoding and is rarely used in production.

Form submission is triggered by clicking a <button type="submit"> or <input type="submit">, or by pressing Enter while focused on a form input. You can prevent the default submission behavior using JavaScript's event.preventDefault() method, which is the standard approach in single-page applications where you want to handle submission with AJAX/fetch instead of a full page navigation.

Modern web development typically uses JavaScript to handle form submission via the Fetch API or XMLHttpRequest rather than relying on the browser's native form submission. However, understanding the native form behavior is crucial because it provides the fallback behavior, governs how browsers handle autofill and validation, and is tested in interviews. Progressive enhancement starts with a working HTML form and layers JavaScript on top.

Code examples

Basic Form with GET Method

<form action="/search" method="GET">
  <label for="query">Search:</label>
  <input type="text" id="query" name="q" placeholder="Enter search term">
  <button type="submit">Search</button>
</form>

<!-- Submitting with "javascript" produces:
     /search?q=javascript -->

A search form using GET. The form data is appended to the URL as query parameters. The name attribute on the input determines the parameter key (q), and the user's input becomes the value.

Form with POST Method

<form action="/api/login" method="POST">
  <label for="email">Email:</label>
  <input type="email" id="email" name="email" required>

  <label for="password">Password:</label>
  <input type="password" id="password" name="password" required>

  <button type="submit">Log In</button>
</form>

A login form using POST. Sensitive data like passwords should always be sent via POST so they appear in the request body rather than the URL. The required attribute prevents submission if the field is empty.

File Upload Form with enctype

<form action="/api/upload" method="POST" enctype="multipart/form-data">
  <label for="avatar">Profile Picture:</label>
  <input type="file" id="avatar" name="avatar" accept="image/*">

  <label for="username">Username:</label>
  <input type="text" id="username" name="username" required>

  <button type="submit">Upload</button>
</form>

When a form includes file inputs, you must set enctype to multipart/form-data. Without this, the file will not be transmitted correctly. The accept attribute restricts the file picker to image files.

Preventing Default Submission with JavaScript

<form id="signup-form" action="/api/signup" method="POST">
  <input type="text" name="name" placeholder="Full Name" required>
  <input type="email" name="email" placeholder="Email" required>
  <button type="submit">Sign Up</button>
</form>

<script>
  document.getElementById('signup-form')
    .addEventListener('submit', function(event) {
      event.preventDefault();

      const formData = new FormData(event.target);
      fetch('/api/signup', {
        method: 'POST',
        body: formData
      })
      .then(response => response.json())
      .then(data => console.log('Success:', data))
      .catch(error => console.error('Error:', error));
    });
</script>

In single-page applications, you typically prevent the browser's default form submission and handle it with JavaScript using the Fetch API. The FormData constructor extracts all named form values automatically.

Key points

Concepts covered

form Element, action, method, GET, POST, enctype