Site Archive (Complete)
Email
Print
Reprint

add to:
Del.icio.us
Digg
Google
Spurl
Slashdot
Y! MyWeb
Blink
Furl
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
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
    NetSeminar
    Fully Utilize Embedded Hardware Potential and Create Advanced User Interfaces Fast
    Processing power and display capabilities previously limited embedded system development. Now larger, full-color displays and powerful hardware running advanced operating systems are affordable. To take advantage of this new opportunity high level programming is required. Learn how with a complete set of tools, such as Trolltech's C++ development framework, fully utilizing hardware potential and creating advanced user interfaces can be achieved quickly and efficiently. Event Date: Wednesday, May 28, 2008
    Amp Up Your Continuous Integration Builds
    Amp up your continuous integration build process by increasing the frequency of your build loop. Learn from experts how to create a build that can quickly adapt to source code changes and drive down build times from hours to minutes. Event Date: Thursday, May 22, 2008
    Become a Better Build Detective: Effective Techniques for Debugging Makefiles
    This Webcast will uncover some of the most common Makefile errors and provide specific, proven techniques for fixing them. If command or syntax errors have been a mystery for you, this is a discussion you won't want to miss. Event Date: Wednesday, May 28, 2008
                                   

    ♦ sponsored
    EVENTS

    July 21-24, 2008
    Chicago, IL
    Find real-world solutions to your biggest software architecture challenges at Architecture & Design World 2008. Register by June 20 and save up to $300!
    The Dobbs Challenge
    THE DOBBS CHALLENGE
    Download the Dr. Dobbs Challenge game for either Windows or Windows Mobile and modify it using Visual Studio 2008. Win $10,000!
    INFO-LINK

    Resource Links:




    Related Sites: DotNetJunkies, SD Expo, SqlJunkies