JavaScript Lesson 4

In this lesson we will look at decision making, looping and opening a new browser window.

IF Statements

Using the IF statement, we can decide what to do if a condition is true.  The IF statement is followed by a condition and the actions to carry out if the condition is true.  You define where the TRUE statements start and stop by containing, or encapsulating, them in {brackets}.

if(test condition)

{

doThis ;

}

else

{

doThat ;

}

To be able to use the IF statement you need to know how to use comparison and logical operators.

Comparison Operators

Comparison operators are like logical operators in that they return Boolean values.  In other words they are either TRUE or FALSE.  Comparison operators are used to compare the value of the operands for equality as well as a number of other conditions.

Operator

Description

= =

Returns true if the operands are equal

!=

Returns true if the operands are not equal

>

Returns true if the left operand is greater than the right operand

<

Returns true if the left operand is less than the right operand

>=

Returns true if the left operand is greater than or equal to the right operand

<=

Returns true if the left operand is less than or equal to the right operand

For example, if x is equal to 10, and y is equal to 20, then the expression

(x > y)             returns false.

(x < y)             returns true

(x == y)           returns false.

(x != y)            returns true

Comparison operators can be used to compare numbers as well as strings; for instance:

"the" != "he"    returns true.

4 == "4"          returns true.

Logical Operators

Logical operators include both binary and unary operators. They take Boolean values as operands and return Boolean values.

Operator

Description

&&

Logical "and"—returns true when both operands are true; otherwise it returns false.

||

Logical "or"—returns true if either operand is true. It only returns false when both operands are false.

!

Logical "not"—returns true if the operand is false and false if the operand is true. This is a unary operator and precedes the operand.

false && anything          is always false.

true || anything              is always true.

For example, if x equals 10 and y equals 20, then the expression

(x > y) && (x < y)

would immediately evaluate to false once the first part of the expression (x > y) is evaluated to false. Likewise,

(y > x) || (x > y)

is evaluated to true simply because the first part of the expression (y > x) is true. The logical "NOT" operator (!) takes a single operator such as:

(!Validentry)               So if Validentry was true, the result would be false (reversed)

Condition Expression

Conditional expressions are like a short IF statement, because a conditional expression can evaluate to one of two different values based on a condition. The structure of a conditional expression is:

(condition) ? val1 : val2

The way a conditional expression works is that the condition, based on the result, evaluates to val1 (true condition) or val2 (false condition).  For example the expression

(day = = "Saturday") ? "Weekend!" : "Not Saturday!"

evaluates to "Weekend!" when day is "Saturday". Otherwise the expression evaluates to "Not Saturday!".

Operator Precedence

Operator precedence is the set of rules that determine the order in which compound expressions are evaluated. The operators you have learned are evaluated in the following order (from lowest precedence to highest):

Assignment operators        (= += -= *= /= %=)

Conditional                        (?:)

Logical OR                        (||)

Logical AND                      (&&)

Equality                            (== !=)

Relational                         (< <= > >=)

Addition/subtraction           (+ -)

Multiply/divide/modulus      (* / %)

Parentheses                     ( ( ) )

Based on these rules, the expression

5 + 3 * 2          evaluates to     5 + 6    which evaluates to 11.

The rules of operator precedence can be over-ridden by the use of parentheses. Expressions in parentheses evaluate before those outside the parentheses, so that the expression

(5 + 3) * 2       would evaluate to 16, instead of 11 without the parentheses.

Time to put some of this theory into practice!

Testing a User's Response

In this example, you will pose a test question to the user and based on the answer, display a different result for the user in the form of one of two different GIF images.  The decision will be made using a conditional statement.

You may want to download the images if you haven't already done so...

The question will be presented in a prompt dialog box and the result displayed by outputting to the client window.

Create the code below and save as If1.htm

<HTML>

<HEAD><TITLE>Testing the user</TITLE>

<SCRIPT LANGUAGE="JavaScript">

// DEFINE VARIABLES FOR REST OF SCRIPT

var question="What is 10+10?";

var answer=20;

var correct='<IMG SRC="correct.gif">';

var incorrect='<IMG SRC="incorrect.gif">';

// ASK THE QUESTION

var response = prompt(question,"0");

// CHECK THE ANSWER

var output = (response = = answer) ? correct : incorrect;

</SCRIPT>

</HEAD>

<BODY>

<SCRIPT LANGUAGE="JavaScript">

// OUTPUT RESULT

document.write(output);

</SCRIPT>

</BODY>

</HTML>

Generally I prefer to use a straight IF statement so we’ll leave conditional operators there.

Using the IF statement.

Create the code below and save as If2.htm

<HTML>

<HEAD><TITLE>So friendly</TITLE>

<SCRIPT LANGUAGE="JavaScript">

function askuser(){

            var statement="Answer yes or no"

            var answer=prompt("Do you like sports?", “”)

            if (answer == "yes")  

            {

                        statement="I like sports too!"

            }

            if(answer == "no")

            {

                        statement="I hate sports too!"

            }

            alert(statement)

 }

</SCRIPT>

</HEAD>

<BODY>

<H1>Activities</H1>

<FORM>

            <INPUT TYPE="button" VALUE="click me" 

            onClick="askuser()">

</FORM>

</BODY>

</HTML>

Run the script, entering different responses to see if the IF section of code is changing the variable ‘statement’.

Activity:

Rewrite this program so that it asks the user if he/she is a male or female. If the user types "male", make the background blue.  If the user types "female", make the background pink.

Remember, JavaScript is case sensitive, so be careful to the case in the condition statement. For example when using the condition:

if (answer = = "male")

If you type Male or MALE, the condition will be false!  There is a .toUpperCase() method that can be used to overcome this

Guess a number

This IF example includes a random number, two functions, and introduces the ELSE.  If/Else allows the program to decide what to do both when the condition is true, and when the condition is false, thus increasing your control of your program.

In order to generate a seemingly random number, we will create a date object and get the current seconds of the clock.  We will do this with the getSeconds() method.   Also we will need to have generated a random number when the page loads, so the onLoad event could be used.

Create the code below and save it as If3.htm

<HTML>

<HEAD>

<SCRIPT LANGUAGE="JavaScript">

function rand(){

            var now=new Date() ;

            num=(now.getSeconds())%10 ;

            num=num+1 ;

 }

function guessnum(){

var guess=prompt("Your guess?", "") ;

            if (guess = = num)       // note the use of 2 equal signs

              {

                        alert("YOU GUESSED IT!!") ;

                        rand() ;

              }

            else

                        alert("No.  Try again.")

 }

</SCRIPT>

</HEAD>

<BODY onLoad="rand()">

<H2>I'm thinking of a number from 1 to 10</H2>

<FORM NAME="myform">

            <INPUT TYPE="button" VALUE="Guess" NAME="b1" ID="b1"

            onClick="guessnum()">

</FORM>

</BODY>

</HTML>

Picking it to pieces we have

<BODY onLoad="rand()">

When the page loads, the randomising function rand() is triggered by the onLoad event in the BODY. This way a random number has been chosen before the button is clicked.  If it weren’t done this way the number would be a new random number every time you clicked the button rather than a set number while you guess.

function rand() {

var now=new Date()

num=(now.getSeconds())%10

num=num+1

 }

The function pulls a pseudo-random number between 0 and 9 from the time and assigns it to num. The program then adds 1 to num, to make the random number between 1 and 10.   The % is the modulus operator (remainder of a division).  The %10 tells JavaScript that the random number will be chosen from numbers between 0 and 9.  The getSeconds() method grabs the current seconds from the internal clock.  As it is working from the clock, it is not truly random.

function guessnum() {

            guess=prompt("Your guess?", "") ;

            if (guess == num)  {

                        alert("YOU GUESSED IT!!") ;

                        rand() ;

              }

            else

                        alert("No.  Try again.")

 }

There is already a number in the browser's memory from the first rand() function call of onLoad.  All this guessnum() function does is allow you to take pot shots until you get the number right. Consider what happens:

