10
Processing Forms with JavaScript

CoffeeRun is off to a good start. It has two JavaScript modules that handle its internal logic and an HTML form styled with Bootstrap. In this chapter, you will write a more complex module that connects the form to the logic, allowing you to use the form to enter coffee orders.

Recall from Chapter 2 that browsers communicate with servers by sending requests for information for a particular URL. Specifically, for every file that the browser needs to load, it sends a GET request to the server for that file.

When the browser needs to send information to a server, such as when a user fills out and submits a form, the browser takes the form data and puts it in a POST request. The server receives the request, processes the data, and then sends back a response (Figure 10.1).

Figure 10.1  Traditional server-side form processing

Traditional server-side form processing

In CoffeeRun, you will not need to send the form data to a server for processing. Your Truck and DataStore modules serve the same purpose as traditional server-side code. Their job is to handle the business logic and data storage for your application.

Because this code lives in the browser and not on a server, you need to capture the data from the form before it goes out. In this chapter you will create a new module called FormHandler to do just that. In addition, you will add the jQuery library to CoffeeRun to help you with your work. As you build out CoffeeRun over the next few chapters, you will use more of jQuery’s powerful features.

Creating the FormHandler Module

The FormHandler module will prevent the browser from trying to send form data to a server. Instead, it will read the values from the form when the user clicks the Submit button. Then it will send that data to a Truck instance, using the createOrder method you wrote in Chapter 8 (Figure 10.2).

Figure 10.2  Application architecture of CoffeeRun with App.FormHandler

Application architecture of CoffeeRun with App.FormHandler

Create a new file called formhandler.js in your scripts folder and add a <script> tag for it in index.html.

...
          </form>
        </div>
      </div>
    </section>
    <script src="scripts/formhandler.js" charset="utf-8"></script>
    <script src="scripts/datastore.js" charset="utf-8"></script>
    <script src="scripts/truck.js" charset="utf-8"></script>
    <script src="scripts/main.js" charset="utf-8"></script>
  </body>
</html>

Like your other modules, FormHandler will use an IIFE to encapsulate the code and attach a constructor to the window.App property.

Open scripts/formhandler.js and create an IIFE. Inside the IIFE, create an App variable. Assign it the existing value of window.App. If window.App does not exist yet, assign it an empty object literal. Declare a FormHandler constructor function, and export it to the window.App property.

(function (window) {
  'use strict';
  var App = window.App || {};

  function FormHandler() {
    // Code will go here
  }

  App.FormHandler = FormHandler;
  window.App = App;

})(window);

So far, this code follows the familiar pattern you used in your Truck and DataStore modules. It will be different soon, though, in that it will import and use jQuery to do its work.

Introduction to jQuery

The jQuery library was created by John Resig in 2006. It is one of the most popular general-purpose open-source JavaScript libraries. Among other things, it provides convenient shorthands for DOM manipulation, element creation, server communication, and event handling.

It is useful to be familiar with jQuery, because there is so much code that has been written using it. Also, many libraries have copied jQuery’s conventions. In fact, jQuery has directly influenced the standard DOM API (document.querySelector and document.querySelectorAll are two examples of this influence).

jQuery will not be covered in depth right now. Instead, aspects of it will be introduced as needed to help you build more complex parts of CoffeeRun. Should you want to explore jQuery further, check out the documentation at jquery.com.

As you did with Bootstrap, you will add a copy of jQuery to your project from cdnjs.com. Go to cdnjs.com/​libraries/​jquery to find version 2.1.4 and copy its address. (There may be a more recent version available, but you should use 2.1.4 for CoffeeRun to avoid any compatibility issues.)

Add jQuery in a <script> tag in index.html.

...
      </div>
    </section>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"
      charset="utf-8"></script>
    <script src="scripts/formhandler.js" charset="utf-8"></script>
    <script src="scripts/datastore.js" charset="utf-8"></script>
    <script src="scripts/truck.js" charset="utf-8"></script>
    <script src="scripts/main.js" charset="utf-8"></script>
...

Save index.html.

Importing jQuery

FormHandler will import jQuery the same way that it is importing App. The reason for doing this is to make it explicit that your module is using code that is defined elsewhere. This is a best practice for coordinating with team members and for future maintenance.

In formhandler.js, create a local variable named $ and then assign it the value window.jQuery.

(function (window) {
  'use strict';
  var App = window.App || {};
  var $ = window.jQuery;

  function FormHandler() {
    // Code will go here
  }

  App.FormHandler = FormHandler;
  window.App = App;

})(window);

When you added the jQuery <script> tag, it created a function named jQuery as well as a variable, named $, pointing to the function. Most developers prefer to use $ in their code. In keeping with that practice, you are importing window.jQuery and assigning it to the local variable $.

Wondering why $ is used for the variable name? JavaScript variable names can contain letters, numbers, the underscore (_), or the dollar sign ($). (They can only start with letters, underscores, or dollar signs, though – not numbers.) The creator of jQuery chose the $ variable name because it is short and unlikely to be used by any other code in a project.

Configuring instances of FormHandler with a selector

Your FormHandler module should be usable with any <form> element. To achieve this, the FormHandler constructor will be passed a selector matching the <form> element in index.html.

Update formhandler.js to add a parameter called selector to the FormHandler constructor. Throw an Error if it is not passed in.

(function (window) {
  'use strict';
  var App = window.App || {};
  var $ = window.jQuery;

  function FormHandler(selector) {
    // Code will go here
    if (!selector) {
      throw new Error('No selector provided');
    }
  }

  App.FormHandler = FormHandler;
  window.App = App;

})(window);

Error is a built-in type that lets you formally signal that there is an unexpected value or condition in your code. For now, your Error instance will simply print out your message on the console.

Save and try instantiating a new FormHandler object without passing it an argument (Figure 10.3). (Remember to start browser-sync, if it is not already running.)

Figure 10.3  Instantiating a FormHandler object without passing arguments

Instantiating a FormHandler object without passing arguments

This is the first step in making FormHandler more reusable. In Ottergram, you created variables for the selectors you used in your DOM code. You will not be doing that with the FormHandler module. Instead, you will use the selector that was passed in to the constructor and use jQuery to find the matching elements.

jQuery is most often used for finding elements in the DOM. To do that, you call the jQuery $ function and pass it a selector as a string. In fact, you use it the same way you have been using document.querySelectorAll (although jQuery works differently under the hood, as we will explain in a moment). It is common to refer to this as “selecting elements from the DOM” with jQuery.

Declare an instance variable named $formElement in formhandler.js. Then find a matching element in the DOM using that selector and assign the result to this.$formElement.

(function (window) {
  'use strict';
  var App = window.App || {};
  var $ = window.jQuery;

  function FormHandler(selector) {
    if (!selector) {
      throw new Error('No selector provided');
    }

    this.$formElement = $(selector);
  }

  App.FormHandler = FormHandler;
  window.App = App;

})(window);

Prefixing a variable with $ is a sign that the variable refers to elements selected using jQuery. This prefix is not a requirement when using jQuery, but it is a common convention used by many front-end developers.

When you use jQuery’s $ function to select elements, it does not return references to DOM elements, the way that document.querySelectorAll does. Instead, it returns a single object, and the object contains references to the selected elements. The object also has special methods for manipulating the collection of references. This object is called a “jQuery-wrapped selection” or “jQuery-wrapped collection.”

Next, you want to make sure that the selection successfully retrieved an element from the DOM. jQuery will return an empty selection if it does not find anything – it will not throw an error if the selector does not match anything. You will need to check manually, because FormHandler cannot do its work without an element.

The length property of a jQuery-wrapped selection tells you how many elements were matched. Update formhandler.js to check the length property of this.$formElement. If it is 0, throw an Error.

(function (window) {
  'use strict';
  var App = window.App || {};
  var $ = window.jQuery;

  function FormHandler(selector) {
    if (!selector) {
      throw new Error('No selector provided');
    }

    this.$formElement = $(selector);
    if (this.$formElement.length === 0) {
      throw new Error('Could not find element with selector: ' + selector);
    }
  }

  App.FormHandler = FormHandler;
  window.App = App;

})(window);

Your FormHandler constructor can be configured to work with any <form> element based on the selector passed in. Also, it keeps a reference to that <form> element as an instance variable. This ensures that your code will not make make unnecessary trips to the DOM. This is a performance best practice. (The alternative is to call $ over and over, which re-selects the same elements each time.)

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.87.161