MAJAX - The Millennium AJAX Library

Copyright 2006-2007 by Godmar Back and Annette Bailey (, Virginia Tech.

License: This software is released under the LGPL license, See

$Id: majax.html,v 1.25 2008/02/16 17:45:47 gback Exp gback $

Two files: this file, majax.html and the file majax.js must be uploaded to your Millennium installation's /screens directory. Subsequently, the functionality it provides can be used on any page that is served from within the same domain. In particular, MAJAX can be used from within the Millennium results pages, or the pages created by WebBridge, or any other static or dynamic web page served by a server in your domain.

MAJAX should automatically determine the correct domain based on where the file is located. For instance, if located in, MAJAX would allow access from all pages in the * domain. Using the automatic domain detection, this copy of MAJAX would allow access from all pages from within the domain. (The domain on the previous line shown in green should show your domain after you copied majax.html to your /screens directory.) MAJAX cannot be used by any webpage outside this domain, because of the same-origin restriction inherent in the JavaScript security model.

Some people may wonder why we are using AJAX and this hidden iframe, rather than dynamic <script> tags. The answer is that MAJAX does not want to rely on any server-side support other than the ability to upload majax.js and majax.html to III's server.

MAJAX was tested with Firefox 1.5.0.* and FF 2.0.* and IE 6.0.2 and IE 7.


To use MAJAX in a page, simply include the following <script> element in the <head></head> section of your webpage:

 <script type="text/javascript" src="http://your.millennium.domain/screens/majax.js">

Replace the your.millennium.domain with the hostname of your Millennium installation.

That's it! Now you can use make use of MAJAX on your webpage.

There are two ways in which to use MAJAX. The first way is recommended for most users. It does not require any Javascript coding. Instead, in those places where you want MAJAX to insert information from the catalog, place HTML <span> elements. For example:

 ISBN: 0743226712 <span class="majax-showholdings" title="i0743226712"></span>

When this page is loaded, MAJAX will insert a note that shows the holdings for the book with ISBN 0743226712. The output may look like this:

ISBN: 0743226712 (2 copies held: AVAILABLE AVAILABLE)

No Javascript code is required: simply place appropriate <span> tags in your document. MAJAX will replace them with information from the catalog. Use the class and the title attributes to specify what information should be shown.

MAJAX supports the following options for these attributes.

  1. ISBN search: use title="iXXXXXXXXXX" and replace XXXXXXXXXX with the ISBN for which to search.
  2. Bibrecord search: use title=".bYYYYYYYY" and replace YYYYYYY with the record number for which to search. Note the dot before the 'b'.
  3. Title search: use title="tzzzzzzzz" and replace zzzzzzzzz with a book title. Use %20 for spaces.
  4. OCLC number search: use title="onnnnnn" and replace nnnnnnn with the OCLC number. This will only be successful if the OCLC number is listed in 001$a.
To determine which information is displayed include one of the following strings in the class attribute:
Shows how many copies are listed in the catalog, and their current status.
Includes a preformatted textbox that can be copied and pasted into Endnote
Like majax-endnote, except textbox can be shown/hidden by clicking on a link.
Displays a link that can be directly imported into Endnote.
Displays a citation of the item in Harvard reference style.
Send us requests/ideas for others.

Styling MAJAX

You may, optionally, apply a CSS style by specifying CSS style rules for the existing styles.

 .majax-showholdings {
     font-weight: bold;
     color: red;

would show all holdings information in bold red.

You can also provide additional classes for the MAJAX <span> tag's class attribute. For instance, <span class="showitalic majax-showholdings" ....> ... would also apply the style rules associated with class "showitalic" to the holdings information. In this way, you may apply different styles to different span elements.

The documentation below refers to how to use MAJAX from JavaScript.

MAJAX can only be used after it has finished loading. You can associate a handler that is called when MAJAX finishes loading by calling


from anywhere in the document. Note that the <body> element's onload handler cannot be used. (The reason is that this handler is used to start loading the inner majax frame; MAJAX is only available after this inner frame has finished loading.)

Calling majaxProcessSpans() will process new span elements. It ensures that each span element is only processed once.

MAJAX Functions

MAJAX provides the following functions, which can be accessed as methods of the frame object in the embedding page, e.g., using the dot notation as in 'majax.majaxSearchByISBN'.

 majaxSearchByISBN(isbn, majaxRequest);

 majaxSearchByTitle(title, majaxRequest);


a boolean. If true, MAJAX will open a new window on every request that display the URL MAJAX is requesting from Millennium. Provided for debugging.
of type string is the ISBN for which to look. This search uses the 'i' index of Millennium and looks up and parses the MARC record for the item found.
of type string is the title for which to look. As with ISBN, the MARC record is looked up.
of type function. The function 'majaxRequest.onsuccess(majaxresult)' is called if a MARC record was found and successfully parsed. 'majaxresult' is a JavaScript object that contains the information MAJAX obtained from Millennium. 'majaxresult' has the following properties:

endnotestringA string that contains a representation suitable for export into EndNote.
endnoteerrorstringIf an error occurred during the creation of the 'endnote' property, the 'endnote' property is not set and this property is set instead.
marcobjectcontains the parsed MARC record. See below.
holdingsarray of strings Entries in the array correspond to the holdings status of the available copies of an item, e.g. "DUE xx-xx-xxxx", or "AVAILABLE", etc.
recordurlstringA URL to the catalog record describing this item.
bibscreenstring The original HTML of the so-called BIBSCREEN extracted from the MARC display. This is usually a section with a table that describes the holdings. Provided for debugging mainly.
marctextstringThe original MARC record as extracted from the MARC display. Provided for debugging.
majaxMakeEndnoteDisplay()functionWhen called, this function creates a hidable PRE element in which the EndNote reference is displayed. The element can be inserted anywhere on the page. See below for more information.
majaxMakeHarvardReference()function When called, this function creates an string of HTML that display a formatted reference according to Harvard-style (Author-Date). The string can be inserted anywhere on the page, for instance by assigning it to an innerHTML property of a known SPAN element. See below for more information.

of type function. If present, the method 'majaxRequest.onfailure(status)' is called if either the request failed or the ISBN or title was not found. status is 200 if the request succeeded, but Millennium returned a different MARC record; else status is 404. Millennium tends to return neighboring records if a specific title or ISBN is not found. MAJAX checks whether the returned record matches the query by examing MARC fields 020$a for ISBN and 245$a for title searches.

A typical example of success/failure callbacks might look like this:

 function successCallback(majaxresult) 
   // see below for documentation for majaxMakeHarvardReference()
   var h = document.getElementById("harvardref");
   h.innerHTML = majaxresult.majaxMakeHarvardReference();

 function failureCallback(status) 
    // handle failure case here

 majax.majaxSearchByISBN(isbn, {
        onsuccess : function (result) {
        onfailure: function (status) { 

 function majaxMakeEndnoteDisplay(doc, labelHTML, showText, hideText, preclass)

Returns a DIV element that can be inserted into document 'doc'. The DIV element is laid out as if it had been created with the following HTML:
        <pre class="preclass">
     This is where the EndNote display would go

Below is shown what the result of this call may look like in the target webpage. Press the "Show" link to see.

Note 1: you must specify the target 'document' as an argument to this call. Simply passing 'document' should work in most cases.

Note 2: any HTML that can be assigned via innerHTML to the created SPAN document can be used as labelHTML.

Note 3: this function is a method of the MAJAX results object. Therefore, a typical calling sequence, which would be included inside a "success" callback function, might be this:

  * This example assumes that the target document contains HTML like this:
  * <FORM name="laurel215_form">
  * </FORM>
  * we want to add the EndNote display at the end of the area enclosed
  * by the FORM element, i.e., as its last child.

 var f = document.forms["laurel215_form"];      
 // 'f' represents the location on the target page where the div should be inserted

 var endnotediv = majaxresult.majaxMakeEndnoteDisplay(document, "Endnote", "Show", "Hide");

 // now place created div as the last child of the target element

 function majaxMakeHarvardReference()

Create a string that represents an HTML representation of the reference, formatted in so-called Harvard reference style. This is an example of what it may look like in the target webpage:

Levitt, Steven D., Dubner, Stephen J., 2005, Freakonomics : a rogue economist explores the hidden side of everything / 1st ed., New York, William Morrow, xii, 242 p. ;

A typical use would look like this:

  * This example assumes that the target document contains HTML like this:
  * <SPAN id="harvardref"></SPAN>
  * we want to insert the reference where the (otherwise invisible)
  * SPAN element is located

 var h = document.getElementById("harvardref");
 h.innerHTML = majaxresult.majaxMakeHarvardReference();

The code above would typically be included inside a "success" callback function.

Currently, majaxMakeHarvardReference() includes the following fields, if present: 100$a, all 700$a fields, 260$c, 245$a, 245$b, 250$a, 260$a, 260$b, 300$a.

MAJAX's MARC Representation

MAJAX retrieves a MARC record from the Millennium catalog. The MARC record is represented as a JavaScript object. This object is stored in the 'marc' property of the result object passed to the callback function. This marc object has the following properties.

For each MARC field found, there is a property datafieldNNN that is an array that corresponds to the NNN data fields found in the record. For instance, marc.datafield650[0] points to the first 650 field found in the MARC record, marc.datafield650[1] points to the second 650 field found in the MARC record, and so on. marc.datafield650.length gives the number of 650 fields. The alias marc.f650 is created as a shortcut for marc.datafield650[0]. Similarly, marc.f100 is an alias for marc.datafield100[0], which points to the first---and presumably only--- 100 data field in the MARC record. Note that both marc.f100 and the marc.datafield100 array are undefined if there is no 100 data field in the MARC record.

Each MARC field instance is a JavaScript object with the following properties. The properties ind1 and ind2 refer to the indicators associated with the MARC record. The property subfields is an object that points to an array of subfields. It is indexed by the subfield code, e.g., 'a', 'b', etc. For instance, marc.f776.subfields['w'] is an array of $w subfields within the first 776 data field. The actual fields are marc.f776.subfields['w'][0], marc.f776.subfields['w'][1] and so on. A shortcut is provided for the first subfield of a given subfield code. For instance, marc.f020.a is short for marc.f020.subfields['a'][0], which is shorthand for marc.datafield020[0].subfields['a'][0], which is the first $a subfield within the first 020 data field --- typically the ISBN. Consequently, the following JavaScript code can be used to check for the existence of a 020$a field in the MARC record:

 if (marc.f020 && marc.f020.a)
     alert('record contains ISBN: ' + marc.f020.a);

Note that you have to check for marc.f020 before checking for marc.f020.a since if the MARC record did not contain a 020 data field, then attempting to access marc.f020.a will trigger an exception, aborting the current function. (A try/catch statement could be used to catch the exception and continue.)

Implementation Notes: Control fields (001--008) and data fields are treated alike for simplicity.

Subfields without an implicit subfield code are assumed to use subfield code $a (is this correct?).

The indicators are preserved as they appear in the record; in particular an empty indicator is a space.