Back to the Basics with HTML Forms
Tags: html, javascript, webdev
Published: 2023-01-14 19:15:41

_Understand the intricacies of how the HTML Form works_

Forms are an essential part of any modern website that allows users to interact with data and submit information. Many modern frameworks like Angular and React have their own implementation and wrappers to facilitate the creation of HTML forms, but it's also important to understand what is happening behind the scenes when you're making an input form. In this article, we're going back to the basics of HTML forms and how to use them.

## Structure of an HTML form

An HTML form is composed of a set of elements for users to interact with. These elements can include an input field, a checkbox, and a submit button. All the information filled in from the form fields can be used to submit information to a web application.

We’re going to create a simple form with two input fields for the username and email address and a submit button. In order to do this, we’re going to introduce three HTML elements:

- `<form>`: The form element is used as a container for various user input fields
- `<input>`: This element allows input for our username and email address
- `<label>`: This element is a caption that is used for the input element

Using these three elements, we can create a simple HTML form like this:

```html
<form>
  <label for="username">Username</label>
  <input name="username" id="username" placeholder="Username" />

  <label for="email">Email</label>
  <input name="email" id="email" placeholder="example@email.com" />

  <input type="submit" value="Submit" />
</form>
```

In this HTML sample, we see some attributes inside the `<label>` and `<input>` elements. Let’s take a look at what they are. 

Inside the `<label>` element, the `for` attribute is used to associate the label with a specific form control. In this case, the label "Username" is associated with the text field that has an **`id`** of "username".

Inside the `<input>` element. we’ve used a couple of attributes:

- `name` : This attribute is used to give the input form control a name. We can identify the correct input with this `name` attribute when the form is submitted.
- `placeholder`: This is used to display placeholder text when the field hasn’t been filled in yet by the user.
- `type`: The final `<input>` element has the attribute `type` with the value submit. This means that it will become a button that submits the form. All `<input>` elements can be given a `type` attribute. If none is defined as in the case of username and email, the default one will be `text`.

When this sample HTML form is displayed by the browser, it will look like this:

![Basic HTML form rendered in the browser](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bgnraayflzsxnwftpus3.png)

## Submitting the form

We’ve created a complete working form with two input elements for username and email and a button to submit the data. What will actually happen when you click on the Submit button? The responsibilities are separated into two parts. The browser or the client is responsible for sending the form data, and the server is responsible for receiving and processing the form data. We’re going to take a look at what happens from the perspective of the browser or client. 

Let’s assume that we’ve filled in `helloworld` and `my@email.com` for the first two input fields.

![HTML form with filled in data](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j87j1h8v5ic6v31b3uhx.png)

When you click on the submit button, a couple of things are going to happen:

- Form data will be collected as a query string based on the input fields like this: `username=helloworld&email=my@email.com`
- The current browser URL will be retrieved. If the form is being served from `localhost:8000`, then that is what the current URL will be.
- The browser will navigate to the current address appended with the query string constructed from the form data. The formula for the constructed address is this: `<currentUrl>?<queryString>`
- The resulting address will be `localhost:8000?username=helloworld&email=my@email.com`

Navigating to this newly constructed URL is in its essence a GET request. It’s up to the server to be able to process this URL with the query string parameters. What we often see with form submissions, is that we would like to do a POST request instead. In addition to that, we might also want to post this request to a specific URL. This can all be achieved by adding the `method` and `action` attributes in the `<form>` element like this

```html
<form method="POST" action="https://myformurl.com">
    ...
</form>
```

If this form gets submitted, the browser is going to perform a `POST` request to the URL [https://myformurl.com](https://myformurl.com) with `username=helloworld&email=my@email.com` as a payload. The request `content-type` header will be set to `application/x-www-form-urlencoded`. It’s then up to the server to be able to process this form submission correctly with the given information. 

## Retrieving the form as a JSON payload

In many modern JavaScript frameworks like Angular, React and Vue, form submission is done via a JSON payload. These frameworks usually don’t use a GET request with query string parameters or a POST request with a payload of content-type `application/x-www-form-urlencoded`. In order to achieve this form extraction as a JSON payload, we are going to add an event listener to the HTML form and some client-side JavaScript. 

The event listener that we are going to add to the HTML form is called `onsubmit`. This event is fired when a form is submitted. When this `onsubmit` event is triggered, we want to call a function named `extractJson()`. We can do it like this:

```html
<form onsubmit="extractJson(event)">
    ...
</form>
```

In this example, the `event` argument is passed to the `extractJson()` function. This object is automatically generated by the browser when the form is submitted. 

We now need some JavaScript to extract the JSON from the HTML form. This can be achieved with the following code:

```jsx
function extractJson(event) {
  event.preventDefault();
  const formData = new FormData(event.target);
  const jsonData = Object.fromEntries(formData);
  console.log(jsonData);

  // Send the JSON payload as a next step
}
```

The line `event.preventdefault();` is used to prevent the default behavior of the form submission to occur. The default behavior, in this case, is the GET request to the current URL with the form data as a query string parameter. 

After preventing the default form behavior, we’re going to use the FormData API to retrieve the FormData which is stored in `event.target`. We use `Object.fromEntries` to convert the `FormData` to a plain JavaScript object and then log into the console. The expected console output will look like this:

```json
{
  "username": "helloworld",
  "email": "my@email.com"
}
```

This resulting variable `jsonData` can be used to send the form data to a server. 

I’ve created a working CodePen sandbox to illustrate the extraction of the form data with these HTML and JavaScript code samples. You can find it over here: https://codepen.io/duncanlew/pen/mdjwMLO. Feel free to play around with it! You can check out the console output by clicking on the Console button in the bottom left corner.

![Console button in CodePen](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k8gob277la95b7iv51zv.png)

I’ve added some CSS in the code sandbox to style the form a bit, but this is of course outside the scope of this article. 💅 All the CSS styling can be commented out so you can see what the unstyled version of the form looks like. This has no effect on the functionality of the form submission. 
![Styled](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e9pxi720v0rn4ahvt0wz.png)

## Wrap-up
HTML forms are one of the basic building blocks in modern websites to interact with data and submit information. Understanding the basics of how HTML forms work and how to use them is an important part of becoming a proficient web developer. With the right configuration, you can even send the form data as a JSON object. Don’t be afraid to take a step back from the modern frameworks and investigate what is happening technically under the hood. Happy coding! 👨‍💻

<hr />
If the content was helpful, feel free to support me [here](https://www.buymeacoffee.com/duncanlew):
<a href="https://www.buymeacoffee.com/duncanlew" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="41" width="174"></a>