YOUR FEEDBACK
More on the Software Assembly Question - Do Design Patterns Help?
Yanic wrote: Hi, > UML and MDA are being changed to be more data and doc...
SOA World Conference
Virtualization Conference
$50 Savings Expire May 23, 2008... – Register Today!

SYS-CON.TV

2007 West
GOLD SPONSORS:
Active Endpoints
Your SOA Needs BPEL for Orchestration
BEA
Virtualized SOA: Adaptive Infrastructure for Demanding Applications
Nexaweb
Overcoming Bandwidth Challenges with Nexaweb
TIBCO
What is Service Virtualization?
SILVER SPONSORS:
WSO2
Using Web Services Technologies and FOSS Solutions
Click For 2007 East
Event Webcasts

2008 East
PLATINUM SPONSORS:
Appcelerator
Think Fast: Accelerate AJAX Development with Appcelerator
GOLD SPONSORS:
DreamFace Interactive
The Ultimate Framework for Creating Personalized Web 2.0 Mashups
ICEsoft
AJAX and Social Computing for the Enterprise
Kaazing
Enterprise Comet: Real–Time, Real–Time, or Real–Time Web 2.0?
Nexaweb
Now Playing: Desktop Apps in the Browser!
Sun
jMaki as an AJAX Mashup Framework
POWER PANELS:
The Business Value
of RIAs
What Lies Beyond AJAX?
KEYNOTES:
Douglas Crockford
Can We Fix the Web?
Anthony Franco
2008: The Year of the RIA
Click For 2007 Event Webcasts
TOP THREE LINKS YOU MUST CLICK ON


Real-World AJAX Book Preview: The Code

Digg This!

This content is reprinted from Real-World AJAX: Secrets of the Masters published by SYS-CON Books. To order the entire book now along with companion DVDs for the special pre-order price, click here for more information. Aimed at everyone from enterprise developers to self-taught scripters, Real-World AJAX: Secrets of the Masters is the perfect book for anyone who wants to start developing AJAX applications.

The Code
The AjaxWord client consists of JavaScript and HMTL code. The application's user interface is defined in HTML. Client-side logic written in JavaScript defi nes the behavior of the user interface by leveraging a generic JavaScript/DHTML toolkit that's built from scratch. From a Model-View-Controller perspective, the HTML files are "Views" and the JavaScript code acts as "Controllers."

The JavaScript/DHTML toolkit defi nes all the UI widgets. By separating UI widgets from the application, it's easier to develop and maintain the application code. Because of the level of richness required by AjaxWord and the limited availability of AJAX toolkits in the late 1990s, this entire toolkit was written from scratch. It would have been easier to build AjaxWord today by leveraging some of the available toolkits that have emerged in the last 12 months.

A Generic DHTML/JavaScript Toolkit
The AjaxWord DHTML/JavaScript toolkit is a generic toolkit that contains a list of rich user interface components, event management, and code for doing asynchronous communications.

In Figure 15.10, the left items are available with Web browsers. All other items aren't available in browsers and have to be built from scratch. In addition to UI elements, the toolkit provides a systematic way of managing UI events and doing asynchronous communications. When the application was written, the popular XmlHttpRequest object wasn't available in browsers, so AjaxWord actually uses hidden frames to asynchronously communicate.

Instead of elaborating on how each component is built, we will use the "window" object as an example. The window object that we are referring to is a draggable, resizable window that resides inside a standard browser window, giving the look-and-feel of a multiple document interface. It is a basic component for desktop application user interfaces, but isn't available for Web applications.

Creating a "Window" Widget

Figure 15.11 shows how an AjaxWord UI Toolkit window is running inside a browser alongside some HTML text. We'll explain how to define its view and its behavior below.

Defining the View
The view is defined using HTML. To mimic a window look, the view defines 14 different areas of a "window" user interface: the four corners, the four edges, the window content, the title bar, and the four window control areas (close, maximize, minimize, and the window icon). Figure 15.12 shows how a window user interface is split into 14 different regions.

Each window area is defined by a "DIV" tag. For the four corners and four edges, each DIV tag contains an image. Each of the four window controls also contain an image. When necessary, these images can be changed according to style requirements. Some of DIV tags have event handlers defined too so that the window can respond to events. The view definition code is shown in Listing 15.1.

Listing 15.1

<DIV ID="wctl" onmousedown=_nwWindowMouseDown(this)
   onselectstart="event.cancelBubble=true;return true;"
  STYLE="BACKGROUND-IMAGE: url(../images/corner-tl.gif); CLIP: rect(0px 16px 16px 0px);
CURSOR: move; HEIGHT: 16px; LEFT: 0px; POSITION: absolute; TOP: 0px; VISIBILITY: visible;
WIDTH: 16px; repeat: no"></DIV>
<DIV ID="wctr" onmousedown=_nwWindowMouseDown(this)
   onselectstart="event.cancelBubble=true;return true;"
   STYLE="BACKGROUND-IMAGE: url(../images/corner-tr.gif); CLIP: rect(0px 16px 16px 0px);
CURSOR: move; HEIGHT: 16px; LEFT: 284px; POSITION: absolute; TOP: 0px; VISIBILITY:
visible; WIDTH: 16px; repeat: no"></DIV>
<DIV ID="wcbl" onmousedown=_nwWindowMouseDown(this)
   onselectstart="event.cancelBubble=true;return true;"
   STYLE="BACKGROUND-IMAGE: url(../images/corner-bl.gif); CLIP: rect(0px 16px 16px 0px);
CURSOR: move; HEIGHT: 16px; LEFT: 0px; POSITION: absolute; TOP: 184px; VISIBILITY:
visible; WIDTH: 16px; repeat: no"></DIV>
<DIV ID="wcbr" onmousedown=_nwWindowMouseDown(this)
   onselectstart="event.cancelBubble=true;return true;"
   STYLE="BACKGROUND-IMAGE: url(../images/corner-br.gif); CLIP: rect(0px 16px 16px 0px);
CURSOR: move; HEIGHT: 16px; LEFT: 284px; POSITION: absolute; TOP: 184px; VISIBILITY:
visible; WIDTH: 16px; repeat: no"></DIV>
<DIV ID="wEdgeLeft" onmousedown=_nwWindowMouseDown(this)
   onselectstart="event.cancelBubble=true;return true;"
   STYLE="BACKGROUND-IMAGE: url(../images/border-v.gif); CLIP: rect(0px 6px 168px 0px);
CURSOR: w-resize; HEIGHT: 168px; LEFT: 0px; POSITION: absolute; TOP: 16px; VISIBILITY:
visible; WIDTH: 6px; repeat: yes"></DIV>
<DIV ID="wEdgeTop" onmousedown=_nwWindowMouseDown(this)
   onselectstart="event.cancelBubble=true;return true;"
   STYLE="BACKGROUND-IMAGE: url(../images/border-h.gif); CLIP: rect(0px 268px 6px 0px);
CURSOR: n-resize; HEIGHT: 6px; LEFT: 16px; POSITION: absolute; TOP: 0px; VISIBILITY:
visible; WIDTH: 268px; repeat: yes"></DIV>
<DIV ID="wEdgeBtm" onmousedown=_nwWindowMouseDown(this)
   onselectstart="event.cancelBubble=true;return true;"
   STYLE="BACKGROUND-IMAGE: url(../images/border-h.gif); CLIP: rect(0px 268px 6px 0px);
CURSOR: s-resize; HEIGHT: 6px; LEFT: 16px; POSITION: absolute; TOP: 194px; VISIBILITY:
visible; WIDTH: 268px; repeat: yes"></DIV>
<DIV ID="wEdgeRight" onmousedown=_nwWindowMouseDown(this)
   onselectstart="event.cancelBubble=true;return true;"
   STYLE="BACKGROUND-IMAGE: url(../images/border-v.gif); CLIP: rect(0px 6px 168px 0px);
CURSOR: e-resize; HEIGHT: 168px; LEFT: 294px; POSITION: absolute; TOP: 16px; VISIBILITY:
visible; WIDTH: 6px; repeat: yes"></DIV>
<iframe id="wContentFrame" NAME="wContentFrame"
   STYLE="BACKGROUND-COLOR: #76efb1; CLIP: rect(0px 288px 142px 0px); HEIGHT: 142px;
