Using JavaScript and forms

Of all the hats JavaScript can wear, its form-processing features are among the most sought and used. Learn how to use JavaScript for form processing, validation, and more.

1 2 Page 2
Page 2 of 2

Thus far we have restricted ourselves to creating forms with plain old JavaScript. In reality, there are many frameworks and libraries that we could use for form handling, ranging from dead simple to very elaborate. We could pick a library dedicated to handling forms, or we could let a generalist framework guide our choices. Let's look at some of the better options.

jQuery

Of the non-reactive libraries, jQuery is the champion and despite its age it remains powerful and up-to-date. (Many of the good ideas about CSS selectors now found in browsers originated with jQuery.) jQuery puts some extra form handling capabilities at your disposal, including plugins and a set of components that can be used to build forms.

jQuery is like vanilla JavaScript with superpowers. It’s a utility library that helps make things easier and helps you avoid having to write the same code over and over. How things work in jQuery is very similar to what you've seen with the examples so far.

Reactive frameworks: React, Vue, Angular, and Svelte

In contrast with a library like jQuery, reactive libraries are quite different from vanilla JavaScript. A reactive library will manage the connection between the UI and the state, which goes for forms, as well. This might seem like a small shift but it turns out to be incredibly powerful.

Listing 5 has a small React form example with some of the ideas we have seen so far implemented in a reactive fashion (you can also check the live version).

Listing 5. A JavaScript form built using React


function MyForm () {
  const [username, setUsername] = React.useState('');
  const [msg, setMsg] = React.useState('');
  const [isValid, setValid] = React.useState(true);
  React.useEffect(() => {
    if (isValid === false) {
      setMsg("Already have that Hobbit!");
    } else {
      setMsg("");
    }
  }, [isValid]);

  function handleUsernameChange (e) {
    setUsername(e.target.value);
  }
  function validateUsername (e){
   if (["frodo","bilbo","sam"].includes(e.target.value)){
     setValid(false);
   } else {
     setValid(true);
   }
  }
  
  function onSubmit(event) {
    event.preventDefault();
    if (isValid){
    	alert('Form submitted. firstName: ' + username);
    } else {
      alert('Invalid username');
    }
  }2

  function handlePasswordChange (e) {
    setPassword(e.target.value)
  }

  return (
    <form onSubmit={onSubmit}>
      <p>Enter something in the box:</p>
      <input type="text" value={username} onChange={handleUsernameChange} onInput={validateUsername}/>
      <p>{msg}</p><p>valid: {JSON.stringify(isValid)}</p>
      <button type='submit'>Submit</button>
    </form>
  )
}

ReactDOM.render(<MyForm />, document.querySelector("#app"))

The first thing you’ll notice is that the markup for the form is no longer in the HTML pane: it now lives inside the JavaScript, in a format called JSX. JSX is like HTML with special JavaScript abilities that link it to the reactive library. (Notice, also, that I switched the “language” to React in the JavaScript panel of the JSFiddle, as shown in Figure 1.)

A JavaScript form. IDG

Figure 1. A JavaScript form created with React.

React takes the single line of markup (<div id="app"/>) and replaces it with the reactive UI defined by the return value of function MyForm (a functional component). If you look at that markup, you’ll see the text input has value={username} defined as an attribute—this is a value binding, a basic form of reactivity. React will ensure that whatever is in the username variable will be set on the input. 

The username value is handled by the useState “hook” (a hook is a fancy kind of function that performs specialized jobs within a functional component), like so: const [username, setUsername] = React.useState('');. This says: give me a reactive variable, “username,” that is set with “setUsername” and initialize it to a blank string. This is generally called the state of the component.

To add our keystroke validation, we use an event listener defined like so: onInput={validateUsername}. This says: when the onInput event triggers, call the validateUsername function. That function was defined earlier in the body of our component, and what it does is set the “isValid” variable according to the same logic of whether the username is already in use (in our real application, we’d call the back-end service). So, in this scenario, isValid is another state variable. 

We then use another hook, useEffect, to watch what happens to isValid. Depending on the state, useEffect will set the value for the msg variable (yet another state variable). If you look at the markup for the component, you can see the msg variable is displayed with this line: <p>{msg}</p> (the curly braces indicate a JavaScript expression to be interpolated into the markup).

When the form is submitted (via the Submit button) we hijack the process with this event listener on the form: <form onSubmit={onSubmit}>. event.preventDefault() ensures the browser default behavior doesn’t occur, and then we use the isValid variable to determine if the form can be submitted or not.

Conclusion

This was a whirlwind tour of JavaScript and some of its applications to forms. The most fundamental power is that JavaScript allows you to take fine-grained control of how form data is handled. Moreover, you can do a variety of useful things like validation and typeahead. Modern applications rely heavily on JavaScript for form processing, often using a reactive framework.

Copyright © 2023 IDG Communications, Inc.

1 2 Page 2
Page 2 of 2