Lesson Wednesday

Now that we know how to use jQuery to gather input from forms, let's return to our calculator app. We should already have the business logic in place, but it still needs a user interface.

Remember, just as we discussed previously, business (or back-end) logic handles calculations and manipulation of data 'behind the scenes', and user interface (or front-end) logic handles interacting with the user, including gathering user input, updating and displaying information on the page, etc. Furthermore, our project should be organized in a manner that keeps these two types of logic distinctly separate.

In this lesson we'll walk through adding user interface (front-end) logic to our existing calculator application, further explore the differences between business and user interface logic, and address how to keep them properly separated. For now we will focus exclusively on our addition functionality. In subsequent lessons we'll expand our user interface to support subtraction, division and multiplication too.

Linking Resources

Clone your existing calculator application, and we'll pick up right where we left off. (If you're concerned your previous calculator project may not contain the correct code, don't worry! All necessary code for a functioning calculator is present in this lesson for review.)

If you were able to complete all directions in the Practice: Calculator Business Logic exercise, your project should already contain an HTML file. Let's update its <head> section to link to everything our application will need. This includes a link to Bootstrap, our own CSS stylesheet, the jQuery library, and our own custom JavaScript scripts.js file.

Here's an example HTML file with these resources correctly linked:

calculator.html
<!DOCTYPE html>
<html>
  <head>
    <title>Calculator</title>
    <link href="css/bootstrap.css" rel="stylesheet" type="text/css">
    <link href="css/styles.css" rel="stylesheet" type="text/css">
    <script src="js/jquery-1.12.4.js"></script>
    <script src="js/scripts.js"></script>
  </head>
  <body>
    <h1>Calculator</h1>
  </body>
</html>

Do note that the file above assumes you've downloaded bootstrap.css into your project's css folder and the latest version of jQuery into your project's js folder, as we've covered in previous lessons. You should already have a scripts.js file in your js folder containing the JavaScript business logic we wrote in the previous calculator exercise.

Additionally, make sure the link to jQuery comes before the link to your own scripts.js file. Because we're going to write code in scripts.js that will use jQuery, our application must load the jQuery library before it loads scripts.js. If jQuery isn't loaded beforehand, our application won't know what to do when it reaches the jQuery code in scripts.js because it won't even know what jQuery is yet! Always link any scripts files that use jQuery after you link the jQuery library itself.

Adding Forms

Now that we have our necessary resources in place, let's begin adding to our application's HTML. Instead of asking the user to provide our calculator numbers with dialog boxes, let's allow them to submit numbers through our actual HTML web page. To do this, we'll add an HTML form.

Since we're focusing only on creating a user interface for our addition functionality for now, we'll give this form the id add. We'll use this id to target the form later on in our jQuery code:

calculator.html
<!DOCTYPE html>
<html>
  <head>
    <title>Calculator</title>
    <link href="css/bootstrap.css" rel="stylesheet" type="text/css">
    <link href="css/styles.css" rel="stylesheet" type="text/css">
    <script src="js/jquery-1.12.4.js"></script>
    <script src="js/scripts.js"></script>
  </head>
  <body>
    <div class="container">
      <h1>Calculator</h1>
      <form id="add">
        <div class="form-group">
          <label for="add1">1st number:</label>
          <input id="add1" class="form-control" type="text">
        </div>
        <div class="form-group">
          <label for="add2">2nd number:</label>
          <input id="add2" class="form-control" type="text">
        </div>
        <button type="submit" class="btn">Add!</button>
      </form>
    </div>
  </body>
</html>

Adding User Interface Logic

Our scripts.js file should already contain some code. If you successfully completed the previous calculator exercise, the business logic present in your scripts.js file should look similar to this:

var add = function(number1, number2) {
  return number1 + number2;
};

var subtract = function(number1, number2) {
  return number1 - number2;
};

var multiply = function(number1, number2) {
  return number1 * number2;
};

var divide = function(number1, number2) {
  return number1 / number2;
};

And the code currently responsible for gathering user input should resemble this:

var number1 = parseInt(prompt("Enter a number:"));
var number2 = parseInt(prompt("Enter another number:"));

alert(add(number1, number2));

If your calculator's business logic doesn't resemble the examples above yet, pause here and take some time to review the example code, or revisit the Practice: Calculator Business Logic exercise before moving forward. We'll continue to add to this calculator project in future lessons, so make sure your version is up-to-date.

Gathering Form Input with jQuery

Now, let's change the logic responsible for interacting with the user. Let's add functionality to gather information the user has supplied in our new form when they hit 'submit'. This will be much nicer than relying on those pesky pop-up dialog boxes.

We'll begin by moving our existing user interface logic into a function passed to $(document).ready(). We only want logic responsible for interacting with the user in this block of code that begins with $(document).ready(). The business logic code should not be within this function, but the jQuery user interface logic should. This is because it's fine if the business logic functions are loaded into the computer's memory before the HTML finishes rendering, but we don't want to begin dealing with input or output until the HTML document is fully loaded. Otherwise, we could hit some pretty big errors.

