Fall Semester 2002


Lecture Notes Seventeen: Client-side scripting.

Take a look at this:

<html><head><title>PHP Tag Styles</title></head><body bgcolor=white>

It's <?=date("H:i, jS F")?> <p> 

<? for ($i = 0; $i < 4; $i++) {
     echo $i, ", "; 
   }
   echo "... done! <hr>"; 
 ?>

<script language="php"> 

   for ($i = 0; $i < 4; $i++) {
     echo $i, ", "; 
   }
   echo "... done! <hr>"; 
 
</script>

</body></html>
The script is here. Notice the new tags.

We briefly review the process, then present client-side scripting.

JavaScript

Lightweight interpeted programming language with rudimentary object-oriented capabilities. Developed by Brendan Eich and his team at Netscape. General-purpose core of the language embedded in Navigator and other web browsers, embellished for web programming with the addition of objects that represent the web browser window and its contents. It allows programmatic control over content of web pages, browser, and HTML forms (through event handlers, pieces of JavaScript code that are executed when a particular event occurs.

Syntactically the core JavaScript language resembles C, C++, and Java. Untyped language, though, which means that variables do not need to have a type specified. Objects in JavaScript are more like Perl's associative arrays than they are like structures in C or objects in C++ or Java. Purely interpreted language.

Simple sample JavaScript program:

<html>
<body bgcolor=white>
<script language="javascript">
document.write("<h2>Table of Factorials</h2>\n"); 
for (i = 0, fact = 1; i < 10; i++, fact *= i) {
  document.write(i + "! = " + fact); 
  document.write("\n</br>"); 
}
</script>
</body>
</html>
Script tags are used to embed JavaScript code within an HTML file. The write method is used to dynamically output HTML text that will be parsed and displayed by the web browser.

Besides allowing programmatic control over the content of web pages, JavaScript also allows programmatic control over the browser and the content of HTML forms that appear in a web page. Not only can JavaScript control the content of HTML forms, it can also control the behaviour of those forms. JavaScript can do that by defining "event handlers" for the form. The code in the event handlers will be executed when a particular event occurs, such as when the user clicks a button.

<html>
<body bgcolor=white>
<form>
<input type="button"
       value="click here!"
       onClick="alert('You clicked the button!')">
</form>
</body>
</html>
The onClick attribute shown in the simple example above is an HTML extension added by Netscape specifically for client-side JavaScript. All JavaScript event handlers are defined with HTML attributes like this one. The value of the onClick attribute is a string of JavaScript code to be executed when the user clicks a button.

The examples above highlight only the simplest features of client-side JavaScript. The real power of JavaScript on the client side is that scripts have access to a hierarchy of objects that are based on the content of the web page.

What is exciting about the language is the context in which it is embedded (the web browser). Client JavaScript is essentially a way of programming the web browser remotely.

JavaScript is not Java simplified, similarity of names purely a marketing ploy. It cannot draw graphics, do networking or multithreading (Java does all these). But unlike Java it can control the browser very well and can communicate well and make a good team with Java (with which it has a disjoint set of features). JavaScript can also control the document appearance and content. This allows you to write arbitrary HTML in a document as the document is being parsed by the browser. You can also generate documents entirely from scratch. What this amounts to is the ability to generate dynamic and conditional HTML documents, a technique that works particularly well in multiframe documents. (Indeed, in some cases, dynamic generation of frame contents allows a JavaScript program to entirely replace the use of a traditional CGI script).

Several JavaScript objects allow control over the behaviour of the browser (The Window and History objects). The Document object and the objects it contains allow programs to read and sometimes interact with portions of the document. By far the most important capability for interacting with document contents is provided by the Form object and by the element objects it can contain: the Button, Checkbox, Hidden, Password, Radio, Reset, Select, Submit allow you to read and write the values of any input element in any form in the document.

HTML forms have been traditionally used with CGI scripts, JavaScript is much more practical in such circumstances since it can transfer some of the computation to the client workstation (instead of sending the data to the server for calculations at every single step in the program, as in the calculator program from the lecture on CGI). Another common use for the ability to read user input from form elements is for verification of a form before it is submitted.

To experiment with JavaScript all you need is a browser (no network connection is necessarry).

Client-side program structure.

There are five techniques for including JavaScript code in HTML:

1. The <SCRIPT> tag. Client-side JavaScript scripts are part of an HTML file and are usually coded within <SCRIPT> and </SCRIPT> tags. Between these tags you may place any number of JavaScript statements. A single HTML document may contain more than one pair of (non-overlapping) <SCRIPT> and </SCRIPT> tags. The context that matters is the HTML page, not the script block. The <SCRIPT> tag has an optional LANGUAGE attribute that specifies the scripting languagefor the script.

Here's a simple JavaScript Program in an HTML file:

<html>
<head>
<title> Today's Date </title>
  <script language="JavaScript"> 
  // Define a function for use later on 
  function  print_todays_date() { 
    var d = new Date(); // today's date and time 
    document.write(d.toLocaleString()); 
  }
  </script> 
</head>
<body bgcolor=white>
<hr>The date and time are: <br> <b> 
  <script language="JavaScript">
  // Now call the function we defined above 
  print_todays_date(); 
  </script>
</b> <hr>
</body>
</html>
2. Including JavaScript Files. The <SCRIPT> supports an SRC attribute. The value of the attribute specifies the URL of a file of JavaScript code. It is used like this:
<html>
<head>
<title> Today's Date </title>
  <script src="date.js"></script> 
</head>
<body bgcolor=white>
<hr>The date and time are: <br> <b> 
  <script language="JavaScript">
  // Now call the function we defined above 
  print_todays_date(); 
  </script>
</b> <hr>
</body>
</html>
where the file date.js has the following contents:
// Define a function for use later on 
function  print_todays_date() { 
  var d = new Date(); // today's date and time 
  document.write(d.toLocaleString()); 
}
The program above prints the date, being essentially equivalent to the program in example 1 above.

A JavaScript file typically has a .js extension.

It is also a good idea to use the LANGUAGE attribute with the SRC atribute.

3. JavaScript and Events. Web browsers are graphical environments responding to mouse button clicks and keystrokes (input) generated by the user. In order to implement an event-driven program you must write event-handler functions that take appropriate actions in response to user's input. You must also register these event handlers with the system in some way (perhaps just by giving them standard names) so that the system can invoke them at the appropriate times.

In order to allow us to define JavaScript event handlers as part of HTML object definitions, JavaScript extends HTML by adding new attributes to various HTML tags that define objects. A common technique is to define the body of the event handler as a function between <SCRIPT> and </SCRIPT> tags and simply invoke the function from the event handler.

Here's a list of event handlers defined by client-side JavaScript objects:

Area
  • onClick()
  • onMouseOut()
  • onMouseOver()
Button
  • onBlur()
  • onClick()
  • onFocus()
Checkbox
  • onBlur()
  • onClick()
  • onFocus()
FileUpload
  • onBlur()
  • onChange()
  • onFocus()
Form
  • onReset()
  • onSubmit()
Frame
  • onLoad()
  • onUnload()
Image
  • onAbort()
  • onError()
  • onLoad()
Link
  • onClick()
  • onMouseOut()
  • onMouseOver()
Radio
  • onBlur()
  • onClick()
  • onFocus()
Reset
  • onBlur()
  • onClick()
  • onFocus()
Select
  • onBlur()
  • onChange()
  • onFocus()
Submit
  • onBlur()
  • onClick()
  • onFocus()
Text
  • onBlur()
  • onChange()
  • onFocus()
TextArea
  • onBlur()
  • onChange()
  • onFocus()
Window
  • onBlur()
  • onError()
  • onFocus()
  • onLoad()
  • onUnload()

Timer Events. There is another type of event, besides those generated through user interaction. These are events generated when specified periods of time have elapsed: they are known as timer events, or timeouts. Timeouts are important to any JavaScript program that must perform an action on some regular schedule, even when the user is not interacting with the browser. Applications of timeouts include clocks and animation. Almost threads.

Here are two examples:

// call the show_date_time() function 1 second from now
setTimeout("show_date_time();", 1000);
shows the date one second after the statement is executed, and
function animate_status_line_annoyingly() {
  // Set the Window.status property here. 
  // then arange to be called later so we can do it again!
  setTimeout("animate_status_line_annoyingly()", 1000); 
}
when invoked, starts a loop of 1-second delayed animations of the status bar.

Note these are just patterns, and we'll use them in actual examples soon.

4. JavaScript in URLs. Another way in which JavaScript code can be included on the client side is in a URL following the javascript: pseudo-protocol specifier. This special protocol type specifies that the body of the URL is arbitrary JavaScript code to be interpreted by the JavaScript interpreter.

For example:

javascript: var now = new Date(); "<h1>The time is:</h1>" + now;
or
javascript: alert("Hello World!"); 
Try both of these in the Location: box of your browser.

The javascript URL can be used anywhere you'd use a regular URL.

5. JavaScript Entities. In Navigator 3.0 and later, Javascript code may appear in one additional location in a web page. This is in a JavaScript entity within the value of an attribute of an HTML tag. Recall that an HTML entity is a sequence of characters like &lt; that represents a special character like <. A JavaScript entity is similar. It has the following syntax:

&{ JavaScript-statements };
The entity may contain any number of JavaScript statements, which must be separated from one another by semicolons. It must begin with an ampersand and an open curly bracket and end with a close curly bracket and a semicolon. Whenever an entity is encountered in HTML, it is replaced with its value. The value of a JavaScript entity is the value of the last JavaScript statement or expression within the entity, converted to a string.

In general, entities can be used anywhere within HTML code. The JavaScript entity, however, is restricted to appear only within the value of HTML attributes. These entities allow you to, in effect, write conditional HTML. Typical usages might look like these:

<body bgcolor="&{favorite_color();};">
<input type="text" name="lastname" value="&{defaults.lastname};">
Execution of scripts occurs as part of the web browser's HTML parsing process.

(So this is a sort of PHP, only on the client side).

Windows and the JavaScript Name Space

In client-side JavaScript the web browser window is represented by a Window object. The Window object is the central, most important object in JavaScript. All other HTML objects in Javascript are accessed as properties of the Window object, or as properties of those properties. This object has methods like alert() and prompt, and properties like location, status and history. There's also another property, self, that is a synonym for the window property. Thus a window can refer back to itself. A window also defines the name space of a JavaScript program (or script).

Programming with Windows

Essentially this involves using methods such as: alert(), confirm(), and prompt(); knowing how to open or close windows; working with the status line; applying various other techniques such as frame programming techniques etc.

Documents and Their Contents

Here's an example of a program using a window for debugging.

<SCRIPT>
var _console = null;

function debug(msg) 
{
    // Open a window the first time we are called, or after an existing
    // console window has been closed.
    if ((_console == null) || (_console.closed)) { 
        _console = window.open("","console","width=600,height=300,resizable");
        // Open a document in the window to display plain text.
        _console.document.open("text/plain");
    }

    _console.document.writeln(msg);
}
</SCRIPT>

<!-- Here's an example of using this script. -->
<SCRIPT>var n = 0;</SCRIPT>
<FORM>
<INPUT TYPE="button" VALUE="Push Me"
       onClick="debug('You have pushed me:\t' + ++n + ' times.');">
</FORM>
Here it is, in action.

Let's now take a look at Special Effects with Images

(Note that this involves timers).

<html><head><title>Animation Example</title></head>
<img src="http://www.cs.indiana.edu/classes/a202-dger/lectures/last/T1.gif" 
     name="animation"> <script>
images = new Array(10); 
for (var i = 0; i < 10; i++) {
  images[i] = new Image(); 
  images[i].src = 
    "http://www.cs.indiana.edu/classes/a202-dger/lectures/last/T" + 
    (i + 1) + ".gif";
} 
function animate() {
  document.animation.src = images[frame].src;
  frame = (frame + 1) % 10; 
  timeout_id = setTimeout("animate()", 250); 
}
var frame = 0; 
var timeout_id = null; 
</script>
<body bgcolor=white>
<form>
  <input type=button value="Start" 
         onClick="if (timeout_id == null) animate()"> 
  <input type=button value="Stop"
         onClick="if (timeout_id) clearTimeout(timeout_id); timeout_id=null;">
</form>
</body></html> 
Here's how this example works. (The code above should be very instructive).

Here's another simple example of JavaScript in a form.

And now a much more comprehensive example:

Forms and Form Elements

(Note: This example uses first-order functions, almost.

It's basically as in C, Scheme, Perl, and somewhat combined).

<FORM NAME="everything">  <!-- A one-of-everything HTML form... -->
 <TABLE BORDER CELLPADDING=5>   <!-- ...in a big HTML table. -->
   <TR>
     <TD>Username:<BR>[1]<INPUT TYPE=text NAME="username" SIZE=15></TD>
     <TD>Password:<BR>[2]<INPUT TYPE=password NAME="password" SIZE=15></TD>
     <TD ROWSPAN=4>Input Events[3]<BR>
       <TEXTAREA NAME="textarea" ROWS=20 COLS=28></TEXTAREA></TD>
     <TD ROWSPAN=4 ALIGN=center VALIGN=center>
       [9]<INPUT TYPE=button VALUE="Clear" NAME="clearbutton"><BR>
       [10]<INPUT TYPE=submit NAME="submitbutton" VALUE="Submit"><BR>
       [11]<INPUT TYPE=reset NAME="resetbutton" VALUE="Reset"></TD></TR>
   <TR>
     <TD COLSPAN=2>Filename: [4]<INPUT TYPE=file NAME="file" SIZE=15></TD></TR>
   <TR>
     <TD>My Computer Peripherals:<BR>
       [5]<INPUT TYPE=checkbox NAME="peripherals" VALUE="modem">28.8K Modem<BR>
       [5]<INPUT TYPE=checkbox NAME="peripherals" VALUE="printer">Printer<BR>
       [5]<INPUT TYPE=checkbox NAME="peripherals" VALUE="tape">Tape Backup</TD>
     <TD>My Web Browser:<BR>
       [6]<INPUT TYPE=radio NAME="browser" VALUE="nn">Netscape Navigator<BR>
       [6]<INPUT TYPE=radio NAME="browser" VALUE="ie">Internet Explorer<BR>
       [6]<INPUT TYPE=radio NAME="browser" VALUE="other">Other</TD></TR>
   <TR>
     <TD>My Hobbies:[7]<BR>
       <SELECT multiple NAME="hobbies" SIZE=4>
         <OPTION VALUE="programming">Hacking JavaScript
         <OPTION VALUE="surfing">Surfing the Web
         <OPTION VALUE="caffeine">Drinking Coffee
         <OPTION VALUE="annoying">Annoying my Friends
       </SELECT></TD>
     <TD align=center valign=center>My Favorite Color:<BR>[8]
       <SELECT NAME="color">
         <OPTION VALUE="red">Red        <OPTION VALUE="green">Green
         <OPTION VALUE="blue">Blue      <OPTION VALUE="white">White
         <OPTION VALUE="violet">Violet  <OPTION VALUE="peach">Peach
       </SELECT></TD></TR>
 </TABLE>
</FORM>

<DIV ALIGN=center>        <!-- Another table--the key to the one above. -->
  <TABLE BORDER=4 BGCOLOR=pink CELLSPACING=1 CELLPADDING=4>
    <TR>
      <TD ALIGN=center><B>Form Elements</B></TD>
      <TD>[1] Text</TD>  <TD>[2] Password</TD>  <TD>[3] Textarea</TD>
      <TD>[4] FileUpload</TD> <TD>[5] Checkbox</TD></TR>
    <TR>
      <TD>[6] Radio</TD>  <TD>[7] Select (list)</TD>
      <TD>[8] Select (menu)</TD>  <TD>[9] Button</TD>
      <TD>[10] Submit</TD>  <TD>[11] Reset</TD></TR>
  </TABLE>
</DIV>

<SCRIPT LANGUAGE="JavaScript1.1">
// This generic function appends details of an event to the big Textarea
// element in the form above. It will be called from various event handlers.
function report(element, event) 
{
    var t = element.form.textarea;
    var elmtname = element.name;
    if ((element.type == "select-one") || (element.type == "select-multiple")){
        value = " ";
        for(var i = 0; i < element.options.length; i++)
            if (element.options[i].selected) 
                value += element.options[i].value + " ";
    }
    else if (element.type == "textarea") value = "...";
    else value = element.value;
    var msg = event + ": " + elmtname + ' (' + value + ')\n';
    t.value = t.value + msg;
}

// This function adds a bunch of event handlers to every element in a form.
// It doesn't bother checking to see if the element supports the event handler,
// it just adds them all. Note that the event handlers call report() above.
function addhandlers(f)
{
    var click_handler = new Function("report(this, 'Click')");
    var change_handler = new Function("report(this, 'Change')");
    var focus_handler = new Function("report(this, 'Focus')");
    var blur_handler = new Function("report(this, 'Blur')");
    var select_handler = new Function("report(this, 'Select')");
        
    for(var i = 0; i < f.elements.length; i++) {
        var e = f.elements[i];
        e.onclick = click_handler;
        e.onchange = change_handler;
        e.onfocus = focus_handler;
        e.onblur = blur_handler;
        e.onselect = select_handler;
    }

    // Special case handlers for the buttons:
    f.clearbutton.onclick = 
        new Function("this.form.textarea.value=''; report(this, 'Click');");
    f.submitbutton.onclick = 
        new Function("report(this, 'Click'); return false");
    f.resetbutton.onclick = 
        new Function("this.form.reset(); report(this, 'Click'); return false");
}
// Activate our form by adding all possible event handlers!
addhandlers(document.everything);
</SCRIPT>

Here's a working version of this example (useful for building interfaces).

A few more things to look at:

  1. Here's The Big Wave (by Duke).

  2. Here's a very long (somewhat dated) document covering JavaScript.

  3. Here's another example you may want to look at.

Shortly we will talk about

  1. Basic Object-Oriented JavaScript.

  2. Building a simple Shopping Cart with JavaScript.

Let's do the Object-Oriented JavaScript first.

Let's create a few JavaScript objects and put them to use:

<html>
  <head><title>Testing</title></head>
  <body bgcolor=white>
  <script language="Javascript">

    var account = new Object(); 

    account.balance = 20; 

    function getBalance() {
      return this.balance; 
    }

    account.getBalance = getBalance; 

    function deposit(amount) {
      this.balance += amount; 
    }

    account.deposit = deposit; 

    document.write(account.getBalance() + "<br>"); 

    account.deposit(30); 

    document.write(account.getBalance()); 
    </script>
  </body>
</html>

So we see that objects are simply hashtables.

Also, that functions are first-class entities in Javascript.

Let's look now at constructor functions.

<html>
  <head><title>Testing</title></head>
  <body bgcolor=white>
    <script language="Javascript">

      function Account(initialBalance) {

        this.balance = initialBalance; 

        this.deposit = 
                function deposit(amount) {
                  this.balance += amount; 
                }

        this.getBalance = 
                function getBalance() { 
                  return this.balance; 
                }
      }

      var account = new Account(20); 

      account.deposit(300);

      document.write(account.balance + "<br>"); 

      document.write(account.getBalance()); // [1] 

    </script>
  </body>
</html>
What do you think would happen if we changed the line marked // [1] to
document.write(account.getBalance);
Note that the parens are missing.

Well, functions are first-class (that is, they can also be data).

Here are a few more examples:

<html>
  <head><title>Testing</title></head>
  <body bgcolor=white>
    <script language="Javascript">

      function square(x) { return x * x; }

      a = square(4); 

      b = square; 

      c = b(5); 

      document.write(a + "<hr>" + b + "<hr>" + c); 

    </script>
  </body>
</html>
Let's look now at objects as associative arrays (or hashes in Perl).

object.property
and
object["property"]
are one and the same thing.

Here's where the second approach would make a difference:

<html>
  <head><title>Testing</title></head>
  <body bgcolor=white>
    <script language="Javascript">

        var one = new Object(); 

        for (i = 0; i < 4; i++) 
          one["prop" + i] = "This is property " + i; 

      document.write(one.prop0 + "<br>"); 
      document.write(one.prop1 + "<br>"); 
      document.write(one.prop2 + "<br>"); 
      document.write(one.prop3 + "<br>"); 

    </script>
  </body>
</html>
How do we get the properties out in a more uniform manner?

You need to know about the for/in construct.

<html>
  <head><title>Testing</title></head>
  <body bgcolor=white>
    <script language="Javascript">

      var one = new Object(); 

      for (i = 0; i < 4; i++) 
        one["prop" + i] = "This is property " + i; 

      // document.write(one.prop0 + "<br>"); 
      // document.write(one.prop1 + "<br>"); 
      // document.write(one.prop2 + "<br>"); 
      // document.write(one.prop3 + "<br>"); 

      for (prop in one) {
        document.write(prop +": " + one[prop] + "<br>"); 
      }

    </script>
  </body>
</html>
Now we can put together these last two examples in a more complex one.

<html>
  <head><title>Testing</title></head>
  <body bgcolor=white>
    <script language="Javascript">

      // first define some simple functions
  
      function add(x, y) { return x + y; }
      function subtract(x, y) { return x - y; }
      function multiply(x, y) { return x * y; }
      function divide(x, y) { return x / y; }

      // this function takes three arguments
      //      a function (operator)
      //      and two operands (operand1, operand2) 

      function operate(operator, operand1, operand2) {
        return operator(operand1, operand2); 
      }

      var result = operate(add, 3, 4); 

      document.write(result + "<br>"); 

      document.write(operate(add, operate(subtract, 3, 4), 5) + "<br>"); 

    </script>
  </body>
</html>
Next lecture offers a slightly more involved example. Which is a bit like this:
<html>
  <head><title>Testing</title></head>
  <body bgcolor=white>
    <script language="Javascript">

      var value = 3; 

      function add(val, arg) { return val + arg; }

      function subtract(val, arg) { return val - arg; } 

      function change(n) {
        if (n % 2 == 0) {
          eval("value = add(value, " + n + ")"); 
        } else {
          eval("value = subtract(value, " + n + ")"); 
        }
      }
 
      change(2); 

      document.write(value + "<br>"); 

      change(3); 

      document.write(value + "<br>"); 

   </script>
</body>
</html>
Now let's develop a calculator that allow us to calculate our grades during the semester.

Here's the calculator. And here's the code:

<html>
  <head><title>A348/A548 Grade Calculator</title></head>
  <body bgcolor=white>

<form name="grades"> <table> 

<tr><td> ASSIGNMENTS </td> 

<td align=center> One </td> 
<td align=center> Two </td> 
<td align=center> Three </td> 
<td align=center> Four </td> 
<td align=center> Five </td> 
<td align=center> Six </td> 

</tr> 

<tr> <td> </td> 

<td> <input type="text" name="a1" size=4 onChange="calculate()"> </td>

<td> <input type="text" name="a2" size=4 onChange="calculate()"> </td>

<td> <input type="text" name="a3" size=4 onChange="calculate()"> </td>

<td> <input type="text" name="a4" size=4 onChange="calculate()"> </td>

<td> <input type="text" name="a5" size=4 onChange="calculate()"> </td>

<td> <input type="text" name="a6" size=4 onChange="calculate()"> </td>

</tr> 


<tr><td> GROUP PROJECT </td> <td> </td> <td> <input type="text" name="gp" size=4
 onChange="calculate()"
> </td> </tr> 
<tr><td> MIDTERM EXAM  </td> <td> </td> <td> <input type="text" name="me" size=4
 onChange="calculate()"
> </td> </tr> 
<tr><td> FINAL EXAM    </td> <td> </td> <td> <input type="text" name="fe" size=4
 onChange="calculate()"
> </td> </tr> 

<tr><td> LAB ASSIGNMENTS </td> 

<td align=center> One </td> 
<td align=center> Two </td> 
<td align=center> Three </td> 
<td align=center> Four </td> 
<td align=center> Five </td> 
<td align=center> Six </td> 

</tr> 

<tr> <td> </td> 

<td> <input type="text" name="l1" size=4
 onChange="calculate()"
> </td>

<td> <input type="text" name="l2" size=4
 onChange="calculate()"
> </td>

<td> <input type="text" name="l3" size=4
 onChange="calculate()"
> </td>

<td> <input type="text" name="l4" size=4
 onChange="calculate()"
> </td>

<td> <input type="text" name="l5" size=4
 onChange="calculate()"
> </td>

<td> <input type="text" name="l6" size=4
 onChange="calculate()"
> </td>

</tr> 

<tr><td>  </td> 

<td align=center> Seven </td> 
<td align=center> Eight </td> 
<td align=center> Nine </td> 
<td align=center> Ten </td> 
<td align=center> Eleven </td> 
<td align=center> Twelve </td> 

</tr> 

<tr> <td> </td> 

<td> <input type="text" name="l7" size=4
 onChange="calculate()"
> </td>

<td> <input type="text" name="l8" size=4
 onChange="calculate()"
> </td>

<td> <input type="text" name="l9" size=4
 onChange="calculate()"
> </td>

<td> <input type="text" name="l10" size=4
 onChange="calculate()"
> </td>

<td> <input type="text" name="l11" size=4
 onChange="calculate()"
> </td>

<td> <input type="text" name="l12" size=4
 onChange="calculate()"
> </td>

</tr> 

<tr> <td colspan=3> Press <input type="reset" name="RESET"> to clear the form. </td> 

<td colspan=4> Your calculated final grade is: <input type="text" name="total" size=6> </td> 

</tr>


</table>

<input type="hidden" name="hwk" value="0.30"> 
<input type="hidden" name="prj" value="0.20"> 
<input type="hidden" name="mid" value="0.15"> 
<input type="hidden" name="fin" value="0.15"> 
<input type="hidden" name="lab" value="0.20"> 

<script language="javascript"> 

  function calculate() {

    var hwk = 0, lab = 0, prj = 0, mid = 0, fin = 0, 

        count = 0, weight = 0.0, total = 0.0; 

    for (var i = 1; i <= 6; i++) {
      var num = document.grades["a" + i].value; 
      if (num == "" || isNaN(num)) { 
        document.grades["a" + i].value = "";     
      } else {
        hwk  = parseInt(hwk) + parseInt(num); 
        count += 1; 
      }
    }

    if (count > 0) { 
      weight = parseFloat(document.grades.hwk.value); 
      hwk = hwk/count * document.grades.hwk.value; 
    } 

    var report = "Homework: " + hwk + "\n"; 

    num = document.grades.gp.value; 
 
    if (num == "" || isNaN(num)) { 
      document.grades.gp.value = ""; 
    } else { 
      weight += parseFloat(document.grades.prj.value); 
      prj = parseInt(num) * document.grades.prj.value; 
    } 

    report += "Group Project: " + prj + "\n"; 

    num = document.grades.me.value; 

    if (num == "" || isNaN(num)) { 
      document.grades.me.value = ""; 
    } else { 
      weight += parseFloat(document.grades.mid.value); 
      mid = parseInt(num) * document.grades.mid.value; 
    } 

    report += "Midterm Exam: " + mid + "\n"; 

    num = document.grades.fe.value; 

    if (num == "" || isNaN(num)) { 
      document.grades.fe.value = ""; 
    } else { 
      weight += parseFloat(document.grades.fin.value); 
      fin = parseInt(num) * document.grades.fin.value; 
    } 

    report += "Final Exam: " + fin + "\n"; 

    count = 0; 

    for (var i = 1; i <= 12; i++) {
      var num = document.grades["l" + i].value; 
      if (num == "" || isNaN(num)) { 
        document.grades["l" + i].value = "";     
      } else {
        lab = parseInt(lab) + parseInt(num); 
        count += 1; 
      }
    }

    if (count > 0) { 
      weight += parseFloat(document.grades.lab.value); 
      lab = lab/count * document.grades.lab.value; 
    } 

    report += "Lab Assignments: " + lab + "\n"; 

    report += "Weight: " + weight + "\n"; 

    total = (fin + mid + hwk + lab + prj) / weight; 

    report += "Final Grade: " + total + "\n"; 

    document.grades.total.value = Math.round(total); 

    // alert(report); 
  
  }
</script>


<table width=100%>

<tr> <th bgcolor=lightgrey colspan=13> <font face="Verdana,Arial,Helvetica">Percent</font> </th> </tr> 

<tr> <td align=center>  0-54 </td> 
<td align=center bgcolor=lightgrey> 55-59 </td> 
<td align=center bgcolor=lightgrey> 60-65 </td> 
<td align=center bgcolor=lightgrey> 66-67 </td> 
<td align=center> 68-69 </td> 
<td align=center> 70-75 </td> 
<td align=center> 76-77 </td> 
<td align=center bgcolor=lightgrey> 78-79 </td> 
<td align=center bgcolor=lightgrey> 80-85 </td> 
<td align=center bgcolor=lightgrey> 86-87 </td> 
<td align=center> 88-89 </td> 
<td align=center> 90-95 </td> 
<td align=center> 96-100 </td> 
</tr> 

<tr> <td align=center align=left> F </td> 
<td align=center bgcolor=lightgrey align=left> D- </td> 
<td align=center bgcolor=lightgrey align=left> D </td> 
<td align=center bgcolor=lightgrey align=left> D+ </td> 
<td align=center align=left> C- </td> 
<td align=center align=left> C </td> 
<td align=center align=left> C+ </td> 
<td align=center bgcolor=lightgrey align=left> B- </td> 
<td align=center bgcolor=lightgrey align=left> B </td> 
<td align=center bgcolor=lightgrey align=left> B+ </td> 
<td align=center align=left> A- </td> 
<td align=center align=left> A </td> 
<td align=center align=left> A+ </td> 
</tr> 

<tr> <th bgcolor=lightgrey colspan=13> <font face="Verdana,Arial,Helvetica">Grade</font> </th> </tr> 

</table>

</form>

  </body>
</html>
Hope you find this useful.


Last updated: Oct 18, 2002 by Adrian German for A348/A548