Overview

Two-week lab

The lab will be done over the course of two weeks. Part 1 implements a simple page using HTML forms and javascript for event handlers. Part 2 adds conditionals to the coffee form, and also covers the javascript needed to calculate the GIF file size ( you will be performing these calculations on the next assignment).

In week one, we expect to get through Task 5 of Part 1. In week two, we will continue Part 1 at Task 6. We are starting to learn about conditional execution of javascript code, this part of the lab will help us practice using conditionals, which will also be a part of the next assignment.

Where to put your javascript code

In an earlier lab using javascript, we put all our javascript code directly in the body of our HTML page, although we mentioned that the best practice is to keep javascript in a separate file (as we do for CSS). We will now learn how to put our javascript code in a separate file, and we ask you to do that on the next assignment and upcoming work, as well.

Refer to the lecture notes on:

for more information.

Lab 6 Part 1: Coffee Calculations Form

In our first lab using javascript, we experimented with accepting input from the viewer of a webpage by using the prompt() function . The prompt function uses a pop-up dialog box, which can be disruptive to the viewer experience of a website. We have since learned in lecture that there are a number of HTML <form> elements which allow the user to enter values directly onto the webpage, and also that we can use javascript to define event handlers for accepting and processing user input.

We'll work with a simple form that asks the user to supply two pieces of information

  1. how much does their favorite cup of coffee cost, and
  2. how many cups do they consume per week.

Here is a screen shot of the original form (note how the space below the horizontal white line is empty):

original form

Once the user has filled out these two form fields, the form performs some calculations. Let's consider what happens when the user supplies two valid inputs. The user fills in the information (two different scenarios are shown here):
original form with user input original form with user input

When the user clicks on the "Calculate Costs" button, the following tasks are performed:

  1. The amount of money spent on coffee per week is calculated
  2. The amount of money spent on coffee per month is calculated
  3. The calculated amounts are displayed on the page.
  4. A feedback message is also displayed, based on the amount spent per week.

original form with results displayed original form with results displayed

And here is a final screen shot, showing where the text shows up in the page: original form with results displayed


Task 1: Create the HTML

Put all your files for today in a folder called lab6, so you can upload them to the server at the end of lab. Also, make sure you keep the javascript error console open while you work. Here is the set up that we will be creating today:

  1. Define HTML code in a file called coffee.html to implement the full page with results displayed shown above (check the lecture notes for details of the HTML syntax for the inputs).
  2. Leave each of the amounts to be filled in the paragraph <span> elements initially, with blank values. Do not worry about styling CSS or adding javascript right now, just get the HTML elements to appear on the page.
  3. Add the following to allow you to reference elements later in your javascript code:
    • Give each of the <input> elements a name attribute,
    • Give each of the paragraphs/divs of text an id, and
    • Give each of the weekly and monthly amounts to be filled in the text an id, as well.
  4. When you are done with the HTML, validate to be sure your code is correct.

Task 2: Write [a little bit of] your javascript function

Define your calculateCosts() javascript function in a new file called coffee.js (the .js stands for javascript). At first, have the function simply get the inputs from the form, store in variables, and write to the console. For example, if the name of the first input is oneCupCostField:
  var oneCupCost = 
    document.querySelector("[name='oneCupCostField']").value;
    
  console.log(oneCupCost);
  
This is just a tiny bit of your javascript function, but it is always a good idea to start small. Let's get your HTML page to run your javascript function calculateCosts(), and then you can augment your function later.

Task 3: Connect your HTML page to your javascript code

  1. Add the <script> tag to the end of the body of the HTML page, to include the javascript file where you defined the calculateCosts() function. This is how your HTML page knows where to find the javascript code.
      <script src="coffee.js">
      </body>
      
  2. Add an onclick attribute to the button element, defining the event handler for clicking the button. The event handler will invoke a javascript function calculateCosts(), which we will define in coffee.js. When someone clicks on your button, then calculateCosts() will be executed. The <button> tag (in your HTML page) will now look like this:
        <button type="button" onclick="calculateCosts();"> Calculate Costs </button>
      

  3. With your javascript console open (Chrome > View > Developer > javascript Console), this is what you should see after you click the button:

