React: You May Not Need Controlled Form Components

To work with forms in React two approaches are to either use Controlled Components or use Uncontrolled Components (as detailed here). Swyx shares a third way of working with forms:

A lower friction way to handle form inputs is to use HTML name attributes. As a bonus, your code often turns out less React specific!

The key is to add an onchange handler onto the form. From there you can access event.currentTarget to get the form, and then add .nameOfTheInput to it.

// 31 lines of code
function NameForm() {
  const handleSubmit = (event) => {
    event.preventDefault();
    if (event.currentTarget.nameField.value === 'secretPassword') {
      alert('congrats you guessed the secret password!')
    } else if (event.currentTarget.nameField.value) {
      alert('this is a valid submission')
    }
  }
  const handleChange = event => {
    let isDisabled = false
    if (!event.currentTarget.nameField.value) isDisabled = true
    if (event.currentTarget.ageField.value <= 13) isDisabled = true
    event.currentTarget.submit.disabled = isDisabled
  }
  return (
    <form onSubmit={handleSubmit} onChange={handleChange}>
      <label>
        Name:
        <input type="text" name="nameField" placeholder="Must input a value"/>
      </label>
      <label>
        Age:
        <input type="number" name="ageField" placeholder="Must be >13" />
      </label>
      <div>
        <input type="submit" value="Submit" name="submit" disabled />
      </div>
    </form>
  );
}

Feels weird to manipulate the form’s submit button disabled state directly 😅

You May Not Need Controlled Form Components →

Why you should probably avoid using <input type="number" />

The fine folks at GOV.UK:

Until now, the GOV.UK Design System date input component used the HTML element <input type="number" /> to provide a number keypad when a user enters dates.

However, we recently moved away from <input type="number"> to <input type="text" inputmode="numeric" pattern="[0-9]*">

Why the GOV.UK Design System team changed the input type for numbers →

Sounds familiar? That’s because the same recommendation was done in the HTML attributes to improve your users’ two factor authentication experience post 🙂

Netlify Forms – Manage forms and submissions without any server-side code

Wow, this is an awesome addition to Netlify:

On Netlify, any HTML form can instantly accept submissions—no backend code or infrastructure required. As soon as your form is deployed, you start seeing submissions appear in your Netlify dashboard.

Just add the netlify attribute to any form and everything gets wired up automatically.

Netlify will automatically create some backend code to handle the form submissions. The submissions will be stored and then shown in your control panel. Comes with a free tier of 100 submissions/month.

Netlify Forms →

Video by Phil Hawksworth

HTML attributes to improve your users’ two factor authentication experience

There are plenty of opportunities for friction in the user experience when logging in, particularly while entering a two factor authentication code. As developers we should be building applications that support the need for account security but don’t detract from the user experience. Sometimes it can feel as though these requirements are in a battle against each other.

In this post we will look at the humble <input> element and the HTML attributes that will help speed up our users’ two factor authentication experience.

The final markup to trigger the correct keyboard and have the browser autocomplete the received SMS code is this:

<input
  type="text"
  name="token"
  id="token"
  inputmode="numeric"
  pattern="[0-9]*"
  autocomplete="one-time-code"
/>

HTML attributes to improve your users’ two factor authentication experience →

🚨 Do note that 2FA using SMS is not secure, mainly due to the lacking policies at SIM providers easily allowing SIM port hacks. The recently announced origin-bound OTP addition as proposed by Webkit/Apple won’t make any difference in the case of a SIM hack.

React Hook Form – Form Validation Hook based on Uncontrolled Components

Now this is an interesting approach, building further upon Uncontrolled Components:

The React Hook Form (react-hook-form) library provides a new form validation mechanism which embraces uncontrolled form validation and support controlled components.

The core idea is to register HTML input’s ref into the custom hook and therefore subscribe to its input value, validate and evaluate the form submission.

I guess this one makes more sense to many as it immediately gives you a values object containing all form values. Validation is also built-in

import React from "react";
import useForm from "react-hook-form";

const Example = () => {
  const { handleSubmit, register, errors } = useForm();
  const onSubmit = values => {
    console.log(values);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input
        name="email"
        ref={register({
          required: 'Required',
          pattern: {
            value: /^[A-Z0-9._%+-][email protected][A-Z0-9.-]+\.[A-Z]{2,4}$/i,
            message: "invalid email address"
          }
        })}
      />
      {errors.email && errors.email.message}

      <input
        name="username"
        ref={register({
          validate: value => value !== "admin" || "Nice try!"
        })}
      />
      {errors.username && errors.username.message}

      <button type="submit">Submit</button>
    </form>
  );
};

