CSCI A348/A548

Lecture Notes 12

Fall 1999


JavaScript Table of Contents. Examples. More perl and CGI.pm examples. Dynamic HTML.

Here's a table of contents for a good overview of JavaScript (complete with interesting and relevant examples) that you will find in the pages of your textbook. Since our next homework assignment (to be posted next week, and due the week after) will require building a shopping cart application (that will be very much like the one described in this chapter starting on page 627) you may safely take the list of topics enumerated below as assigned reading.

571: Chapter 10: JavaScript

More (Simple) JavaScript Examples

1. Here's the most basic idea about in-lab assignment 2 (lab notes 6).

You need to install a script like this:

#!/usr/bin/perl
use CGI;
$q = new CGI; 
print $q->header, 
      $q->start_html(-title=>'JavaScript Lab (Template)',
                     -bgcolor=>'white');                   
if ($q->request_method() eq 'POST') {
  print "Thank you for your submission!<p>Here's your data: <p> "; 
  print $q->dump; 
} else { # GET matches this branch too... 
  print qq{
    <script>
	function validate() {
          alert("I don't think so!"); 
          return false; 
        } 
    </script> 
    <form method='POST' 
          action='$ENV{SCRIPT_NAME}'
          onSubmit='return validate()'> 
      Notice that this particular form is empty. <p> 
      Click <input type='submit' value='Proceed'> to continue.  
    </form> 
  }; 
} 
print $q->end_html;
I marked the It should be clear This last case is precisely describing our situation in this short example here where we pop up an alert window and disable the submission.

A note on the assignment, that should be true of the next homework assignment: there was a typo in the lab notes, so don't expect code from the notes or the textbook to run when typed in (although most of the times that will be true). Try to understand the code as you type it in and this way you will be avoiding delays in finishing the assignments, and possibly moments of mild frustration.

2. Here's homework assignment 2 (more or less) implemented with JavaScript. This example uses the animation code from the lecture notes on Tuesday by calling the animate function to actually render a single frame:

<html>
<head>
<title>
javascript: example
</title>
</head>
<body bgcolor=white>

This represents an implementation of homework 2 (almost) without
the server being involved at all. It provides an example of the use
of the <code>javascript:</code> URL pseudo-protocol 
that we talked about in lecture 
yesterday. Hope you find the example informative and interesting. <p> 

<!-- This is the HTML, that contains the links 
        and shows the first frame  -->

<table width=100%>
<tr>  <td> <a href="javascript:animate(1);">One</a>
</td> <td> <a href="javascript:animate(2);">Two</a>
</td> <td> <a href="javascript:animate(3);">Three</a>
</td> <td> <a href="javascript:animate(4);">Four</a>
</td> <td> <a href="javascript:animate(5);">Five</a>
</td> <td> <a href="javascript:animate(6);">Six</a>
</td> <td> <a href="javascript:animate(7);">Seven</a>
</td> <td> <a href="javascript:animate(8);">Eight</a>
</td> <td> <a href="javascript:animate(9);">Nine</a>
</td> <td> <a href="javascript:animate(10);">Ten</a>
</td> </tr> 

<tr> <td colspan=10 align=center>
<img src=
     "http://www.cs.indiana.edu/classes/a202/lectures/last/T1.gif" 
     name="animation"> 
</td> </tr> </table> 

<!-- Now the JavaScript functions that are invoked 
        through the links above -->

 <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/lectures/last/T" 
          + (i + 1) + ".gif";
      } 

      function animate(frame) {
        frame = (frame + 1) % 10; 
        document.animation.src = images[frame].src;
      }
      var frame = 0; 

</script> 

</body></html>  

I have used the same color conventions as before.

3. This is homework 3 (more or less) without CGI processing.

<html>
<head>
<title>
Howework 3 Calculator with JS
</title>
<script>
acc = 0; 
function calculate() {
  if (document.calculator.fun.selectedIndex == 1) {
    acc = acc + eval(document.calculator.arg.value); 
  } else if (document.calculator.fun.selectedIndex == 2) {
    acc = acc - eval(document.calculator.arg.value); 
  } else {
    acc = acc; 
    alert('Please choose one of the available functions!'); 
  }
  document.calculator.acc.value = acc; 
  document.calculator.arg.value = 0; 
}
</script>
</head>
<body bgcolor=white>
<form name="calculator" onSubmit="calculate(); return false;">
The accumulator is: <input type="text" name="acc"> <p> 
Choose a function: <select name="fun"> 
<option value="none"> Click Me!
<option value="add"> Add
<option value="sub"> Sub
</select> <p> 
And type an argument: <input type="text" name="arg"> <p> 
Then click <input type="submit" value="Compute"> <p> 
</form> 
</body>
</html>
More examples with CGI.pm