LEFT: 6px; POSITION: absolute; TOP: 31px; VISIBILITY: visible; WIDTH: 288px"
   SRC="about:blank"></iframe>
<DIV ID="wTitleBar"
   onselectstart="event.cancelBubble=true;return false;"
   STYLE="CLIP: rect(0px 288px 24px 0px); CURSOR: default; HEIGHT: 24px; LEFT: 6px; POSITION:
absolute; TOP: 6px; VISIBILITY: visible; WIDTH: 288px">
<DIV ID="wClose" onmouseup="_nwWindowMouseDown(this)"
   title="click here to close the window"
   STYLE="CLIP: rect(0px 20px 20px 0px); HEIGHT: 20px; LEFT: 268px; POSITION: absolute;
TOP: 0px; VISIBILITY: visible; WIDTH: 20px"><A
   href="JavaScript://"><IMG border=0 id=wCloseImg
   onselectstart="event.cancelBubble=true;return false;"
   src="../images/close0.gif" width="20" height="20"></img></a></DIV>
<DIV ID="wMax" onmouseup="_nwWindowMouseDown(this)"
   title="click here to maximize the window"
   STYLE="CLIP: rect(0px 20px 20px 0px); HEIGHT: 20px; LEFT: 248px; POSITION: absolute;
TOP: 0px; VISIBILITY: visible; WIDTH: 20px"><A
   href="JavaScript://"><IMG border=0 id=wMaxImg
   onselectstart="event.cancelBubble=true;return false;"
   src="../images/max0.gif" width="20" height="20"></a></DIV>
<DIV ID="wMin" onmouseup="_nwWindowMouseDown(this)"
   title="click here to minimize the window"
   STYLE="CLIP: rect(0px 20px 20px 0px); HEIGHT: 20px; LEFT: 228px; POSITION: absolute;
TOP: 0px; VISIBILITY: visible; WIDTH: 20px"><A
   href="JavaScript://"><IMG border=0 id=wMinImg
   onselectstart="event.cancelBubble=true;return false;"
   src="../images/min0.gif" width="20" height="20"></a></DIV>
<nobr>
<DIV ID="wTitle" onselectstart="event.cancelBubble=true;return false;"
   STYLE="CLIP: rect(0px 208px 24px 0px); FONT-FAMILY: Arial; FONT-SIZE: 14px; FONTWEIGHT:
bold; HEIGHT: 24px; LEFT: 20px; POSITION: absolute; TOP: 0px; VISIBILITY: visible;
WIDTH: 208px"> <SPAN
   ID="wTitleText" onselectstart="event.cancelBubble=true;return false;">Loading...</
SPAN></DIV>
</nobr>
<DIV ID="wIcon"
   STYLE="CLIP: rect(0px 20px 20px 0px); HEIGHT: 20px; LEFT: 0px; POSITION: absolute;
TOP: 0px; VISIBILITY: visible; WIDTH: 20px"><A
   href="JavaScript://"><IMG border=0 id=wIconImg
   onselectstart="event.cancelBubble=true;return false;"
   src="../images/icon.gif" width="20" height="20"></a></DIV>
</DIV>
<DIV ID="wTitleSep"
   STYLE="BACKGROUND-COLOR: #62659c; CLIP: rect(0px 288px 1px 0px); CURSOR: default;
HEIGHT: 1px; LEFT: 6px; POSITION: absolute; TOP: 30px; VISIBILITY: visible; WIDTH:
288px"></DIV>
<nobr>
<DIV ID="wStatus" onselectstart="event.cancelBubble=true;return false;"
   STYLE="BACKGROUND-COLOR: #e2e2e2; CLIP: rect(0px 288px 20px 0px); CURSOR: default;
FONT-FAMILY: Arial; FONT-SIZE: 12px; HEIGHT: 20px; LEFT: 6px; POSITION: absolute; TOP:
174px; VISIBILITY: visible; WIDTH: 288px"> <SPAN
   ID="wStatusText" onselectstart="event.cancelBubble=true;return false;">Status</SPAN></
DIV>
</nobr>
<DIV ID="wStatusSep"
   STYLE="BACKGROUND-COLOR: #62659c; CLIP: rect(0px 288px 1px 0px); HEIGHT: 1px; LEFT:
6px; POSITION: absolute; TOP: 173px; VISIBILITY: visible; WIDTH: 288px"></DIV>

Defining the Controller
The controller logic of a window widget is defined using JavaScript. The JavaScript file "NWindow.js" is one of the controllers that define the basic behavior of a window widget.

Window Initialization
When a window is created, "NWindow.js" initializes it by connecting the JavaScript object with the "view" object (HTML code), hooking up event handlers and initializing object properties. Here is the initialization code:

Listing 15.2

function NWindow(title,parentLayer,x,y,w,h,pwin,windowDefinitionFile)
{
   this.jPanel=JPanel;
   this.jPanel(parentLayer,x,y,w,h,null,true,null,true,true,pwin);
   objectManager.add(this);

   if(!windowDefinitionFile)
     windowDefinitionFile="../client_lib/windowTemplate.html";
   this.load(windowDefinitionFile);

   this.title=title;
   this.titleBarHeight=24;
   this.statusBarHeight=20;
   this.statusText="Copyright(C)1996-2005, Coach Wei (<a href='http://www.coachwei.
com'>blog</a>). Open Source licensed.";
   this.borderWidth=6;
   this.iconWidth=20;
   this.iconLength=200;
   this.iconized=false;
   this.winIcon="../images/icon.gif";
   this.corner=16;
   this.separator=1;
   this.color = new Object();
   this.color.titleUnfocused = '#cdceff';
   this.color.titleFocused='#00ffff';
   this.color.iconFocused='#aaffff';
   this.color.iconUnfocused="#bbbbbb";
   this.color.tileTextUnfocused="menu";
   this.color.titleTextFocused="highlighttext";
   this.className="NWindow";
   this.initWindow=_nWindowInitWindow;
   this.onMouseDown=_nwWindowMouseDown;
   this.onMouseUp=_nWindowOnMouseUp;
   this.onFocus=_nWindowOnFocus;
   this.onBlur=_nWindowOnBlur;
   this.repaintResize=_nWindowRePaintResize;
   this.addToTaskbar=_nWindowAddToTaskbar;
   this.startResize=_nwWindowStartResize;
   this.resize=_nWindowSetSize;
   this.iconize=_nWindowIconize;
   this.onClose=_nWindowOnClose;
   this.onMaximize=_nWindowOnMaximize;
   this.onMinimize=_nWindowOnMinimize;
   this.setTitle=_nWindowSetTitle;
   this.setIcon=_nWindowSetIcon;
   this.setStatus=_nWindowSetStatus;
   this.sizeContent=_nWindowSizeContent;
   this.loadContent=_nWindowLoad;
   this.getWindowSize=_getBrowserWindowSize;
}

function _nWindowInitWindow(win)
{
   if(!win||!win.document) return;
   this.doc=win.document;
   this.wctl=this.getJPanelFor("wctl",win);
   this.wctl.domObj.parentCtrl=this;
   this.wctr=this.getJPanelFor("wctr",win);
   this.wctr.domObj.parentCtrl=this;
   this.wcbr=this.getJPanelFor("wcbr",win);
   this.wcbr.domObj.parentCtrl=this;
   this.wcbl=this.getJPanelFor("wcbl",win);
   this.wcbl.domObj.parentCtrl=this;
   this.wEdgeTop=this.getJPanelFor("wEdgeTop",win);
   this.wEdgeTop.domObj.parentCtrl=this;
   this.wEdgeBtm=this.getJPanelFor("wEdgeBtm",win);
   this.wEdgeBtm.domObj.parentCtrl=this;
   this.wEdgeLeft=this.getJPanelFor("wEdgeLeft",win);
   this.wEdgeLeft.domObj.parentCtrl=this;
   this.wEdgeRight=this.getJPanelFor("wEdgeRight",win);
   this.wEdgeRight.domObj.parentCtrl=this;
   this.wTitleBar=this.getJPanelFor("wTitleBar",win);
   this.wTitleBar.domObj.parentCtrl=this;
   this.wIcon=this.getJPanelFor("wIcon",win);
   this.wTitle=this.getJPanelFor("wTitle",win);
   this.wTitle.domObj.parentCtrl=this;
   this.wClose=this.getJPanelFor("wClose",win);
   this.wClose.domObj.parentCtrl=this;
   this.wMax=this.getJPanelFor("wMax",win);
   this.wMax.domObj.parentCtrl=this;
   this.wMin=this.getJPanelFor("wMin",win);
   this.wMin.domObj.parentCtrl=this;
   this.wTitleSep=this.getJPanelFor("wTitleSep",win);
   this.wStatus=this.getJPanelFor("wStatus",win);
   this.wStatusSep=this.getJPanelFor("wStatusSep",win);
   this.wContent=this.getJPanelFor("wContentFrame",win,false,true);
   if(this.wContent.domObj) this.wContent.domObj.parentCtrl=this;
   this.wTitleText=win.document.all["wTitleText"];
   this.wStatusText=win.document.all["wStatusText"];
   this.wIconImg=win.document.all["wIconImg"];
   this.setDragable(true);
   top.dragManager.setGrab(this,this.borderWidth,this.borderWidth,this.getWidth()-
3*this.iconWidth-2*this.borderWidth,this.titleBarHeight);
   if(this.resize) this.resize(this.w,this.h);
   if(top._initSystemEvent)
   {
     top._initSystemEvent(win);
     top._initSystemEvent(this.wContent.iframe.frame);
   }
}

