Lesson Thursday

The last time we added to our ongoing calculator project, we implemented four separate forms, each with their own submit button and event listener. This was great practice in creating and retrieving information from HTML forms in JavaScript; but it makes our code very repetitive. Let's look into how we can use just one form to handle multiple options.

## Consolidating Multiple Options into One Form

Now that we've spent time exploring JavaScript branching, let's consolidate all four capabilities of our calculatorâ€”addition, subtraction, multiplication, and divisionâ€”into a single form with a single submit button and event listener. We'll add radio buttons that allow the user to choose whether they'd like to add, subtract, multiply, or divide the two numbers provided in the form.

This new, all-inclusive form should look something like this:

calculator.html
``````<!DOCTYPE html>
<html lang="en-US">
<title>Calculator</title>
<script src="js/jquery-3.5.1.js"></script>
<script src="js/scripts.js"></script>
<body>
<div class="container">
<h1>Calculator</h1>
<form id="calculator">
<div class="form-group">
<label for="input1">1st number:</label>
<input id="input1" class="form-control" type="text">
</div>
<div class="form-group">
<label for="input2">2nd number:</label>
<input id="input2" class="form-control" type="text">
</div>
<label>
</label>
</div>
<label>
subtract
</label>
</div>
<label>
multiply
</label>
</div>
<label>
divide
</label>
</div>
<button type="submit" class="btn">Go!</button>
</form>
<div id="output">

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

In the HTML above we've given the form an id of `calculator` and the inputs have the ids `input1` and `input2` (instead of something like `add1` and `add2`, since this form will be used for all operations). We've also added radio buttons to allow users to choose what operation to perform on the two numbers they provide.

### Updating User Interface Logic

Now that we've made these changes, we also need to update `scripts.js` to point to the newly-updated id's when attaching the form submit listener and reading the input values from our form:

js/scripts.js
``````
// Business logic not included because it will remain the same.

\$("form#calculator").submit(function() {
event.preventDefault();
const number1 = parseInt(\$("#input1").val());
const number2 = parseInt(\$("#input2").val());
\$("#output").text(result);
});
});
``````

Here we've changed the form id we're attaching the event listener to in the line `\$("form#calculator").submit(function() {`, and the ids of the form input fields we're gathering values from in the two lines `const number1 = parseInt(\$("#input1").val());` and `const number2 = parseInt(\$("#input2").val());`. We've also added a line to grab the radio button input to determine which operation we'd like to perform on the two numbers: `const operator = \$("input:radio[name=operator]:checked").val();`

Now, if we launch our HTML page in the browser we should see our two inputs and radio buttons:

## Testing and Debugging with console.log()

If we submit the form, it should work. However, we're still calling the `add()` function no matter what mathematical operation the user selects with the line `const result = add(number1, number2);`. Before we address this by adding code to call different functions depending on the radio button value, let's briefly confirm that we're correctly gathering our new form inputs.

We'll add the following instances of `console.log()` to our user interface logic:

js/scripts.js
``````// business logic code not included here because we're not changing it

\$("form#calculator").submit(function() {
event.preventDefault();
const number1 = parseInt(\$("#input1").val());
const number2 = parseInt(\$("#input2").val());
console.log("1st number: " + number1);  // for debugging
console.log("2nd number: " + number2);  // for debugging
console.log("operator: " + operator);  // for debugging
\$("#output").text(result);
});
});
``````

Here, we've added three `console.log()` lines that log our inputted values to the JavaScript console. For the purposes of debugging, `console.log()` works similarly to`alert()` but prints values in the JavaScript console, instead of a pop-up dialog box. Now, if we complete and submit the form, we should see something like this appear in the console:

This confirms that the code gathering our form input values is indeed retrieving the correct information, and doing so successfully. Using `console.log()` in this manner is a great debugging approach. If our form were not functioning correctly, or if our calculator was providing us odd, unexpected results (such as `NaN`) we could use `console.log()`to double-check that our values are being retrieved. And, if they weren't, we could pinpoint which value is causing the issue, and double-check that we're retrieving this value with the correct HTML id.

`console.log()` should be a go-to tool in your debugging tool belt when working in JavaScript!

## Implementing Branching

Now that we've confirmed we're successfully collecting form input values, let's add branching to call the appropriate function based on the user's selected radio button:

js/scripts.js
``````// business logic code not included here because we're not changing it

\$("form#calculator").submit(function() {
event.preventDefault();
const number1 = parseInt(\$("#input1").val());
const number2 = parseInt(\$("#input2").val());
let result;
} else if (operator === "subtract") {
result = subtract(number1, number2);
} else if (operator === "multiply") {
result = multiply(number1, number2);
} else if (operator === "divide") {
result = divide(number1, number2);
}
\$("#output").text(result);
});
});
``````

Here, we've simply added an `if...else` statement that calls different methods depending on what radio button the user has selected. For instance, if they select "divide", we run our `divide()` function; if they select "subtract", we run our `subtract()` function, etc. Regardless of which operation they opt to perform, we still insert the answer onto our page with the same line, `\$("#output").text(result);`.

Notice in the code above that we declared the variable `result` outside the `if...else` statement, but we did not immediately give it a value. We simply told JavaScript that it exists. It will have the value of `undefined` until we define its value depending on which branch we're following. Then, after the `if...else` statement, we stick the value of result into the `#output` div.

By the way, you might be wondering why there is no `else` condition in the code above. Remember that anything that our other statements don't cover will end up in the `else` condition. If you don't have an `else` condition, it just means the code will move on. We could, of course, add an `else` condition that returns `"Error - unrecognized operator"`. It's not necessary for the code to function but it could be helpful for users to understand what went wrong.

Keep in mind, though, that we wouldn't want to use an `else` statement for something like division, though. What if someone entered `cosine`, for example? It shouldn't default to division. That's why, in this case, an `else` statement would likely just be used to handle errors and operands the code doesn't recognize.

## Additional Note on Separation of Logic

Also, notice that because we made sure to separate our user interface and business logic in `scripts.js`, we only had to change the user interface logic when we made changes to our HTML! This is yet another benefit of keeping user interface and business logic well-separated; when you need to alter how the user will interact with your site, you'll only need to update JavaScript in one place, instead of untangling the whole file.

## Example Code

calculator.html
``````<!DOCTYPE html>
<html lang="en-US">
<title>Calculator</title>
<script src="js/jquery-3.5.1.js"></script>
<script src="js/scripts.js"></script>
<body>
<div class="container">
<h1>Calculator</h1>
<form id="calculator">
<div class="form-group">
<label for="input1">1st number:</label>
<input id="input1" class="form-control" type="text">
</div>
<div class="form-group">
<label for="input2">2nd number:</label>
<input id="input2" class="form-control" type="text">
</div>
<label>
</label>
</div>
<label>
subtract
</label>
</div>
<label>
multiply
</label>
</div>
<label>
divide
</label>
</div>
<button type="submit" class="btn">Go!</button>
</form>
<div id="output">

</div>
</div>
</body>
</html>
``````
js/scripts.js
``````function add(number1, number2) {
return number1 + number2;
}

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

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

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

\$("form#calculator").submit(function() {
event.preventDefault();
const number1 = parseInt(\$("#input1").val());
const number2 = parseInt(\$("#input2").val());
let result;
} else if (operator === "subtract") {
result = subtract(number1, number2);
} else if (operator === "multiply") {
result = multiply(number1, number2);
} else if (operator === "divide") {
result = divide(number1, number2);
}
\$("#output").text(result);
});
});
``````

Lesson 59 of 62
Last updated January 3, 2022