Task 4: Incrementally improve your calculateCosts()

  1. Add the calculations for the weekly and monthly costs and also store these in variables (assume there are 4.3 weeks in a month and 52 weeks in a year). Write the results to the console to be sure you are correct.

    Note: there is a javascript function which can set the number of digits after the decimal point to two, so your values look like currency. It is called toFixed(). For example, if your variable is weeklyCost:

      console.log(weeklyCost.toFixed(2));
      
    should produce:

  2. Once that works, instead of writing to the console, write the results to the page in the place in the paragraph where they belong. You should use something like this (assuming that < span id = "weekly" >):
      document.querySelector("#weekly").innerHTML = 
             weeklyCost.toFixed(2);
      

  3. Now, add code so that this message always shows up near the bottom of the page "You'd better quit the habit before you go broke". At this point, we want the same message to show up everytime. Later on, we will use conditionals to make this fancier.

Task 5: Style Visibility

You should put all of your CSS in a third file, called coffee.css. Add the code necessary to your HTML file to connect that page to your coffee.css style sheet.
  1. Your CSS should include all the styling rules you use to make your page aesthetically pleasing. It should also make the calculations and feedback message paragraphs/divs hidden initially. Assuming <p id="displayCosts">:
    #displayCosts { visibility: hidden;}
     

    The message about the costs ("reasonable amount" v. "better quit") should also be initially hidden. You should now see that the calculations and message are invisible when you reload the page.

  2. In your coffee.js javascript file, add the code to your function to make the page visible when the button is clicked:
    document.querySelector("#displayCosts").style.visibility = "visible";
     

    Repeat the same process for the feedback message paragraph/div of your page.

Lab 6 - Part 2 Conditionals/feedback message

There are two places where we will use conditionals in our calculateCosts() function:
  1. We need to check and make sure that both inputs are non-zero
  2. We need to print a message based on how much money the user spends weekly on coffee

Handling 0 as a form input

What if one of the form fields has a value of zero? Then, the calculation becomes meaningless, because there is no cost to be computed. So if one of the fields is 0, our page prints a message to indicate that non-zero values must be provided.

0 inputs 0 inputs

  • Add a conditional to your javascript function to check and make sure that both inputs are not zero. If one or both of them is zero, then print the message "All fields must be non-zero." You'll need to decide what goes between the parentheses below:
       if (           ) {
         document.querySelector("#displayMessage").innerHTML = 
                    "All fields must be non-zero";
    
  • Test your page to make sure that this non-zero input part works correctly.

Whoa big spender! (Printing message based on coffee spending)

We would like to give the user different feedback messages depending on how much they spend on coffee, as shown below:

original form with results displayed original form with results displayed

  • Add to your javascript function a conditional statement to test if the user spends more than $50 a week, and set the feedback message based on this result (NOTE: this code should go BEFORE the code which makes the feedback message visible). You'll need to decide what goes inside the parentheses below:
    if (             ) {
             document.querySelector("#displayMessage").innerHTML = 
             "You'd better quit the habit before you go broke.";
       } else {
             document.querySelector("#displayMessage").innerHTML = 
             "That's a reasonable amount.";
    }
    
  • Test your code by reloading the page several times, entering values to display the different messages.

GIF File Size

Last week, we performed hand calculations to determine the file size for a GIF image. You can also write a function that computes and returns a GIF file size (something you are also asked to do on your next assignment).

In case you need a reminder, the file size (in bits) of a GIF graphic is given by the formula:

 file_size (in bits) = width * height * bit_depth + size of color table
where size of color table = (numColors) * 3 Bytes/color. The bit_depth can be obtained mathematically by the following formula:
 bit_depth = ceiling(log(numColors)/log(2))

The bit_depth must be a whole number, so if the result has a fractional part, you need to round up to the next highest whole number (that is the meaning of ceiling). The javascript Math class contains two methods which can be used to perform this calculation:

  • Math.log(), and
  • Math.ceil() (rounds up to the next highest whole number).

Remember that if you need to convert the file from bits to bytes or Kilobytes, you will need some additional calculations to make that conversion.