ASP and Javascript Quiz

A simple quiz program in ASP and JavaScript

I haven’t had the chance to write a proper tutorial for this page but here’s some code to get you started.

 Download the database, source code and images

21-nov-03: Re-wrote the quiz from scratch today. The “show answers” fuction didn’t work in Opera 5.x or NS4.x and the code was difficult to understand.

Now instead of changing background colours (which Opera 5.x doesn’t support and NS4.x usually chokes on) I have hidden graphics that show the user whether they are correct or not. As far as I know it works in all browsers.

If your web site doesn’t have ASP and database support, you can now configure the quiz quite easily using just javascript (the random generation doesn’t work however) to get the JavaScript-only version view the source of this sample page.

Preview Below:


1) What did Margaret Thatcher’s father do?
He was a tailor
He was a grocer
He was a banker
He was a farmer
 
2) Where would you expect to find a cloister?
In an inn
In a monastery
In a house
In a castle
 
3) In which year was “The Rumble in the Jungle” between Muhammad Ali and George Foreman?
1976
1970
1974
1972
 
4) Starsky & Hutch’s car was what colours?
White
Red with a Confederate flag on top
Red and white
Blue and white
 
5) Who was the last Briton to win the Formula One championship?
Nigel Mansell
Johnnie Herbert
David Coulthard
Damon Hill
 
6) What is a ‘capybara’?
A type of tree
A South American dish
A type of fish
The worlds largest rodent
 
7) ‘garderobe’ is the medieval name for a what?
wardrobe
cupboard
toilet
dressing room
 
8) What is the main purpose of putting hops in beer?
To colour it
To flavour it
To give it a smell
To preserve it
 
9) Which of these films was NOT directed by Orson Welles?
The Third Man
The Magnificent Ambersons
Touch of Evil
Citizen Kane
 
10) ‘Road To Nowhere’ was a hit for which band?
Thompson Twins
Talking Heads
Take That
Talk Talk
 

Drop Down Menu Tutorial Version 2

dHTML Drop Down Menu Tutorial – Part 1

Aims of the tutorial

This tutorial is intended to get you started on your way to building your own drop down menu system in JavaScript.

It is written for educational purposes, but will hopefully provide a full, comprehensive menu system for download at the end (at least, all the basics will be in place from which to build one).

If you want to download the example menu system for use in your site,   Download Drop down menu example here

The code in the tutorial will be loosely based on an evolution of the code from the drop down menu section (as used at the top of this page) and will include some of the improvements that will be in Version 3 or the menus. It won’t neccesarily include all of the features of these menus.

Contents

Browser Compatibility

I currently test code on the following browsers:

Windows Mac Linux (Red Hat 9)
Microsoft Internet Explorer 4.0
5.0
5.5
6.0
5.0 (OS9)
5.1.7 (OS9)
5.2 (OSX)
n/a
Netscape Navigator / Communicator 4.72
6.01
6.1
6.2
7.1
4.75
6.1
4.72
Opera 5.02
6.0
7.11
6.03 (OS9)
7.5b (OSX)
7.23
Mozilla 1.5 1.3
1.6
1.4.2
Other Safari 1.0.2
Camino 0.7
Konqueror 3.1-15

Details on obtaining browsers for testing can be found here.

The JavaScript API

Along with most of the dHTML on this site, this drop-down menu tutorial will make use of the JavaScript API. The API (Application Programming Interface) is a core set of cross-browser JavaScript functions to make dHTML programming quicker and easier.

The API performs tasks such as moving and hiding page elements (DIVs, layers or images) as well as getting and setting their attributes (such as size/position).

The API includes the following functions:

  • Basic Browser Sniffing - Not a complete browser sniffer, it only highlights those browsers that can cause problems in the menu system.
  • Get Style Object - Returns the Style Object for a given page element.
  • Change Object Visibility - Hides or shows an element.
  • Find Image (NS4 only) - Used to find image objects in NS4.
  • Find object (NS4 only) - Used to find other objects in NS4.
  • Get Element Width/Height - Gets the width or height of any page element (not images in NS4).
  • Get Element Top/Left - Get the page co-ordinates of any element (not images in NS4).
  • Get Image width/Height - Gets the width or height of any image.
  • Get Image Top/Left - Get the page co-ordinates of any image.
  • Move Element - Sets the x and y co-ordinates of an element.
  • Change Style Class - changes the style class of an object (Not NS4 or Opera 5/6).

It’s worth taking a few minutes to familiarise yourself with the API. Click here to go to the API section (opens in a new window).

How the System Will Work

The code for the menus will be perform two main tasks:

1. Building the menus

To make the menus easy to build and maintain, we’ll build a set of functions that will create the html for the menus for us. Not only does this make building the menus simpler, these configuration files will used throughout your site – just change one file and the changes will effect every page.

There will be functions to build the menu bars and the menus themselves. The menu bars are just tables containing links that activate the menus, the actual menus are tables wrapped in a <div> element that can be displayed, hidden and moved around the page.

2. Operating the menus

These functions will show and position the menus when the user activates them and hide them again when necessary.

The positioning of the menus is based on the position of the label they are attached to. We’ll use functions from the JavaScript API to get the page co-ordinates of the label, and then to position the menu relative to it.

Terminology Used in the Tutorial

In the tutorial I’ll be using terms like “menus”, “submenus”, “menu labels”, “submenu labels” and “menu items”.

The figure on the right should help to explain what I mean by these terms. It shows a menu bar along the top of a page with a menu dropping down from it. Hanging off this menu is a submenu.

Menus drop down from the menu bar, Submenus hang from other menus.

We need different names for them in the tutorial because the rules for positioning them are different.

Menus and submenus are made up of Menu Items. Menu items which spawn submenus are referred to as Submenu Labels.

The Bullet Points

This may seem like an odd place to start the tutorial, but it explains a little about object oriented programming (OOP) in JavaScript.

You can find out more about JavaScript OOP at javascriptkit.com.

The Code

The code below creates an object with 3 properties:

  1. An image object for the “off” version of the bullet
  2. An image object for the “on” version of the bullet
  3. A string containing the URL of the “off” version of the bullet (used later in the tutorial)
function bulletPoint(offURL, onURL) {
	this.offImage = new Image();
	this.offImage.src = offURL;
	this.onImage = new Image();
	this.offImage.src = onURL;
	this.menuBulletURL = String(offURL);
}

Usage

The code below creates three bulletPoint objects called menuItemBullet, labelBullet and subMenuBullet. We’ll use these later in the tutorial.

menuItemBullet = new bulletPoint("menu_off.gif", "menu_on.gif");
labelBullet = new bulletPoint("header_off.gif", "header_on.gif");
subMenuBullet = new bulletPoint("sub_header_off.gif", "sub_header_on.gif");

The images in these objects can then be referenced by menuItemBullet.offImage,menuItemBullet.onImage etc. The URL of the “off” image would be menuItemBullet.menuBulletURL.

Some Globals

The menu system will use a number of global variables. Using globals goes against the OOP design, but makes sharing data easier.

The globals are:

// used to hold a timer
var timeOn = null;

// the maximum number of menus in the system
// (can be increased if necessary)
var numMenus = 50;

// used internally to count the menus defined so far
var currentMenuNo = 0;

// used internally to store whether a menu is active
// or not. Speeds up the system
var menuActive = new Array(numMenus);

// stores which tier the menu is in
var tier = new Array(numMenus);

// used to help line up the menus more accurately
// when borders are enabled
var borderMod = new Array(numMenus);

// the "off" class of the corresponding (sub)menu label link
var offClass = new Array(numMenus);

// the "on" class of the corresponding (sub)menu label link
var onClass = new Array(numMenus);

// the "off" colour of the corresponding (sub)menu label background
var offColours = new Array(numMenus);

// the "on" colour of the corresponding (sub)menu label background
var onColours = new Array(numMenus);

// the name of the bullet object (if any) used
// by the corresponding (sub)menu label
var labelBulletName = new Array(numMenus);

// the type of (sub)menu label corresponding to this menu
// currently can be 'defualt' for a normal menu
// or 'blank'
var menuType = new Array(numMenus);

// an array used to hold the menu objects in the system
var menus = new Array(numMenus);

Building the Menu Bar – The “menuBar” Object

The menuBar object does the job of building the HTML for the menu bar.

Below are the properties of the object (the two methods are covered later).

// -- OBJECT ARGUMENTS: --
// barName: an ID for the DIV that surrounds the menu bar
//   which can then be altered using CSS
// barWidth: the width of the menu bar in pixels
// orientation: can be 'horizontal' or 'vertical'
// i_Bor: Inner border colour (between the menu labels)
//   (set as 'null' for no inner border)
// o_Bor: Outer border colour(around the menu bar as a whole)
//   (set as 'null' for no outer border)

function menuBar(barName, barWidth, orientation, i_Bor, o_Bor) {

// --- PRIVATE PROPERTIES --

  // used internally count the number of labels in the menu bar
  this.numLabels = 0;

  // store the border colours and orientation
  this.i_Bor = i_Bor;
  this.o_Bor = o_Bor;
  this.orientation = orientation;

  // used to store the HTML for the menu bar
  this.labelText = new Array();
  // used in vertical menu bars to store the row element
  this.rowText = new Array();

// -- PUBLIC PROPERTIES --
// can be altered BEFORE adding menu labels to the menu bar

// height of the bar in pixels
  this.height = 15;

// the classes for the links
  this.offClass = 'MenuLabelLink';
  this.onClass = 'MenuLabelLinkOn';

// alignment of the bullet points (if any)
// can be 'left' or 'right'
  this.bulletAlign = 'left';

// can be 'self', 'iframe', 'frame', 'new'
  this.targetType = 'self'; 

// '_self', '_blank' or (i)frame name
  this.targetFrame = '_self'; 

// -- METHODS --
// (described later)
  this.addLabel = function(bullet, labelText, menuNo, labelWidth,
    offColour, onColour, labelURL, align) {
    // code displayed later
  }
  this.writeMenuBar = function() {
    // code displayed later
  }
}

Usage

The following creates a 450 pixel wide horizontal menu bar called “myTest”:

myTest = new menuBar('myTest',450, 'horizontal', '#ff0000', '#000000');

Building the Menu Bar – Adding menu labels

Quick Tip: Early revisions of my menu code used multiple document.write statements to write the html one line at a time. This works fine in most browsers except Opera 5.x (and to a lesser extent Opera 6.x) where document.write seems to be very slow. In this system we’ll build fewer, longer strings. This greatly increases the speed in the Opera browsers.

This method builds a string of HTML for a menu label and stores it it in the labelText array. Due to differences in Netscape 4, the code is quite long. Netscape 4 uses a layer nested in an ilayer (mouseover and mouseout events are attached to the layer – NS4 doesn’t offer onclick events for layers). The other browsers use just a div element (the events are attached to the parent td element).

The Code

// -- METHOD ARGUMENTS --
// bullet: the name of a bullet object or null
// labelText: the text to appear in the menu label
// menuNo: the number of the menu which pops from this menu label
//   (can be a blank menu - i.e. one with no menu items)
// labelWidth: width of the label in pixels
// offColour: the background colour of the label's "off" state
// onColour: the background colour of the label's "on" state
// labelURL: the URL of the page the menu label links to
// align: the text alignment can be 'left', 'right', or 'center'
//   (note American spelling in this case)

this.addLabel = function(bullet, labelText, menuNo,
  labelWidth, offColour, onColour, labelURL, align) {

  // increment the counter of menu labels in the menu bar
  this.numLabels += 1;

  // set the tier for the menu hanging from this label
  tier[menuNo] = 0;		

  // this is an offset for placing the menu due to the outer border
  if (this.o_Bor != null) borderMod[menuNo] = 1;
  else borderMod[menuNo] = 0;

  // set the globals for the menu label
  if (menuNo != null) {
    onColours[menuNo] = onColour;
    offColours[menuNo] = offColour;
    onClass[menuNo] = this.onClass;
    offClass[menuNo] = this.offClass;
    labelBulletName[menuNo] = bullet;
  }

  // create a temporary string object to hold
  // the html for the menu label
  temp = new String('');

  // create a string object to hold the row tag
  // for the label (if necessary)
  this.rowText[this.numLabels] = new String('');

  if (this.orientation == 'vertical')
    this.rowText[this.numLabels] += '<tr id="labelRow'+ menuNo + '">';

  // create the td tag
  temp += '<td id="labelCell' + menuNo + '" width="'+ labelWidth + '" bgcolor="' +
    offColour + '" valign="middle" height="' + this.height + '" ';

  // if the browser ISN'T Netscape 4...
  if (!ns4) {
    // ...attach events to the td tag
    temp += ' onmouseout="menuOut(); "onmouseover="menuOver(); ';

    if (this.orientation == 'vertical')
      temp += 'return !showMenuSide('+ menuNo+', event, tier['+menuNo+']);" ';
    else
      temp += 'return !showMenu(' + menuNo + ', event);" ';

    if (this.targetType=='self')
      temp += ' onclick="document.location.href=\'' + labelURL + '\';" ';
    if (this.targetType=='new')
      temp += ' onclick="openMe(\'' + labelURL + '\'); return false;" ';
    if (this.targetType=='frame')
      temp += ' onclick="parent.' + this.targetFrame +
        '.document.location.href=\'' + labelURL + '\';" ';
    if (this.targetType=='iframe')
      temp += ' onclick="' + this.targetFrame + '.location.href=\'' +
        labelURL + '\';" ';
  }
  // close the td tag
  temp +='>';

  // if the browser IS Netscape 4...
  if (ns4) {
    // ...create layer within an ilayer and attach the events to this
    temp +='<ilayer><layer onmouseout="menuOut();" onmouseover="menuOver(); ';
    if (this.orientation == 'vertical')
      temp +='return !showMenuSide('+menuNo+', event, tier['+menuNo+']);" ';
    else
      temp +='return !showMenu(' + menuNo + ', event);" ';
  } else {
    // if NOT Netscape 4 we use a div tag instead
    temp +='<div ';
  }

  // give the layer/div an ID and start the link tag
  temp += ' width="' + labelWidth +
    '"  id="menuLabel' + menuNo +'"><a href="' + labelURL +'"
    target="' + this.targetFrame + '"
    id="menuLink' + menuNo +'">';

  // if bullet points are enabled...
  if (bullet != null)
    // put in the bullet point
    temp += '<img src="' + eval(bullet + ".URL") + '" border="0"
      align="' + this.bulletAlign + '"
      id="menuBullet' + menuNo + '" name="menuBullet' + menuNo + '">';

  // close the link tag
  temp += labelText + '</a>';

  // close the layer or div (depending on browser)
  if (ns4) temp += '</layer></ilayer>';
  else temp += '</div>';

  // close the td tag
  temp += '</td>';	

  // create a string object and store the HTML
  // from the temporary string in it for later
  this.labelText[this.numLabels] = new String(temp);
}

Usage

The following Code adds three menu labels to the menu bar:

myTest.addLabel('menuItemBullet', 'test1', 1, 150, '#cccccc',
  '#ffffff', 'test1.asp', 'left');
myTest.addLabel('labelBullet', 'test2', 2, 150, '#cccccc',
  '#ffffff', 'test2.asp', 'center');
myTest.addLabel('subMenuBullet', 'test3', 3, 150, '#cccccc',
  '#ffffff', 'test3.asp', 'right');

					

Javascript API

JavaScript API

Download Zip Now

WARNING: This is a very old API and is only kept here for historical purposes. If you are looking for a robust API to make javascript coding easier I recommend you check out prototype or jQuery

Introduction

This is a simple API (Application Programming Interface) for creating dHTML pages.

There’s nothing even remotely new here, but I use this code in many of the other scripts on the site so I thought I’d explain how it works.

Continue reading “Javascript API” »