<FORM NAME="myform">

            <INPUT TYPE="button" VALUE="Guess" NAME="b1" ID="b1"

            onClick="guessnum()">

</FORM>

This should look familiar by now.  The function is triggered when the user clicks on the button.

Nested If Statements

If there are a number of decisions to be made, you can nest the if statements.  Nested if statements are relatively easy to write, but you need to be sure of the logic behind what is happening.

An example of a nested if statement could look similar to this.

if (a = = 10)

            dothis

else

{

            if (b = = 10)

                        dothat

            else

            {

                        if (c = = 10)

                        {

                                    doSomethingElse

                        }

                        else

                        {

                                    doThisIfAllElseFails

                        }

            }

}

Alternatively you might have:

if (a = = 10){

            if (b = = 10){

                        if (c = = 10){

                                    dothis

                        }

                        else      {

                                    dothat

                        }

            }         

}

Switch Statement

An alternative to using nested IF statements, is to use a switch statement.  A switch statement allows a program to evaluate an expression and attempt to match the expression's value to a case label. If a match is found, the program executes the associated statement(s).

A switch statement looks as follows:

switch (expression)

{

   case label1 :

               statement;
               break;

   case label2 :

               statement;
               break;

  ...

   default : statement;
}

The program first looks for a label matching the value of expression and then executes the associated statement.  If no matching label is found, the program looks for the optional default statement and, if found, executes the associated statements.  If no default statement is found, the program continues execution at the statement following the end of switch.

The optional break statement associated with each case label ensures that the program breaks out of switch once the matched statement is executed and continues execution at the statement following switch.  If break is omitted, the program continues execution at the next statement in the switch statement.

Example

In the following example, input_value is a variable used to store a string of text from the user.  If the input_value is equivalent to "Bananas", the program matches the value with case "Bananas" and executes the associated document.write() statement. When break is encountered, the program terminates switch and executes the statement following switch.  If break were omitted, the statement for case "Cherries" would also be executed.

switch (input_value)

{

case "Oranges" :     document.write("Oranges are $1.59 a kilogram.<BR>");

break;

case "Apples" :       document.write("Apples are $1.32 a kilogram.<BR>");

          break;

case "Bananas" :    document.write("Bananas are $2.48 a kilogram.<BR>");

          break;

case "Cherries" :     document.write("Cherries are $8.00 a kilogram.<BR>");

          break;

default :           document.write("Sorry, we are out of " + input_value + ".<BR>");

}

Create the following code and test it out

<HTML>

<HEAD><TITLE>Switching</TITLE></HEAD>

<BODY>

<SCRIPT >    

            var num = prompt("Enter a number between 1 and 5", "") * 1; 

            switch(num)

            {

                        case 1:

                                    document.fgColor = "#FF0000";

                                    document.write("One");

                                    break;

                        case 2:

                                    document.fgColor = "#00FF00";

                                    document.write("Two");

                                    break;

                        case 3:

                                    document.fgColor = "#0000FF";

                                    document.write("Three");

                                    break;

                        case 4:

                                    document.fgColor = "#0FF0FF";

                                    document.write("Four");

                                    break;

                        case 5:

                                    document.fgColor = "#FF00FF";

                                    document.write("Five");

                                    break;

                        default:

                                    document.write("Dummy - number is between 1 and 5");

            } // end switch statement

</SCRIPT>

</BODY>

</HTML>

Using loops

All programming languages have a branching (selection) control structure. The most used branching control structure in JavaScript is IF, which we’ve just looked at.  All programming languages also have looping techniques. JavaScript has two: While loops and For loops.

In general, you use for loops when you know how many times you want to perform a loop.  Use while loops when you are not sure how many times you want to perform a loop.

The For Loop

The structure of a for loop is:

            for ( counter = startvalue ; test condition  ; increment counter)

Create the following and save as For1.htm

<HTML>

<HEAD>

            <TITLE>Getting Loopy</TITLE>

</HEAD>

<BODY>

<H2>We'll now count from one to ten: </H2>