This content is reprinted from Real-World AJAX: Secrets of the Masters published by SYS-CON Books. To order the entire book now along with companion DVDs, click here to order.

About Coach Wei
Coach Wei is the founder and CTO of Nexaweb (www.nexaweb.com), developers of the leading software platform for building and deploying Web 2.0 and AJAX applications. Previously, Coach played a key role at EMC Corporation in the development of a new generation of storage network management software. Coach has his master's degree from MIT, holds several patents, is the author of several technology publications including JDJ, Web 2.0 Journal, and AJAXWorld Magazine, and is an industry advocate for the proliferation of open standards.

LATEST AJAXWORLD STORIES
3rd International Virtualization Conference & Expo: Themes & Topics
From Application Virtualization to Xen, a round-up of the virtualization themes & topics being discussed in NYC June 23-24, 2008 by the world-class speaker faculty at the 3rd International Virtualization Conference & Expo being held by SYS-CON Events in The Roosevelt Hotel, in mi
AJAX World - You've Heard of Widgets, But What Are Woodgets?
DreamFace DataWidgets have gotten a lot of press lately, but what are Woodgets? DreamFace Interactive CEO, Olivier Poupeney gets specific about woodgets while presenting key differentiators of DreamFace's Web 2.0 Open Source Framework in his interview with Jeremy Geelan for SYS-C
JavaOne 2008: Sun Talks Up its Late-to-the-Party AIR-Silverlight Rival
At Java One this week Sun has been selling its year -old-but-still-upcoming - and definitely late-to-the-party - Adobe AIR- and Microsoft Silverlight-competitive JavaFX Rich Client environment as a potential revenue-generator capable of putting ads on mobile applications and JavaF
Payless Car Rental Launches iPhone and iPod Touch Portal
Payless Car Rental has launched an iPhone and iPod Touch optimized website. Payless Car Rental is a car rental agency that built a customized version of its website for the iPhone and iPod Touch. The homepage of Payless' iPhone interface also features a 'Call to Book' button that
Alpha Five Platinum Brings AJAX to the Enterprise
Alpha Software is now shipping Alpha Five Platinum Edition, the ninth release of the company's flagship Web database development platform. It's a development tool that can visually build AJAX-powered applications, integrate SQL databases with drag+drop simplicity, and deliver ent
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS
SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
Click to Add our RSS Feeds to the Service of Your Choice:
Google Reader or Homepage Add to My Yahoo! Subscribe with Bloglines Subscribe in NewsGator Online
myFeedster Add to My AOL Subscribe in Rojo Add 'Hugg' to Newsburst from CNET News.com Kinja Digest View Additional SYS-CON Feeds
Publish Your Article! Please send it to editorial(at)sys-con.com!

Advertise on this site! Contact advertising(at)sys-con.com! 201 802-3021

SYS-CON FEATURED WHITEPAPERS

ADS BY GOOGLE