FREE Subscription to Dr. Dobb’s Digest: Same Great Content, New Digital Edition
Site Archive (Complete)
Email
Print
Reprint

add to:
Del.icio.us
Digg
Google
Furl
Slashdot
Y! MyWeb
Blink
January 01, 2002
The DOM in Version 5 Browsers

(Page 1 of 3)

WebReview.com: JavaScript for the MVC example

June 18, 1999 Issue > Browsers

JavaScript for the MVC example

By Mitch Gould

The DOM in Version 5 Browsers

Let's look at the JavaScript that runs our example. In studying mvctable.js, a veteran DHTML coder will find some surprises due to its use of the new DOM.

/*
 mvctable.js v0.3 Monday, May 31, 1999
 Mitch Gould - humanfact@generalpicture.com

by Mitch Gould, humanfact@generalpicture.com

This script demonstrates dynamic documents in Netscape
Navigator and Internet Explorer 5 in the following ways:

(a) it exercises W3C's standard Document Object Model API. (b) it creates, modifies, and destroys a table. (c) it partially illustrates the concept of model-view-controller.

(To fully illustrate the MVC concept, modifications made to the data view would need to be propagated back to the data model.)

*/

// A. Data initialization. var datacount = 0 model = new Array()

// Allocate the first dataset, a set of quotations, from this array. arrayquotes = new Array( "Oh dear! I shall be too late.", "Curiouser and curiouser!", "Who are -you-?", "We're all mad here.", "Twinkle, twinkle, little bat.", "Off with her head!", "I make you a present of everything I've said...", "Once, I was a real Turtle.", "Sentence first—verdict afterwards.") // When a link is clicked, the quotations' sources will be revealed // from this array. arraysources = new Array( "White Rabbit", "Alice", "Caterpillar", "Cheshire Cat", "Dormouse", "Red Queen", "Dutchess", "Mock Turtle", "Red Queen")

// B. MVC-DOM methods.

// Establish a new data model and assign it to a new view. function startController() {

// Populate the model with initial data. datamodel = refreshModel(arrayquotes)

// Get the document body element. var docbod = getBody()

/* Create a view in the body of the document and fill it with the initial data. */ createView(docbod, model) }

// Copy the specified dataset into the model. function refreshModel(arraycurrent) {

// Populate the model with the current datastore. for(var i=0; i < arraycurrent.length; i = i + 1) { model[i] = arraycurrent[i] } return model }

/* this could be generalized to provide alternatives to a a table view, such as a select object, a tree, or even a textarea. this sample produces a one-column table. Multi-column tables are more complex. */ function createView(bodyelement, themodel) { table = document.createelement("TABLE") table.border = 1 table.id = "viewtable" tablebody = document.createelement("TBODY") for(var i=0; i < model.length; i++) { currentrow = document.createelement("TR") currentcell = document.createelement("TD") currentcell.appendchild(document.createtextnode(model[i])) currentrow.appendchild(currentcell) tablebody.appendchild(currentrow) } table.appendchild(tablebody) bodyelement.appendchild(table) return table }

// refresh the model first, then the view. function refreshview(dataset) { // populate the model with new data. refreshmodel(dataset)

tablebody = document.getelementsbytagname("TBODY").item(0) var count = 0 replacealltext(tablebody) }

// One can also destroy HTML objects using the DOM. function destroyView() { objecttodestroy = document.getelementbyid("viewtable") body = getbody() body.removechild(objecttodestroy) // now destroy the buttons. objecttodestroy = document.getelementbyid("whosaid") body.removechild(objecttodestroy) objecttodestroy = document.getelementbyid("goaway") body.removechild(objecttodestroy) }

// c. dom tree-navigation and utilities.

/* One must climb the trunk, branches, and twigs to get (or set!) the fruit. The recursive nature of this algorithm reflects an essential fractal nature of documents. */ function replaceAllText(startelem) { // Climb the object tree, replacing its text nodes with // new data. for (var i=0; i < startelem.childnodes.length; i = i + 1) { switch (startelem.childnodes.item(i).nodetype) { case 1: // element nodetype replacealltext(startelem.childnodes.item(i)) break; case 3: // text nodetype if (datacount < model.length) { settext(startelem.childnodes.item(i), model[datacount]) datacount = datacount + 1 } else { settext(startelem.childnodes.item(i)," - ? - ") } break; } //endswitch } //endfor } //endfunction

/* many operations on dynamic documents require one to start from the document's body element. */ function getBody() { if(navigator.appName != "Netscape") { resultelement = document.body; } else { resultelement = document.getelementsbytagname("body").item(0); } return resultelement; }

// utility function to overwrite text nodes. function settext(tagtoset, valuetoset) { tagtoset.nodevalue = valuetoset }

// d. this can't start until the page loads. window.onload = startcontroller

Listing 2. The JavaScript source for mvctable.js.

For the sake of clarity, mvctable.js is divided into four parts:

A. data initialization,
B. MVC-DOM methods,
C. DOM tree-navigation and utilities, and
D. load-event handler.

Section A is simply expected in a script of any size. Here, it sets up the string arrays that contain the Alice quotations and their sources.

The code in the B section provides a way to implement a model-view-controller design pattern using the Document Object Model. This section acts as the controller, initializing the model and view, refreshing the model and view with updated values, and destroying the view upon request.

Section C provides support routines that encapsulate lower-level details of access to document objects. It's a bit disappointing that the DOM doesn't provide standardized access to the document at this level of encapsulation, but once these utility methods are written, they can be reused endlessly. These methods are responsible for navigating the document tree to touch the desired objects, notably in this case, text content that must be replaced.

The D section is required to start the controller as soon as the browser finishes loading the page.

With this background, we're ready to examine the code example. As the page is loading, the browser processes the data initialization section, executing the constructor

 model = new Array()

to create an empty model, and creating two more arrays: arrayquotes and arraysources.

Initializing the controller

Once the page has finished loading, the controller starts.

// This can't start until the page loads entirely. window.onload = startController

The controller transfers the quotes to the model, and creates a new table in the document to act as a view, as shown in Listing 3.

// B. MVC-DOM methods.

// Establish a new data model and assign it to a new view. function startController() {

// Populate the model with initial data. datamodel = refreshModel(arrayquotes)

// Get the document body element. var docbod = getBody()

/* Create a view in the body of the document and fill it with the initial data. */ createView(docbod, model) }

Listing 3. The startController() function.

To understand the functions called by startController(), we must turn to a description of the DOM, which we'll cover in the next section.


JavaScript for the MVC example
Understanding the Document Object Model

1 | 2 | 3 Next Page
TOP 5 ARTICLES
No Top Articles.
DR. DOBB'S CAREER CENTER
Ready to take that job and shove it? open | close
Search jobs on Dr. Dobb's TechCareers
Function:

Keyword(s):

State:  
  • Post Your Resume
  • Employers Area
  • News & Features
  • Blogs & Forums
  • Career Resources

    Browse By:
    Location | Employer | City
  • Most Recent Posts:
    MEDIA CENTER  more
                                   
    INFO-LINK

    Resource Links: