Javascript vs HTML standard form behavior
Tags: javascript, webdev, html, a11y
Published: 2021-02-08 04:38:23

Forms are useful. They allow us to pass data to a website. We see them everywhere, signup forms, contact forms, and in a million other ways. They are an html way to communicate with other html pages over HTTP. 

You can see how your document tries to communicate with itself with this simple and ugly form.

```html
<form>
  <input name='submission' type='text'>
  <input type='submit'>
</form>
```
If I type the word 'something' then press submit, I get this:

![image](https://dev-to-uploads.s3.amazonaws.com/i/3x45nbn0te92az96k7hd.png "screenshot of a url with a query parameter at the end.")

My URL is updating on form submission! In technical terms, my form is submitting a GET request with the query parameter "submission" set to "something" to the server. This is great for dumb pages or server side rendered applications, but we frontend developers love to handle state on the browser. We could be having state that needs to be persistent, and refreshing the page is unacceptable. (think of a modal popup window with a form, you don't want to refresh the page and make the user re-open it).

So why does the browser refresh happen? Basically, forms in the browser want to pass data to a page. When you submit a form, it redirects you to the page that you submitted the data to. If you don't supply an action attribute to the form, or a method it will submit it to your current page using a GET parameter like we showed above. 

so the HTML code above is doing the same as this. 
```html
<form action="/" method="GET">
  <input name='submission' type='text'>
  <input type='submit'>
</form>
```
The form [action="/"] attribute is telling the browser that we want to post the data to the root URL of the website. The method is expecting an HTTP verb (POST, PUT, PATCH, DELETE, etc...) but GET is the default one. GET requests are appended to the url as shown in the image above. This is handy, but often you don't want that because you don't need that information in your browser history for everyone to see. 

When you submit a form, the browser navigates to the url that you provide to the [action] attribute. However, we said we wanted to avoid page reload all together. To do this, you need to intercept the standard form behavior with javascript. You can actually do this by using the preventDefault() method on the submit event itself.

```html
<form action="/" method="GET" onsubmit="event.preventDefault()">
   <input name='submission' type='text'>
   <input type='submit'>
</form>
```

If you run test again, you no longer get a query string in the URL and your state persists!

![image](https://dev-to-uploads.s3.amazonaws.com/i/91uiyowfzfovdsjlw1xp.png "screenshot of a url without a queryparameter at the end")
(This is a boring image but it shows the form element still holding a value because the page didn't refresh!!)

You are preventing the browser from doing what it does whenever it sees a form element. 

Now let's handle it with javascript because we all know that you should handle everything with javascript (I'm just leaving this here to piss off backend developers). You can do that without writing it in the html by handling it in your js like this:

```html
 <form>
    <input name='submission' type='text'>
    <input type='submit'>
 </form>

<script>
  document.querySelector("form").addEventListener("submit", (event) => event.preventDefault());
</script>
```

Ahh much nicer, we took away the native properties of the form element and told the browser, we'll take it from here. Now we can decide exactly how we want the form to behave.

## Why use forms at all?

So the more adept programmer might say something along the lines of 'if I have to jump through hoops when I put a form element on the page, can't I just omit it altogether?'. And yes, they would be right that they could do the same as the example above only using an input element and a button. However, forms are the 'semantic' way of writing html, which is useful especially for screen readers. Screen readers are all programmed to react predictably to a form element, but if you don't group the functionality of an input with a submit, you'll have to keep track of all that yourself through adding labels and grouping the behavior together. This is possible, but it is not recommended because it introduces more surface area for mistakes appear.  

So there you have it. Hopefully this helps if you are wondering why you are losing the state of the application every time you hit submit on your forms. Stay tuned for more tips and tricks!