All forms elements with CGI.pm methods:

#!/usr/bin/perl

use CGI;
$query = new CGI;

print $query->header, 
      $query->start_html (-bgcolor=>'white', 
                          -title=>'HTML Forms Widgets'); 
if ($query->request_method eq 'GET') {
  &show_form; 
} else {
  print $query->dump, $query->hr; 
  &process_query;   
} 
print $query->end_html; 

sub show_form { print 
  "\n", $query->start_form(-method=>'POST', 
                           -action=>$query->url),
  "\n", qq{This is a text field called fieldT1: <p>}, 
  "\n", $query->textfield(-name=>'fieldT1', 
                          -size=>20, 
                          -maxlength=>40),
  "\n", qq{<hr>Textarea called fieldT2: <p>},
  "\n", $query->textarea(-name=>'fieldT2', 
                         -default=>'Replace me with your answer', 
                         -rows=>5, 
                         -columns=>60),
  "\n", qq{<hr>Password field called fieldPw: <p>}, 
  "\n", $query->password_field(-name=>'fieldPw', 
                               -size=>20,
                               -maxlength=>20),
  "\n", qq{<hr>Popup menu field called fieldM: <p>},
  "\n", $query->popup_menu(-name=>'fieldM',
                           -values=> [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
                           -labels=> { 1 => 'one', 2 => 'two',
                                       3 => 'three', 4 => 'four', 
                                       5 => 'five', 6 => 'six', 
                                       7 => 'seven', 8 => 'eight',
                                       9 => 'nine', 10 => 'ten'}), 
  "\n", qq{<hr>Scrolling list field called fieldSc: <p>}, 
  "\n", $query->scrolling_list(-name=>'fieldSc', 
                               -values=> [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
                               -size=>5, -multiple=>'true', 
                               -labels=> { 1 => 'one', 2 => 'two',
                                           3 => 'three', 4 => 'four', 
                                           5 => 'five', 6 => 'six', 
                                           7 => 'seven', 8 => 'eight',
                                           9 => 'nine', 10 => 'ten'}), 
  "\n", qq{<hr>Group of checkboxes called fieldChk: <p>}, 
  "\n", $query->checkbox_group(-name=>'fieldChk', 
                               -linebreak=>'true', 
                               -values=> [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
                               -labels=> { 1 => 'one', 2 => 'two',
                                           3 => 'three', 4 => 'four', 
                                           5 => 'five', 6 => 'six', 
                                           7 => 'seven', 8 => 'eight',
                                           9 => 'nine', 10 => 'ten'}),
  "\n", qq{<hr>Group of radio buttons called fieldR: <p>},
  "\n", $query->radio_group(-name=>'fieldR', -default=>'--', 
                            -linebreak=>'true', 
                            -values=> [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
                            -labels=> { 1 => 'one', 2 => 'two',
                                        3 => 'three', 4 => 'four', 
                                        5 => 'five', 6 => 'six', 
                                        7 => 'seven', 8 => 'eight',
                                        9 => 'nine', 10 => 'ten'}),
  "\n", qq{<hr>A hidden field with name fieldH and value <em>discreet</em>: <p> }, 
  "\n", $query->hidden(-name=>'fieldH', -default=>'discreet'), 
  "\n", qq{<hr> Submit button to send the contents of this form to the server: <p> }, 
  "\n", qq{ Click here to}, $query->submit(-name=>'proceed'), 
  "\n", qq{<hr> Reset button to start again: <p> }, 
  "\n", qq{ To reset the form to the original values: }, $query->reset, 
  $query->end_form;  
} 

sub process_query {
  foreach $name ('fieldT1', 'fieldT2', 'fieldPw', 
    'fieldM', 'fieldSc', 'fieldChk', 'fieldR', 'fieldH') { 
    &process_param($name); 
  } 
} 

sub process_param {
  my ($name) = @_; 
  if      ($name eq 'fieldT1') {
    $value = $query->param($name); 
    print $query->ul(
            $query->li("Name: $name"),
            $query->li("Value: " . 
                        $query->escapeHTML($value)));
    print $query->hr;  
  } elsif ($name eq 'fieldT2') {
    $value = $query->param($name); 
    $value = $query->param($name); 
    print $query->ul(
            $query->li("Name: $name"),
            $query->li("Value: " . 
                        $query->escapeHTML($value)));
    print $query->hr;  
  } elsif ($name eq 'fieldPw') {
    $value = $query->param($name); 
    $value = $query->param($name); 
    print $query->ul(
            $query->li("Name: $name"),
            $query->li("Value: " . 
                        $query->escapeHTML($value)));
    print $query->hr;  
  } elsif ($name eq 'fieldM') {
    $value = $query->param($name); 
    $value = $query->param($name); 
    print $query->ul(
            $query->li("Name: $name"),
            $query->li("Value: " . 
                        $query->escapeHTML($value)));
    print $query->hr;  
  } elsif ($name eq 'fieldSc') {
    @values = $query->param($name);
    foreach $value (@values) { 
	$value = $query->escapeHTML($value); 
    } 
    print $query->ul(
            $query->li("Name: $name"),
            $query->li("Values: " . 
		       $query->blockquote(join('<br>', @values)))); 
    print $query->hr;  
  } elsif ($name eq 'fieldChk') { 
    @values = $query->param($name);  
    foreach $value (@values) { 
	$value = $query->escapeHTML($value); 
    } 
    print $query->ul(
            $query->li("Name: $name"),
            $query->li("Values: " . 
		       $query->blockquote(join('<br>', @values)))); 
    print $query->hr;  
  } elsif ($name eq 'fieldR') {
    $value = $query->param($name); 
    $value = $query->param($name); 
    print $query->ul(
            $query->li("Name: $name"),
            $query->li("Value: " . 
                        $query->escapeHTML($value)));
    print $query->hr;  
  } elsif ($name eq 'fieldH') {
    $value = $query->param($name); 
    $value = $query->param($name); 
    print $query->ul(
            $query->li("Name: $name"),
            $query->li("Value: " . 
                        $query->escapeHTML($value)));
    print $query->hr;  
  } else {

  } 
} 

sub escapeHTML {
  my ($string) = @_; 
  # 
  return $string; 
}
Feedback form with CGI.pm (comments mailed to you by script):

#!/usr/bin/perl

use CGI;

$query = new CGI;

if ($query->request_method eq 'GET') {
  &show_form; 
} elsif ($query->request_method eq 'POST') {
  &process_form; 
} else {
  &error('Unsupported request method.'); 
} 

sub error { my ($message) = @_; 
  print $query->header, 
        $query->start_html(-bgcolor=>'white'), 
        qq{ $message }, $query->end_html; 
} 

sub process_form {
  my $email, $message; 
  $message = $query->param('message'); 
  $email = $query->param('email'); 
  $email =~ s/\s//g; 
  if ($email =~ /^[a-zA-Z]+\@indiana.edu$/i) { 
  } elsif ($email =~ /^[a-zA-Z]+$/i) {
    $email .= "\@indiana.edu"; 
  } else { &error('Unsuported e-mail address format.'); } 
  open MAIL, "| mail $email dgerman\@indiana.edu "; 
  print MAIL $message; 
  close MAIL; 
  print $query->header,
        $query->start_html(-bgcolor=>'white'),
        qq{ Your message<blockquote>$message</blockquote> has 
            been sent to the webmaster. A copy has been sent  
            to the e-mail address that you indicated. }, 
        $query->end_html;
} 

sub show_form { print 
  $query->header, 
  $query->start_html(-bgcolor=>'white', 
                     -title=>'feedback'),
  $query->start_form(-method=>'POST', 
                     -action=>$query->url),
  qq{ Email address: }, 
  $query->textfield(-name=>'email', 
                    -size=>20,
                    -maxlength=>40),
  $query->p, qq{Message: },
  $query->textarea(-name=>'message', 
                   -rows=>5, 
                   -columns=>60,
                   -default=>'Replace me with your comments...'),
  $query->p, $query->submit(-name=>'Proceed'), $query->end_form, 
  $query->end_html; 
}
Working with clickable images using CGI.pm is easy:

Note that the image acts as a submit button so we could not make this part of the form from the example above (that exemplifies the managing of HTML form widgets using CGI.pm).

However we will show later how Java and Javascript can cooperate to make a clickable image behave as a two-dimensional (graphical) radio button.

#!/usr/bin/perl

use CGI;
# use CGI::Carp 'fatalsToBrowser'; 
$query = new CGI;

print $query->header, 
      $query->start_html(-bgcolor=>'white', -title=>'Clickable Image');

if ($query->request_method eq 'GET') { 
  print $query->startform(-method=>'POST', 
                          -action=>$query->url), 
  qq{ Please click on the image below and the server will return the X 
      and Y coordinates of that pixel within the image to you. <p> }, 
  $query->image_button(-name=>'picture',
                       -src=>'http://www.cc.columbia.edu/low3.gif'),
  $query->p, $query->endform;
} else { print $query->dump, 
  qq{ X coordinate: }, $query->param('picture.x'), $query->p, 
  qq{ Y coordinate: }, $query->param('picture.y'), $query->p; 
} 

print $query->end_html;           
We'll also discuss homework assignment 4, and perhaps take a look at Dynamic HTML to make comparisons between JavaScript and VBScript and Netscape and IE.

Documentation for CGI.pm needs to be looked into for homework 4.


Last updated: October 7, 1999 by Adrian German