Notes 12
— print (last updated: Jul 15, 2009) print

Select font size:

Hyperlink-activated function calls

An interesting usage of JavaScript functions is having them called through hyperlinks. This can be done very easily, simply preface the function by "javascript:". For example,
<a href="javascript:alert('testing')">Testing Alert</a>
has this effect:
Testing Alert
This simple example illustrates why it is useful to have more than type of quotes to create strings because the testing string used inside the href attribute's value must be quoted.

User-defined functions

The previous example illustrated how to call function from a hyperlink. To allow for more general behaviors on events, JavaScript allows the creation of new functions, called user-defined functions, using this syntax:
function foo() 
{
  // Javascript code
}
This defines foo as a function with no parameters (we won't worry about parameters at the moment). Once foo has been defined, it can be used in later JavaScript code. Functions are typically defined within the script tags placed within the head of an HTML document. Here is a prototypical usage:
<html>
<head>
<title></title>
<script type="text/javascript">
<!--
function foo() 
{ 
  // do something
}
// -->
</script>
</head>
<body>
 
<a href="javascript:foo()">Call Foo</a>

</body>
</html>
Here is an example of some of our standard JavaScript programming activated through a hyperlink. You can create much of the syntax through the JS button in HTML-Kit.
<html>
<head>
<title></title>
<script type="text/javascript">
<!--
function foo()
{
  var str = prompt( "Enter your name", "YOUR NAME" )   // prompt
  document.writeln( "Hello, " + str ) 
}
// -->
</script>
</head>
<body>
<a href="javascript:foo()">Testing</a>
</body>
</html>

Unfortunately, this is less than desirable because the output effectively overwrites the hyperlink making it apparently unusable more than once without refreshing the page and starting over. Used in this way, the document.writeln operation always creates a new document, discarding the old one.

The document.getElementById function and innerHTML property

When we use a function to create output in a document, we typically don't want the output to be created with the document.writeln function because this would effectively start from scratch and overwrite the entire document. In particular, if the function were activated from a hyperlink as in the above example, the document, including the hyperlink, would be overwritten.

What we want to do is to modify, in JavaScript, aspects of an HTML element "in place". This can be done provided that we know: Obtaining a JavaScript representation of an HTML element can be done in several ways, but, perhaps the simplest way is to use the id attribute in conjuction with the function
document.getElementById
Every HTML element supports the id attribute and the JavaScript function document.getElementById does exactly what it suggests, it gets the object which represents the element with that specific id value. If more than one element have the same id value, all but the first are ignored.

Once we have this HTML element as an object in JavaScript, we can modify any of its attributes or even its contents (i.e., the HTML code between the start and end tags). For example, if we have this element in our document

<p id="mypar">Here is a paragraph</p>
then the following JavaScript code obtains the object which represents the element:
var mypar = document.getElementById( "mypar" );
and we can modify this element as we please, for example:
mypar.innerHTML = "New paragraph content";
The HTML contents of the paragraph mypar is obtained by a special subobject called innerHTML. In contrast to the document.writeln usage above, document.getElementById in conjunction with the setting of innerHTML modifies the current document in place.

Simple program revised

Applying the ideas above to our simple program we revise this with the following steps: The effects of these changes yields this program:
<html>
<head>
<title></title>
<script type="text/javascript">
<!--
function foo()
{
  var x = document.getElementById( "x" )
  var str = prompt( "Enter your name", "YOUR NAME" )
  //document.writeln( "Hello, " + str )
  x.innerHTML = "Hello, " + str
}
// -->
</script>
</head>
<body>
<a href="javascript:foo()">Testing</a>
<p id="x">***</p>
</body>
</html>

The square program revisited

To make the square program more interesting, we activate the squaring through a hyperlink and print the output in an empty paragraph below the hyperlink.
<html>
<head>
<title>Square from Hyperlink</title>
<script type="text/javascript">
<!--
function do_sqr()
{
  var output = document.getElementById("output")   // get output paragraph
  var str = prompt( "Enter a number", "" )   // prompt
  var num = parseFloat(str)                  // string -> numeric
  if (isNaN(num)) {
    alert( "Inputs Cancelled/Invalid" ) 
  } else {
    var result = num * num                           // compute
    output.innerHTML = num + " squared is " + result  // replace contents
  }
}
// -->
</script>
</head>

<body>

<a href="javascript:do_sqr()">Compute A Square</a>

<p id="output">Answer</p>

</body>
</html>

The effects of this program can be seen through this link.

output variation

Consider a variation of this program in which the input and result are placed into the document. The initial document looks like this:
Compute A Square
input: ---
result: ---
The goal is to place the answers into the document, e.g.,
Compute A Square
input: 3
result: 9
The other issue is what to do about input errors/cancellation. A common solution is to reset the document to its original appearance.

Multiple inputs

Consider an example of a program which prompts for two inputs and multiplies them. We want to raise separate alerts for: Key in this program into the script tags within the body and run it in different ways to test all the cases, e.g.:
first input second input
Cancel
5Cancel
56
xx6
4xx
<html>
<head>
<title>Multiply Two Numbers</title>
<script type="text/javascript">
<!--
function compute()
{
  var output = document.getElementById("output") 
  var str1 = prompt( "Enter first number", "3" )
  var str2 = prompt( "Enter second string", "4" )
  if (str1 == null || str2 == null) {
    alert( "Input(s) cancelled" )
    output.innerHTML = ""
  } else {
    var num1 = parseFloat(str1)
    var num2 = parseFloat(str2)
    if ( isNaN(num1) || isNaN(num2) ) {
      alert( "at least one non-numeric entry" ) 
      output.innerHTML = ""
    } else {
      var prod = num1 * num2
      output.innerHTML =  num1 + "*" + num2 + " = " + prod 
    }
  }
}
// -->
</script>
</head>

<body>

<a href="javascript:compute()">Multiply 2 Numbers</a>

<p id="output"></p>

</body>
</html>

The effects of this program can be seen through this link.

Computation with if/else structures

In many situations a numeric computation is based on cases. The if/else structure provides the means to diffentiate these cases. We will want to choose from the entire set of boolean comparison operators:
== (equals),        != (not equals), 
<  (less than),     <= (less than or equal), 
>  (greater than),  >= (greater than or equal) 
For example, consider this simple problem:

If your monthly salary is $4000 or more, you are taxed at 23%; if it is less than $4000, but at least $2000, you are taxed at 21%; otherwise, you are taxed at 18%.

Write a javascript program to prompt for the monthly salary, compute and print out the amount of tax. Round the tax amount to 2 decimal places. Alert for invalid or cancelled input.
The computation can be broken down as into two decisions: A solution follows the lines of decision:
<html>
<head>
<title>Compute Tax</title>
<script type="text/javascript">
<!--
function compute()
{
  var S = document.getElementById("S") 
  var T = document.getElementById("T") 

  var str = prompt( "Enter monthly salary: ", "" ) 
  var sal = parseFloat(str) 

  var tax; // tax is undefined in declaration because its
           // computed value differs depending on the case

  // now, compute the tax based on the salary
  // we could check now for a umeric errors, or wait 
  // until later as we do here

  if (sal >= 4000)
    tax = sal * .23 
  else if (sal >= 2000)
    tax = sal * .21 
  else
    tax = sal * .18 
	
  // if everything went OK, round and print result, 
  // otherwise raise an alert

  if (isNaN(sal)) {
    alert( "invalid/cancelled input" ) 
    S.innerHTML = "---" 
    T.innerHTML = "---" 
  } else {
    tax = Math.round(tax * 100) / 100 
    S.innerHTML = sal
    T.innerHTML = tax
  }
}
// -->
</script>
</head>

<body>
<a href="javascript:compute()">Compute Tax</a>
<p>
Salary:  <span id="S">---</span>
<br />
Tax Due: <span id="T">---</span>
</p>
</body>
</html>

The effects of this program can be seen through this link.

Observe that, when computing with if/else statements, it is useful to be able to simply declare the variable tax without giving it an initial value.


© Robert M. Kline