Our scripts.js file should now look like this (although you don't need the comments; those are just for reference here in this lesson):

js/scripts.js

// Business (or back-end) logic:

var add = function(number1, number2) {
  return number1 + number2;
};

var subtract = function(number1, number2) {
  return number1 - number2;
};

var multiply = function(number1, number2) {
  return number1 * number2;
};

var divide = function(number1, number2) {
  return number1 / number2;
};

// Everything below this line is user interface (or front-end) logic:

$(document).ready(function() {
  var number1 = parseInt(prompt("Enter a number:"));
  var number2 = parseInt(prompt("Enter another number:"));

  alert(add(number1, number2));
});

Now, let's add code to gather the data users provide in our form. Before we add this directly into scripts.js, let's experiment in the console. Visit your HTML page, and enter some values in the form. Then, if we open the JavaScript console on that same page we can test out the following jQuery to see what will successfully return the input we've placed in the form.

Let's try out the following lines of jQuery:

  • $("#add1").val();
  • $("#add2").val();

Here, we're targeting two HTML form elements in each of the two lines listed above. An input with the id of add1 and an input with the id of add2 and calling .val() to fetch the current value of that form.

testing-jquery-for-retrieving-calculator-form-values

And hey, it works! We can see that each of these two lines of jQuery successfully returned the value currently present in the respective form fields. Now that we know these two lines of code gather the information we need, we can include them in our user interface logic:

$(document).ready(function() {
  var number1 = parseInt($("#add1").val());
  var number2 = parseInt($("#add2").val());
  alert(add(number1, number2));
});

Here, we're replacing the values retrieved via prompt() dialog boxes with jQuery to instead retrieve these values from our form. We still need parseInt() because, like the information we gathered with prompt() dialog boxes, content gathered from form inputs is also always in string format, and our calculator's add() function requires numbers.

Waiting for Users to Submit Form

Now, if we open our HTML file in the browser, it displays our form, but immediately greets us with an alert reading NaN. Even though we're now waiting for the html document to finish loading!

no-submit-listener-resulting-in-alert-with-NaN

This is because we're not actually waiting for the user to submit the form, and the alert above is being triggered after the HTML loads, but before the user has time to fill our form out! Our code is grabbing the empty form inputs and attempting to add them together, resulting in the NaN value we see here.

Ideally we want to wait until the user actually submits the form. Let's add a form submit event handler and its accompanying event.preventDefault() we discussed in the Forms lesson:

js/scripts.js
var add = function(number1, number2) {
  return number1 + number2;
};

var subtract = function(number1, number2) {
  return number1 - number2;
};

var multiply = function(number1, number2) {
  return number1 * number2;
};

var divide = function(number1, number2) {
  return number1 / number2;
};

$(document).ready(function() {
  $("form#add").submit(function(event) {
    event.preventDefault();
    var number1 = parseInt($("#add1").val());
    var number2 = parseInt($("#add2").val());
    alert(add(number1, number2));
  });
});

Displaying Results Directly in HTML

If we refresh our page and try again, everything should work correctly this time:

calculator-alert-dialog-with-correct-value

We don't see that alert dialog box with the result until after we provide two numbers and submit the form. Perfect!

However, that pop-up alert() dialog doesn't make for the nicest user interface. Instead, let's display our calculator's answer directly in our HTML web page and bypass the need for pop-up dialogs all together. This is also part of the user interface logic.

Below the form, let's add in an empty div where we may place the result. We'll give it an id of output in order to target it using jQuery:

calculator.html
<!DOCTYPE html>
<html>
  <head>
    <title>Calculator</title>
    <link href="css/bootstrap.css" rel="stylesheet" type="text/css">
    <link href="css/styles.css" rel="stylesheet" type="text/css">
    <script src="js/jquery-1.12.4.js"></script>
    <script src="js/scripts.js"></script>
  </head>
  <body>
    <div class="container">
      <h1>Calculator</h1>
      <form id="add">
        <div class="form-group">
          <label for="add1">1st number:</label>
          <input id="add1" class="form-control" type="text">
        </div>
        <div class="form-group">
          <label for="add2">2nd number:</label>
          <input id="add2" class="form-control" type="text">
        </div>
        <button type="submit" class="btn">Add!</button>
      </form>
      <div id="output">

      </div>
    </div>
  </body>
</html>

And, instead of popping up that alert dialog, we'll simply replace the contents of our new output div with the result, using jQuery's .text() method. Let's also assign the result of our add() method to the variable name result, then simply insert result directly onto our page in order to make our code clean and easy to follow:

js/scripts.js
var add = function(number1, number2) {
  return number1 + number2;
};

var subtract = function(number1, number2) {
  return number1 - number2;
};

var multiply = function(number1, number2) {
  return number1 * number2;
};

var divide = function(number1, number2) {
  return number1 / number2;
};

$(document).ready(function() {
  $("form#add").submit(function(event) {
    event.preventDefault();
    var number1 = parseInt($("#add1").val());
    var number2 = parseInt($("#add2").val());
    var result = add(number1, number2);
    $("#output").text(result);
  });
});

Now, we should be able to run our application in the browser, insert two numbers into the form fields, and submit the form to see our answer added to the page! Perfect!

calculator-result-appearing-directly-on-page

You may have noticed that our calculator's user interface only offers the option to add two numbers together; despite our business logic containing functions that offer subtraction, multiplication, and division too. In future lessons we'll add support for users to choose which mathematic operation they'd like to execute on the provided numbers, instead of defaulting to addition.

But for now, we have a fully functioning addition calculator, complete with a user interface. That's awesome!

Separation of Logic Review

Let's take a moment to review the manner we organized our business and user interface logic:

js/scripts.js

// Business (or back-end) logic:

var add = function(number1, number2) {
  return number1 + number2;
};

var subtract = function(number1, number2) {
  return number1 - number2;
};

var multiply = function(number1, number2) {
  return number1 * number2;
};

var divide = function(number1, number2) {
  return number1 / number2;
};

// User interface (or front-end) logic:

$(document).ready(function() {
  $("form#add").submit(function(event) {
   event.preventDefault();
    var number1 = parseInt($("#add1").val());
    var number2 = parseInt($("#add2").val());
    var result = add(number1, number2);
    $("#output").text(result);
  });
});

We can see that the business logic and user interface logic are in distinctly separate sections of our scripts.js file. The user interface sections is responsible for gathering user-provided values, parsing them into integers, and calling our add() function when the user submits a form. It also displays the result of the add() function directly on the page for the user to view. Essentially, this section is handling all interactivity with our user. It can call a back-end function (as seen in the line var result = add(number1, number2);), but the function is not defined here in this block of code. That's the responsibility of the business, or back-end logic.

The business logic contains functions for all capabilities our calculator will eventually have. It instructs our application what to do when a user opts to add two numbers, versus what to do when a user opts to divide two numbers (a feature we'll add later on). However, notice that it does not contain anything that interacts with the user. All logic here occurs 'behind the scenes'. The user interface logic may call one of the business logic's functions when necessary, but the functions themselves are defined in the back-end or business logic.

This is ideal separation between front and back-end logic. They're distinctly separate areas of our scripts.js file, are responsible for distinctly different things, and our front-end logic simply calls functions defined in the back-end when necessary.

Now that we've created a working application with functioning front and back-end logics, revisit the Business and User Interface Logic if necessary.

Additional Resources

Before we move on make sure to also take a look at the jQuery documentation. It may feel a bit overwhelming at first, since it contains many concepts we haven't yet covered, but that's absolutely okay! Reading documentation is an incredibly important part of programming, so begin to familiarize yourself with it now. Not everything may make sense, but you'll be surprised at the amount you do understand after only a few weeks of programming!

In particular, check out the sections on Effects, Mouse Events, Form Events, Manipulation, and Traversing. Consider trying out some of the methods listed here in your next project!

And in the future, when you're trying to figure out how to do something with jQuery, the documentation is always the first place to look.

Examples


Example calculator HTML:

calculator.html
<!DOCTYPE html>
<html>
  <head>
    <title>Calculator</title>
    <link href="css/bootstrap.css" rel="stylesheet" type="text/css">
    <link href="css/styles.css" rel="stylesheet" type="text/css">
    <script src="js/jquery-1.12.4.js"></script>
    <script src="js/scripts.js"></script>
  </head>
  <body>
    <div class="container">
      <h1>Calculator</h1>
      <form id="add">
        <div class="form-group">
          <label for="add1">1st number:</label>
          <input id="add1" class="form-control" type="text">
        </div>
        <div class="form-group">
          <label for="add2">2nd number:</label>
          <input id="add2" class="form-control" type="text">
        </div>
        <button type="submit" class="btn">Add!</button>
      </form>
      <div id="output">

      </div>
    </div>
  </body>
</html>

Example calculator JavaScript, including both business and user interface logic:

js/scripts.js
// This is the business (or back-end) logic:

var add = function(number1, number2) {
  return number1 + number2;
};

var subtract = function(number1, number2) {
  return number1 - number2;
};

var multiply = function(number1, number2) {
  return number1 * number2;
};

var divide = function(number1, number2) {
  return number1 / number2;
};

// Everything below this line is the user interface (or front-end) logic: 

$(document).ready(function() {
  $("form#add").submit(function(event) {
    event.preventDefault();
    var number1 = parseInt($("#add1").val());
    var number2 = parseInt($("#add2").val());
    var result = add(number1, number2);
    $("#output").text(result);
  });
});

Tips


  • Always link any scripts files that use jQuery after you link the jQuery library itself. Otherwise your application won't know how to handle jQuery code, since it doesn't even know what jQuery is.

Resources