<SCRIPT LANGUAGE="JavaScript">

            for ( i = 1 ; i <= 10 ; i = i + 1 )

            {

                        document.write(i + "<BR>");

            }

</SCRIPT>

That was exciting.  Wasn’t it?

</BODY>

</HTML>

Picking it to pieces

for ( i=1 ; i<=10 ; i=i+1 )

{

            document.write(i + "<BR>");

}

Let's look at the syntax of a for statement, for(i=1; i<=10; i=i+1). There are three parts. Notice semicolons separate them all.

i=1 sets the starting value of the variable used to control the loop. In this case i is set to 1, but it could be set to 10 or 100. Think of it as simply a starting point for the loop to occur.

i <=10 is the condition controlling the number of times the loop will be repeated.  In this example, the loop will be repeated while i is less-than or equal to 10.  We started with one, and we'll count to ten.  As long as the answer to the test condition is true, it will carry out whatever you want.

i=i+1 defines the increment value. In this case, the program will add 1 to i at the bottom of the loop. The program might also add 2 or 3. We just want it to add one.  When adding incrementing i we could use i++ instead.  I++ is called a post increment.

Finally the document.write() statement prints the number.  Notice the <BR> in the document.write statement.  This JavaScript will be iterated, or looped, ten times. Thus it will produce the numbers one through ten. We could have it count to a million just as easily as ten, but that would take up too much Web page space.  You can try it if you’re game…

Modify the code above so that the text “This is loop number: loopcounter.” appears 1000 times and is incremented by 2 each loop.

While Loops

Normally you use WHILE loops when you are not sure how many times you want to perform a loop, such as reading a set of records from a database - though that would be an unusual task for JavaScript.  But in this sample we will set a limit for the sake of simplicity.  This sample shows you how to use variables to count iterations in a loop.

Create the code below and save as while.htm

<HTML>

<HEAD>

<TITLE>More Loopy</TITLE>

</HEAD>

<BODY>

<H2>Well this is what I have to say</H2>

<SCRIPT LANGUAGE="JavaScript">

            var loops = 3;

            var counter = 1;

            while (counter <= loops)

            {

                        document.write("Going ");

                        counter = counter + 1;

            }

            document.write("GONE")

</SCRIPT>

</BODY>

</HTML>

It should seem simpler than the FOR statement because there is only the test condition (counter <= loops) in the initial structure of the while statement.  However you need have a variable predefined as in the case of the loops=3. 

If, for example, you are processing an unknown number of objects in a list you will often want to keep a count of the number of objects that have been processed.  The

counter = counter+1 statement does just that.

Note, the counter variable can also be incremented by writing counter++ or ++counter

At some point you need to create the trigger that will stop the loop mechanism.  Otherwise the script will just keep on going until the computer blows up.

Let’s create an example of a script that will fill out a table for us.  One that can also be used to calculate the total of items.  As in the case of the Grog.htm file you created in the last lesson. This example will be reasonably tricky in what it does, for the amount of code involved.

Create the file below and save as Grogshop.htm

<HTML>

<HEAD>

<TITLE>Old Winery Sales</TITLE>

<SCRIPT LANGUAGE="JavaScript">

  <!--- Hide script from old browsers

ItemArray = new Array();

PriceArray = new Array();

ItemArray[0] = "Ruff Red";                            PriceArray[0] = "12.50";       

ItemArray[1] = "Whimpy White";                   PriceArray[1] = "8.50";

ItemArray[2] = "Chunder Champas";              PriceArray[2] = "1.75";

ItemArray[3] = "Burley Beer";                        PriceArray[3] = "22.40";

ItemArray[4] = "Warm Cooler";                      PriceArray[4] = "2.50";

ItemArray[5] = "John Beam";                         PriceArray[5] = "32.10";

ItemArray[6] = "Rotten Ruskie";                     PriceArray[6] = "17.50";

ItemArray[7] = "Superb Scotch";                    PriceArray[7] = "50.95";

var MaxItems = 7;       // 8 items - counting from 0