React Hook Form Presentation (Twitter Thread) →
React Hook Form →

💡 The React Hook Form Twitter Thread was compiled from its origin tweet to one single page using Threader

Making a Better Custom Select Element

24ways – the advent calendar for web geeks – is back! First post is “Making a Better Custom Select Element” in which Julie Grundy tries to create an accessible Custom Select Element:

Sometimes, I can’t recommend the select input. We want a way for someone to choose an item from a list of options, but it’s more complicated than just that. We want autocomplete options. We want to put images in there, not just text. The optgroup element is ugly, hard to style, and not announced by screen readers. The focus styles are low contrast. I had high hopes for the datalist element, but although it works well with screen readers, it’s no good for people with low vision who zoom or use high contrast themes.

Here’s a pen with the result:

Making a Better Custom Select Element →

An HTML attribute potentially worth $4.4M to Chipotle

Jason Grigsby:

I recently found myself racing to fill out Chipotle’s online order form before my mother could find her credit card. In the process, I discovered a bug that could cost Chipotle $4.4 million annually.

The form didn’t play nice with autocomplete and therefore would not get sent …

The culprit? A JS library which enforced a 2-digit pattern on the card details’ year field, thus truncating the autocompleted value (202320).

The solution? The pattern attribute, which the autocomplete feature can detect, thus passing in a correctly shortened valued (202323)

An HTML attribute potentially worth $4.4M to Chipotle →

Button Placement in Forms

Button placement on forms is often ignored or prioritised based on what looks good.

But button placement can make or break a form, and a form can make or break a user’s experience. That’s why it’s essential to get it right.

Here I’ll explain where to put buttons across a range of different forms based on research and best practice.

Where to put buttons on forms →

🤔 I found this one highly interesting to read as I tend to do the exact opposite when it comes to placing buttons. Inspired by macOS I place the primary button on the right, the secondary button to the left of the primary one, and the cancel option at the very left.

I’m wondering what Johan (Interface Designer) and Roel (Digital Accessibility Nerd) their take is on this …

UPDATE 2019.09.18: Thanks to (requested) input by Johan/Roel/Xavier we can safely conclude that the mentioned guidelines are not perfect.

As Johan mentions in the comments below:

I agree with your take mentioned in this blog post.

When there is only a single submit at the bottom of a typical form I do agree with aligning it left (in the linked post).

Roel also chimes in on placing the primary button on the right as all OS conventions do so. He however does wonder:

But, then again: web forms are not dialog windows…

As Xavier mentions on Twitter:

It doesn’t matter how your primary button is aligned. What matters is where all of the other buttons are relative to your primary action & inputs.

I think the main gist is that:

  • As the OS places primary actions on the right (in a left-to-right language that is), it’s a good idea to do so to as users are used to that.
  • If you do diverge from it, be consistent (cfr. Design Principle #9)

Thanks for the input y’all!

Clicking Buttons: Inconsistent behavior across browsers

Great research by Zell Liew:

I noticed browsers were inconsistent in how they handle a click on <button>. Some browsers choose to focus on the button. Some browsers don’t.

In this article, I want to show you my test and findings. Then, I want to talk about a way to overcome these inconsistencies.

Great to see all those illustration gifs to show what’s going one. Must’ve taken a ton of work to create them all.

Inconsistent behavior among browsers when clicking on buttons →

Hierarchic Indeterminate Checkboxes with JavaScript (Vanilla)

Earlier today Chris Coyier tweeted that he was in the process of rewriting one of his pens without jQuery:

Sparked by his tweet I decided to fork his pen and try to do it myself. Here’s the result:

A fun exercise if I say so myself, even though I’m not 100% satisfied with the manual traversal I needed to do (.parentElement.parentElement — really?). Perhaps there’s a better way to do this?

Did this help you out? Like what you see?
Thank me with a coffee.

I don't do this for profit but a small one-time donation would surely put a smile on my face. Thanks!

☕️ Buy me a Coffee (€3)

To stay in the loop you can follow @bramus or follow @bramusblog on Twitter.