Three HTML Form Related Tips That Make Web Developers Life Easier

Three HTML Form Related Tips That Make Web Developers Life Easier

I've recently learned a few things about HTML forms, which are a fundamental part of the web. We web developers spend quite a lot of time and effort making forms simple and accessible so that users can easily accomplish tasks. Even after years of working with these building blocks, we can still learn new things.

Naming things can break the form

A short backstory on an issue that I had with a HTML form: I was working on a page that accepted user input and displayed a warning before submission. The simplified jQuery version would look like this:

var $form = $('#simple-example-form');
$form.on('submit', function (e) {
  ... some logic..

  // prevent submitting the form before user confirms
  e.preventDefault();

  confirm()
    .yup(function() {
      // get the actual DOM element not the jQuery wrapped
      // Call submit to trigger the original form submit
      $form[0].submit(); 
    })
    .nope(function() {
      // close confirmation pop-up etc.
    }); 
})

This is a simplified version of the markup:

<form action="/Account/Edit/1" method="post" id="simple-example-form">
    <input type="hidden" name="id" />
    <label>
      Name
      <input type="text" name="name" />
    </label>
    <label>
      Age
      <input type="number" name="age" />
    </label>
    <input value="Save" id="submit" type="submit">
</form>

Everything looks perfect, right? Unfortunately, the error is difficult to spot.

Remember $form[0].submit();? It results in the error "Submit is not a function." The same error occurs without the jQuery code: document.getElementById('simple-example-form').submit().

The problem is that you can reference any form's input element through the form element itself. For example, if the form has an input element named id then document.getElementById('simple-example-form').name would return HTML input called name instead of the form's name. You can override any form function or property, which is absolutely crazy! In my case, the submit function was overridden by the submit button.

You can easily test this behavior in this playground.

Tip: avoid form control names that might collide with form properties.

Form inputs outside forms

Have you encountered an input element that would be more appropriate outside a form? For example, the form might include two search fields, one in the header and one in the body. A layout with optional sidenotes outside the form is another scenario.

HTML5 introduced a solution: the form attribute.

<form action="/Account/Edit/1" method="post" id="simple-example-form">
    <input type="hidden" name="id" />
    <label>
      Name
      <input type="text" name="name" />
    </label>
    <input value="Save" id="submit" type="submit">
</form>

<input form="simple-example-form" name="note" />

Simply add a form attribute to the HTML control, then you can reference the form by its id. It's great!

Quite often in web development, bad news is lurking around the corner. The website Can I use tells us that Microsoft IE and Edge don't support the form attribute, which, unfortunately, makes it unusable. But wait! You haven't spent time reading this in vain; Edge support of the form attribute is in backlog with priority level Medium. Points to the Edge team for being open about what they are doing.

Tip: use the form attribute appropriately, when it is fully supported by browser vendors.

Forms and form controls are linked

Access all of a document's forms with forms HTMLCollection:

document.forms

The Document object is not the only DOM object that can be traversed. Let's take <label>, for example:

<form action="/Account/Edit/1" method="post" id="cat">
  <label for="age">Age</label>
  <input type="number" name="age">
</form>

We can access this label's form control with label.control! Quite often, you will see this done with jQuery:

var control = $label.attr('for');
var $controlEl = $('[name=' + control + ']');

or

var $controlEl = $label.next();

which would break immediately if the DOM structure changed.

This statement would be better without jQuery:

var control = label.control;

You can also access the associated form with label.form. No more $label.closest('form')!

Tip: sometimes, the native API of the form control is better than the abstraction.

Conclusion

I hope you've learned some new things about forms. Having been web developers for a long time, it is so easy for us to think that we know everything about the basics. Sometimes, it is wise to go back and read or skim through specifications and MDN pages. I've listed a few such tools in the resources. The accessibility aspect of forms is a huge topic, and I highly recommend checking out the writing of Aaron Gustafson. If you like what you have read, please share this and follow me on Twitter

Embedded JavaScriptto get similar content!

Resources