function compute(frm)   {

            var Total = 0;

            var i = 0;

            var currentCalculation = 0;

            while (i <= MaxItems)

            {

                        currentCalculation =  PriceArray[i] * frm.elements[i].value;

                        Total += currentCalculation;

                        i = i+1;

            }

            frm.result.value = Total;

  }

// end hiding from old browsers -->

</SCRIPT>

</HEAD>

<BODY BGCOLOR="moccasin" TEXT="#000000" LINK="#0000ff" VLINK="#800080" ALINK="#ff0000">

<CENTER><H2>Welcome to Greg's old wine sales</H2></CENTER>

<FORM NAME="order">

<TABLE BORDER=0 WIDTH=80%>

<TR>

  <TD WIDTH=25%>

            <B>The Grog you want</B>

  </TD>

  <TD WIDTH=25% ALIGN=RIGHT >

            <B> Price per bottle or case </B>

  </TD>

  <TD WIDTH=30% ALIGN=RIGHT >

            <B>The number you want to buy</B>

  </TD>

</TR>

<SCRIPT LANGUAGE="JavaScript">

                        // write all product details in one loop

for (i = 0; i <= MaxItems; i++)

{                      // this next command must go on 1 line – not as shown here

            document.write("<TR><TD>" + ItemArray[i] + " </TD>

                        <TD ALIGN=RIGHT >$" + PriceArray[i] + " </TD>

                        <TD ALIGN=RIGHT> <INPUT TYPE=text Value=0 SIZE=2

                        MAXLENGTH=2></TD></TR>");

}

</SCRIPT>

<TR>

  <TD colspan=2>

            <FONT SIZE=+2>You will need to spend:

  </TD>

  <TD ALIGN=RIGHT >

            <INPUT TYPE="text" NAME="result" ID="result" SIZE=10 ></FONT>

  </TD>

</TR>

<TR>

  <TD colspan=3>

            <INPUT TYPE="button" VALUE="Calculate"

            onClick="compute(this.form)">

            <INPUT TYPE="reset" VALUE="Clear"

            onMouseOver="window.status='Clears the form' "

            onMouseOut="window.status='The grog shop' ">

  </TD>

</TR>

</TABLE>

</FORM>

</BODY>

</HTML>

When you run this file, you should see that, in the long run, using a loop becomes simpler and far less wordy.

Also you may notice the occasional strange set of decimal places appear, such as 197.45000000000002 in the results input box.  Using text, eg “12.50”, can cause this.  While JavaScript is loosely typed, it is not without its faults.

There are a number of ways to over come this problem.  The rounding method associated with the Math object might do the job.  Try editing the file in the calculation of each item.

            currentCalculation = Math.round((PriceArray[i] * f.elements[i].value) * 100)/100

The above should round the result of the calculation to 2 decimal places. 

Now I have used both looping structures in this example.  The first is while

            while (i <= MaxItems)

            {

                        currentCalculation = PriceArray[i] * frm.elements[i].value;

                        Total += currentCalculation;

                        i = i+1;

            }

            frm.result.value = Total;

This is a typical structure for a while loop.  As long as there are more items to process, the loop will continue to take the value that is stored in the PriceArray[i] (whatever i is at the time) and multiply it by the whatever the value is at the i th element of the for.  So if i is 5 then the sixth form element and array subscript are extracted and used.

            i = i+1;

This incrementing line is very important.  Unlike the for loop, if this was omitted the loop would never end.  The value of i is tested the next time around.  The official method of incrementing by 1 is i++

            Total += currentCalculation;

This line gives our running total.  It takes the value of Total and adds the value of currentCalculation.

for (i = 0; i <= MaxItems; i++)

{

            document.write("<TR><TD>" + ItemArray[i] + "</TD>

                        <TD ALIGN=RIGHT>$" + PriceArray[i] + " </TD>

                        <TD ALIGN=RIGHT> <INPUT TYPE=text Value=0 SIZE=2

                        MAXLENGTH=2> </TD></TR>");

}

Without using this loop, our HTML code would be very lengthy indeed.  For every time that the variable i is less-than or equal to the MaxItems, the loop will:

The real benefit of using loops will be obvious if you needed to write the code 100 or more times.  This is neat and simple.

Opening and Closing Windows

A window is created automatically when you launch the browser; you can open another window by choosing New… Window, from the File menu.  You can close a window by choosing either Close or Exit from the File menu.  You can also open and close windows with JavaScript.

Opening a Window

You can create a window with the open method. The following statement creates a window called msgWindow that displays the contents of the file sesame.html:

msgWindow=window.open("sesame.html")

The following statement creates a window called homeWindow that displays the TAFE home page:

homeWindow=window.open("http://www.tafe.nsw.edu.au”)

Windows can have two names. The following statement creates a window with two names. The first name, msgWindow, refers to the window object. This object has information on the window's properties, methods, and containership. When you create the window, you can also supply a second name, in this case displayWindow, to refer to that window as the target of a form submit or hypertext link.

msgWindow=window.open("sesame.html","displayWindow")

A window name is not required when you create a window. But the window must have a name if you want to refer to it from another window.

When you open a window, you can specify attributes such as the window's height and width and whether the window contains a toolbar, location field, or scrollbars.  The following statement creates a window without a toolbar but with scrollbars:

msgWindow=window.open("sesame.html", "displayWindow", “toolbar=no, scrollbars=yes")

To write to another window, you just prefix the window’s object name.  To write hello in an opened window we named msgWindow we could write.

msgWindow.document.write(“Hello”)

Closing a Window

You can close a window with the close method. Each of the following statements closes the current window:

window.close()
self.close()
close()

Do not use the third form, close(), in an event handler. Because of how JavaScript figures out what object a method call refers to, inside an event handler it will get the wrong object.

The following statement closes a window called msgWindow:

msgWindow.close()

Example:

Let’s create an example using the Grogshop.htm file we created earlier.

At the end of the Table in your Grogshop.htm, add another button, next to the existing ones, that will send the final total to a new window

            <INPUT TYPE="button" VALUE="Send"

            onClick="sendData(this.form)">

We also need a function sendData() that will carry out this onClick event.  Back up within the Script tag create the following function.

function sendData(frm) {

            OrderWindow=window.open("", "", "height=300,width=300");

            OrderWindow.document.write(”Hello”);

}

Save as Grogshop2.htm and try it out.

To send more information to the opened window just keep adding document.write statements prefixed with the window name.  Try it.

OrderWindow.document.write(“There <BR>”);

OrderWindow.document.write(“<FONT color=blue>A new line of junk </FONT>”);

Now modify the code to send more useful information, such as the total cost of this purchase.

An alternative approach to the sending of sending lots of small pieces of data is to create a String object and simply keep adding the text that will be sent to the new window.  That way there is only one window.document.write() statement.  If you have a function that keeps adding text to the string object or variable, now you only need say.

            OrderWindow.document.write(addtoStringObject(frm))

Example function

function addtoStringObject(frm)

{

OrderStr = new  String("<HTML><TITLE>Order Details </TITLE>”);

OrderStr += “<BODY BGCOLOR='00ffff'><CENTER>”;

OrderStr += "<FONT SIZE=+1> Order Details </FONT> <P>";

OrderStr += "<HR WIDTH='60%'><P></CENTER> <P>";

OrderStr += "Total Amount for this sale: " + frm.result.value;

OrderStr += "<P> <A href='' onClick='self.close()'>Close the window </A> <P>

OrderStr += "</HTML>";

return OrderStr;

}

Note the += means the same as oldValue = oldValue + newValue.  It means less typing which is always good.

The two single quotes in the <A href='' onClick='self.close()'> simply means it is a link to nowhere.

Student Challenge

See if you can modify your code to include the addToStringObject(frm) function

Try automatically closing the window after a set number of seconds by placing this line at the end of you sendData(frm) function.

            setTimeout(“OrderWindow.close()”, 5000);

The OrderWindow should close after 5000 milliseconds or 5 seconds.  The setTimeout() function is useful if you want to call a function after a set amount of time has elapsed.