Download the Ajax.zip archive. Install this as a Java Web Application with Existing Sources. Add the CommonsLang Library as used in java-forms.html. This application contains the important jQuery JavaScript package which is represented by the single file in the js folder of the Web Pages (the actual folder is web).
jquery.js
JavaScript, Ajax, Toolkits
AJAX is an acronym for Asynchronous Javascript And Xml. The most important point that AJAX is about using JavaScript to make asynchronous server-side calls without having to do a browser reload, allowing web applications to behave more like standard graphical user interface applications.
Modern web applications often feature specialized effects accomplished by JavaScript code written using client-side toolkits. Writing in JavaScript directly tends to be quite tedious and error-prone. The JavaScript language, per se, lacks capabilities for modularity, sharing and testing. Errors are often difficult to track down and browser differences become prominent. The point about client-side toolkits is that they:
* add and replace functionality to JavaScript
* hide browser differences and quirks
* optimize the usage of JavaScript code
As can be expected, there are quite a few such toolkits. One can choose among a long list such as Dojo, Prototype, MochiKit, Google Web Toolkit, AJILE, Echo, Ext, jQuery, ASP.NET AJAX, MooTools, qooxdoo, Rialto, Rico, Scriptaculous, SmartClient, Spry, Yahoo! UI Library, etc. The one we'll use is jQuery along with one of its plugins found at these websites:
jquery.js: http://www.jquery.com/
jquery.form.js: ttp://malsup.com/jquery/form/
Testing/Debugging
JavaScript used in any setting is a difficult language to debug. Fortunately there are some tools and techniques that make it possible. Here are some key points:
1. Use Firefox (sorry IE devotees)! Firefox's built-in JavaScript debugger is the Error Console (accessed through the Tools Error Console menu) which often suffices to debug JavaScript.
2. Install Firebug. Once installed, access it by: Tools Firebug Open Firebug. The HTML tab will display JavaScript-generated code which is not visible by viewing the source code. The console tab will view show information about the AJAX activations which is not visible directly in any other way.
3. JavaScript uses a form of lazy object construction in that its objects are not declared anywhere, just created on the fly. This means that you can add new members at will to almost any existing object. The big downside of this approach is that most misspellings of a subobject will not be regarded as errors. For example, if you mean to write:
document.getElementById('myelt').innerHTML = "hello"
but mistakingly write:
document.getElementById('elt').innerHtml = "hello"
there will be no error, but "nothing will happen," making it hard to track down.
This points to one of the advantages of client-side toolkits in that they provide alternative operations which avoid direct usage of JavaScript coding.
4. Alerts and console messages. A common way of debugging JavaScript is to issue alert("...") statements which invoke a popup message. More subtle is the usage of console.log("...") messages which are issued to the Firebug console.
5. It is often useful to test the server-side handlers "by hand", independently of their being called by a JavaScript activation. In this case, you'll want to manipulate the browser's location line by hand, passing the parameters via the query string. For example, assuming that xx and yy are the relevant incoming query parameters, try:
http://localhost:8080/.../servlet/Handler?xx=1&yy=2
JavaScript
The JavaScript language shares much of the same syntax as the Java language minus the strong typing. Strings can be delimited by double or single quotes and there is only one numeric type (represented by a double).
Other than language details, the most significant difference with Java is that JavaScript is built in to the standard browsers in order program all the browser features according to the so-called Document Object Model (DOM). The DOM supports at its top level the window object, representing the entire browser. The subobjects of window are these:
* document (referring to the HTML document contents),
* navigator (information about the browser type, version, etc),
* location (information about the URL being accessed),
* history (access to previous pages),
* status (the status bar at bottom of browser),
* frames[] (access to frames in a frame-based layout).
For example, the expression window.document refers to the document part of window object. In all cases, JavaScript permits the omission of the top-level "window." syntax and simply write "document" (and others).
Introducing JavaScript code into HTML
JavaScript code is typically made available through the script tags:
These lines make a browser which does not recognize JavaScript ignore the code between:
Alternatively, an external code file, say extern-code.js can be loaded with this script tag usage:
Activation through JavaScript Events
Our JavaScript code of interest consists mostly of functions called by JavaScript events. For example, we can create a "generic" button which calls a JavaScript function as follows:
or
where the JavaScript code section contains:
function my_button_handler()
{
// what to do when the button is pressed
}
Reading/Writing HTML elements from JavaScript
Within JavaScript code we need to be able to read and write data from the HTML elements. JavaScript provides a number of ways to obtain a DOM object for an HTML element, but perhaps the simplest and direct way is by assigning an id attribute to the element and obtaining an object for it with the function document.getElementById. For example, if we define:
then, within JavaScript we can obtain an object representing this textfield with the statement:
var tf = document.getElementById( "tf" )
JSON format
JSON (JavaScript Object Notation) is a format for expressing structured object literals. This notation is used heavily in most of the client-side toolkits as parameters of the function calls. For example:
{ x: 222, y: "hello" } -- an object with members x and y
[ 12, "hello", 15 ] -- an array
{ z: [ 22, 33 ] } -- an object with array value
[ {x: 12, y: "aa"}, {x: 17, y: "bb"} ] -- an array of objects
Not only are these JSON literals used to call client-side functions, they can be used to transmit structured data back to JavaScript after a server-side call. What this means is that the server creates a JSON literal, the JavaScript function retrieves it and then converts it into a JavaScript object by the eval function:
var data = eval( "(" + JSON-literal + ")" );
After that, we can access data as a JavaScript object like this (respectively):
data.x, data.y -- an object with members x and y
data[0], data[1], ... -- an array
data.z[0], data.z[1] -- an object with array value
data[0].x, data[1].y -- an array of objects
Both Java and JavaScript support a "comma at the end" of the last array element, e.g.
[ 12, "hello", 15 ] is the same as [ 12, "hello", 15, ]
However, Internet Explorer, at least is some versions, appears to put an extra null at the end of array in the latter case. So it's better to avoid the "comma at the end."
XML format is an alternative format for transmitting structured data from a server-side call back to the client. However, the extraction of the structured information from the XML literal is significantly slower than a JSON literal, and JSON is generally preferred over XML for reasons both of efficiency and simplicity. In retrospect "AJAX" probably should have been "AJAJ"; however the former definitely sounds cooler.
jQuery Preliminaries
The jQuery package has the advantage of being usable without having to modify the HTML, thus most jQuery JavaScript code can be introduced through external script files. The only requirement of the HTML code is that key elements specify certain attributes, of which, the most basic being the id attribute (which would be the case for any JavaScript usage).
In particular, we can avoid the insertion of JavaScript code in the handler attributes (onclick, onsubmit, onchange, etc). The definitions of the handler attributes can be effected all through jQuery code outside the document's body.
According to the jQuery usage logic, all the event-handling definitions are enclosed within the structure:
$(document).ready(
function() {
...
}
)
meaning, when the document is ready, call the function to effect certain actions. jQuery and other toolkits make heavy usage of these "anonymous" functions which do something when an event takes place.
The "$" is actually the special jQuery object from which everything else is based. This seems odd, but $ is actually a legal identifier character in JavaScript, and thus $ by itself is a legal identifier, along with others like $x, x$, $x$y, etc.
The next jQuery notational convenience is that the above can expressed and rewritten as this:
$( function() {
...
})
It may look a bit too compact, but the crunched syntax "})" actually works well with NetBeans formatter.
Identifying HTML elements
An element's id attribute is commonly used in JavaScript in conjuction with the expression:
var elt = document.getElementById("elt_id")
The jQuery equivalent is the expression:
$("#elt_id")
which retrieves a certain jQuery object from which we can express operations. If you know CSS notation, the "#" is actually a perfect choice for the designator prefix. Although we do not need more than this, jQuery also makes it easy to effect operations on a set of elements. Specifically the expression
$(".some_class")
is an object from which we can effect changes to all elements which define:
class="some_class"
Handling an onclick event
A very common situation is to activate some JavaScript code, like an AJAX call when the user clicks a button or hyperlink. The way jQuery expresses this is by the code:
$(function() {
$("#clicker_id").click(function() {
...
})
})
The JavaScript onclick event is turned into the jQuery click function. As with "onload", the argument passed to the click function is a function which will be executed when the onclick event happens.
In the case of hyperlink clicking, jQuery usually wants to "take control" of the actions and so must prevent the hyperlink's default behavior. The is done very cleanly by realizing the event argument passed to the click function as follows:
$(function() {
$("#clicker_id").click(function(evt) {
evt.preventDefault()
...
})
})