Tuesday, April 22, 2008

Universally Related Popup Menus AJAX Edition: Part1

Getting Acquainted with the New Script and Sample Files

Welcome to the fourth installment of my Universally Related Popup Menus (URPM) series. I think you'll agree that AJAX has ushered in a whole new paradigm of browser and server interaction and end user satisfaction. If you haven't yet heard of it, prepare to be amazed!

If you aren't familiar with the URPMs, here's a working example of the original JavaScript implementation.

This article is divided into three parts. This section covers:

* a brief overview of AJAX
* some relevant JavaScript 1.3 enhancements
* how to run the example
* using the script within your own Web page

The second section will offer a more in-depth explanation of the JavaScript code.

Finally, the third section will conclude the line-by-line walkthrough of the JavaScript code and describe the server-side classic ASP script code.
AJAX in a Nutshell
AJAX stands for Asynchronous JavaScript And XML. Unlike Perl or Java, AJAX isn't a distinct language, but rather an extension of JavaScript used in conjunction with XML and DHTML. AJAX was created to solve a nagging problem that developers of dynamic Web content were faced with: how to refresh Web data without reloading the entire page. Before the advent of AJAX, developers had to resort to browser dependent hacks such as IFrames or more esoteric solutions such as Java applets. In JavaScript, the XMLHttpRequest object is what allows the browser to make asynchronous server calls behind the scenes. Since execution of AJAX processes can proceed independently, other processes may be started before the asynchronous process has finished. In other words, the user can continue to interact with the page. Otherwise, the browser would "freeze up" while it waits for the response from the server. We'll be looking at the XMLHttpRequest object in a lot more detail a little later on.
AJAX vs. XML

In the URPMs Version III article, I used XML to logically represent the contents of several related dropdown lists. To make it easier on the developer, an ASP script generated the XML code from a database. Here is an example of the resulting XML code:
1
2
3
4
5 2.2 PREMIUM
6 2.3
7 3.0
8

9
10 PREMIUM
11 SE
12 SPORT
13

14
15 GS
16 GS-R
17 LS
18 RS
19 SE
20 TYPE-R
21

22

23
24
25 LEVEL N/A
26

27
28 LEVEL N/A
29 VELOCE
30

31

32 ...
33
view plain | print | ?
2.2 PREMIUM 2.3 3.0 PREMIUM SE SPORT GS GS-R LS RS SE TYPE-R LEVEL N/A LEVEL N/A VELOCE ...

This structure makes it easy to see how each child list relates to its parent node. After reading several responses from people and playing with the sample page, there's no question that it was a versatile and useful implementation of the URPM concept. However, there was still one issue that it didn't resolve, the initial page size. The problem is that all possible selections must be download along with the page. Depending on the size of your lists, that can amount to a lot of unnecessary text! ( On the plus side, changes in the list contents are lightning fast. :-) ) AJAX circumvents this issue by loading the child lists when a selection is made instead of when the page first loads. A server-side script retrieves items from a database or flat file and then returns them to the page. Small amounts of data like this usually load fairly quickly so that any delay in loading is minimal and hardly noticeable. As a side benefit, retrieving only the relevant list items resulted in simpler server-side code than generating complex nested XML nodes.
JavaScript Gets a Makeover

The JavaScript has been updated from version 1.2 to 1.3 in order to take advantage of the new call() and apply() Function object methods. Although JavaScript 1.5 is the most current, I chose to go with 1.3 because it is the latest version supported by Internet Explorer 6. According to the w3schools.com browser statistics for December of 2007, 33.2% of web surfers were still using IE 6, compared to an even 21% for IE 7. Who wants to alienate a third of Internet users?!

Both the call() and apply() methods allows you to share the same object between any number of functions. This allows us to pass it to a function so that it runs within the scope of the object. In other words, the supplied object will be accessible to the function via the this pointer. The call() function accepts any number of parameters, while apply() takes only two, as the second parameter is an array. Later on, we'll see how to recycle a function's arguments by passing the Function.arguments property to the apply() function. Here is some sample code for the call() and apply() functions:
1 function car(make, model, year)
2 {this.make = make, this.model = model, this.year = year}
3
4 function hireCar(carNo, make, model, year)
5 {this.carNo = carNo, car.call(this, make, model, year)}
view plain | print | ?
function car(make, model, year) {this.make = make, this.model = model, this.year = year} function hireCar(carNo, make, model, year) {this.carNo = carNo, car.call(this, make, model, year)}

OR
1 function RentalCar(carNo, make, model, year)
2 {this.carNo = carNo, car.apply(this, new Array(make, model, year))}

No comments: