Professional JavaScript Frameworks: Prototype,YUI, ExtJS, Dojo ...

quaggafoulInternet και Εφαρμογές Web

14 Δεκ 2013 (πριν από 3 χρόνια και 7 μήνες)

6.012 εμφανίσεις

www.wrox.com
$49.99 USA
$59.99 CANADA
Wrox Professional guides are planned and written by working programmers to meet the real-world needs of programmers,
developers, and IT professionals. Focused and relevant, they address the issues technology professionals face every day. They
provide examples, practical solutions, and expert education in new technologies, all designed to help programmers do a better job.
Recommended
Computer Book
Categories
Web Development
JavaScript
ISBN: 978-0-470-38459-6
As the needs and demands of developers have evolved over
the years, so has JavaScript, which boasts a track record
of delivering high-performing and exceptionally impressive
web-user experiences. This flexible, dynamic programming
language is increasingly used for serious development on the
web, and several of its tools and projects are being shared in
the form of libraries and frameworks. Packed with coverage
of many of the most popular JavaScript frameworks, this
authoritative guide examines how these frameworks can
present unique and varying approaches to a variety of
problems in web development—each of which has its own
pros and cons.
This unparalleled team of authors has assembled some of
the most active and popular JavaScript frameworks available
and they walk you through common web development tasks
addressed by each framework, while also examining how the
framework approaches a particular set of tasks. In addition,
practical examples and clear explanations demonstrate the
many aspects of contemporary web development and exactly
what the selection of JavaScript frameworks has to offer so
that you can get up and running quickly.
What you will learn from this book
● The Prototype framework: handling cross-browser events,
manipulating common data functions, simplifying AJAX
and dynamic data, and more
● Yahoo! User Interface (YUI) library: using animation and
drag and drop, building user interfaces with widgets,
working with YUI CSS tools, and more
● Ext JS framework: talking with the server, using dataviews
and grids, dealing with form controls and validation, and
more
● The Dojo framework: manipulating the DOM, composing
animators, deploying and expanding Dojo, and more
● The MooTools framework: enhancing development with
MooTools, building user interfaces and using animation,
and more
Who this book is for
This book is for web developers who are eager to explore the
benefits of JavaScript frameworks. A working knowledge of
HTML, CSS, and JavaScript is required.
Orchard
Pehlivanian
Koon
Jones
spine=1.734"
Updates, source code, and Wrox technical support at
www.wrox.com
Leslie M. Orchard, Ara Pehlivanian, Scott Koon, Harley Jones
Professional
Professional
JavaScript
®
Frameworks
Prototype, YUI, Ext JS,
Dojo and MooTools
JavaScript
®
Frameworks
Prototype, YUI, Ext JS, Dojo and MooTools
JavaScript ®
Frameworks
Prototype, YUI, Ext JS, Dojo and MooTools
Professional
Wrox Programmer to Programmer
TM
Wrox Programmer to Programmer
TM
spine=1.734"
Get more out of
WROX.com
Programmer to Programmer

Interact
Take an active role online by participating in
our P2P forums
Wrox Online Library
Hundreds of our books are available online
through Books24x7.com
Wrox Blox
Download short informational pieces and
code to keep you up to date and out of
trouble!
Chapters on Demand
Purchase individual book chapters in pdf
format
Join the Community
Sign up for our free monthly newsletter at
newsletter
.wrox.com
Browse
Ready for more Wrox? We have books and
e-books available on .NET, SQL Server, Java,
XML, Visual Basic, C#/ C++, and much more!
Contact Us.

We always like to get feedback from our readers. Have a book idea?
Need community support? Let us know by e-mailing wrox-partnerwithus@wrox.com
Professional JavaScript® Frameworks
Introduction ...............................................................................................xxv
Part I: Prototype 1
Chapter 1: Extending and Enhancing DOM Elements ........................................3
Chapter 2: Handling Cross-Browser Events ....................................................23
Chapter 3: Simplifying AJAX and Dynamic Data .............................................33
Chapter 4: Working with Forms .....................................................................43
Chapter 5: Manipulating Common Data Structures and Functions ..................53
Chapter 6: Extending Prototype ....................................................................71
Part II: Yahoo! User Interface Library 89
Chapter 7: Traversing and Manipulating the DOM with YUI .............................93
Chapter 8: Handling Cross-Browser Events ..................................................113
Chapter 9: Using Animation and Drag and Drop ..........................................147
Chapter 10: Simplifying AJAX and Dynamic Loading ....................................173
Chapter 11: Building User Interfaces with Widgets (Part I) .........................189
Chapter 12: Building User Interfaces with Widgets (Part II) ........................225
Chapter 13: Enhancing Development with the YUI Core ..............................269
Chapter 14: Dealing with Data, Tables, and Charts .....................................291
Chapter 15: Working with YUI CSS Tools ....................................................317
Chapter 16: Building and Deploying ............................................................329
Part III: Ext JS 335
Chapter 17: Architecture and Library Conventions ......................................337
Chapter 18: Elements, DomHelper, and Templates ......................................351
Continued
ffirs.indd iffirs.indd i 7/22/09 10:05:31 AM
7/22/09 10:05:31 AM
Chapter 19: Components, Layouts, and Windows ........................................373
Chapter 20: Handling Data and Talking with the Server ...............................395
Chapter 21: DataViews and Grids ...............................................................415
Chapter 22: Form Controls, Validation, and a Whole Lot More .....................431
Part IV: Dojo 451
Chapter 23: Enhancing Development with Dojo Core ....................................453
Chapter 24: Manipulating the Dom ..............................................................473
Chapter 25: Handling Events .......................................................................499
Chapter 26: Composing Animations ............................................................525
Chapter 27: Working with Ajax and Dynamic Data .......................................547
Chapter 28: Building User Interfaces with Widgets ......................................595
Chapter 29: Building and Deploying Dojo .....................................................655
Chapter 30: Expanding Dojo ........................................................................663
Part V: MooTools 689
Chapter 31: Enhancing Development with MooTools ....................................691
Chapter 32: Manipulating the Dom and Handling Events ..............................725
Chapter 33: Simplifying Ajax and Handling Dynamic Data .............................763
Chapter 34: Building User Interfaces and Using Animation ...........................787
Index .........................................................................................................835
ffirs.indd iiffirs.indd ii 7/22/09 10:05:32 AM
7/22/09 10:05:32 AM
Professional
JavaScript® Frameworks
Prototype, YUI, Ext JS, Dojo and MooTools
Leslie Michael Orchard
Ara Pehlivanian
Scott Koon
Harley Jones
Wiley Publishing, Inc.
ffirs.indd iii
ffirs.indd iii 7/22/09 10:05:32 AM
7/22/09 10:05:32 AM
Professional JavaScript® Frameworks:
Prototype, YUI, Ext JS, Dojo and MooTools
Published by
Wiley Publishing, Inc.
10475 Crosspoint Boulevard
Indianapolis, IN 46256
www.wiley.com
Copyright © 2009 by Wiley Publishing, Inc., Indianapolis, Indiana
Published simultaneously in Canada
ISBN: 978-0-470-38459-6
Manufactured in the United States of America
10 9 8 7 6 5 4 3 2 1
No part of this publication may be reproduced, stored in a retrieval system or transmitted in any form or by
any means, electronic, mechanical, photocopying, recording, scanning or otherwise, except as permitted
under Sections 107 or 108 of the 1976 United States Copyright Act, without either the prior written
permission of the Publisher, or authorization through payment of the appropriate per-copy fee to the
Copyright Clearance Center, 222 Rosewood Drive, Danvers, MA 01923, (978) 750-8400, fax (978) 646-8600.
Requests to the Publisher for permission should be addressed to the Permissions Department, John Wiley &
Sons, Inc., 111 River Street, Hoboken, NJ 07030, (201) 748-6011, fax (201) 748-6008, or online at
http://www
.wiley.com/go/permissions.
Limit of Liability/Disclaimer of Warranty: The publisher and the author make no representations or
warranties with respect to the accuracy or completeness of the contents of this work and specifically
disclaim all warranties, including without limitation warranties of fitness for a particular purpose. No
warranty may be created or extended by sales or promotional materials. The advice and strategies contained
herein may not be suitable for every situation. This work is sold with the understanding that the publisher is
not engaged in rendering legal, accounting, or other professional services. If professional assistance is
required, the services of a competent professional person should be sought. Neither the publisher nor the
author shall be liable for damages arising herefrom. The fact that an organization or Web site is referred to in
this work as a citation and/or a potential source of further information does not mean that the author or the
publisher endorses the information the organization or Web site may provide or recommendations it may
make. Further, readers should be aware that Internet Web sites listed in this work may have changed or
disappeared between when this work was written and when it is read.
For general information on our other products and services please contact our Customer Care Department
within the United States at (877) 762-2974, outside the United States at (317) 572-3993 or fax (317) 572-4002.
Wiley also publishes its books in a variety of electronic formats. Some content that appears in print may not
be available in electronic books.
Library of Congress Control Number: 2009932978
Trademarks: Wiley, the Wiley logo, Wrox, the Wrox logo, Wrox Programmer to Programmer, and related
trade dress are trademarks or registered trademarks of John Wiley & Sons, Inc. and/or its affiliates, in the
United States and other countries, and may not be used without written permission. JavaScript is a
registered trademark of Sun Microsystems, Inc. All other trademarks are the property of their respective
owners. Wiley Publishing, Inc., is not associated with any product or vendor mentioned in this book.
ffirs.indd ivffirs.indd iv 7/22/09 10:05:32 AM
7/22/09 10:05:32 AM
Many thanks go to my wife, Alexandra, who somehow put up with
me over the last few years’ adventures — of which writing a book was
the least stressful, relatively speaking.
—Leslie Michael Orchard
For my wife, Krista, my daughter Emma, and the new one who’s on the way!
Thanks for your love and support. I couldn’t have done this without you!
—Ara Pehlivanian
I want to thank Kim, Amelia, and Naomi for putting up with all the
late nights banging away on the laptop and I dedicate my work on this book to them.
—Scott Koon
To Marlene, Carolyn, Houston, and my mom.
—Harley Jones
ffirs.indd v
ffirs.indd v 7/22/09 10:05:33 AM
7/22/09 10:05:33 AM
Credits
Acquisitions Editor
Scott Meyers
Development Editor
Kenyon Brown
Technical Editors
Scott Koon
Michael Galloway
Dave Bouwman
Joel Tulloch
Alexei Gorkov
Production Editor
Daniel Scribner
Copy Editor
Mildred Sanchez
Editorial Manager
Mary Beth Wakefield
Production Manager
Tim Tate
Vice President and Executive Group Publisher
Richard Swadley
Vice President and Executive Publisher
Barry Pruett
Associate Publisher
Jim Minatel
Project Coordinator, Cover
Lynsey Stanford
Proofreader
Scott Klemp, Word One
Kyle Schlesinger, Word One
Indexer
Ron Strauss
ffirs.indd viffirs.indd vi 7/22/09 10:05:33 AM
7/22/09 10:05:33 AM
About the Authors
Leslie Michael Orchard is a tinkerer, writer, and serial enthusiast from the Detroit area. He shares his
home with a lovely wife, two spotted Ocicats, and a pair of dwarf bunnies. On rare occasions when spare
time is found, he shares and documents odd bits of code and other interests at a web site called
0xDECAFBAD
(http://decafbad.com)
.
Ara Pehlivanian has been working on the Web since 1997. He’s been a freelancer, a webmaster, and most
recently, a front-end architect and practice lead for Nurun, a global interactive communications agency.
Ara’s experience comes from having worked on every aspect of web development throughout his career,
but he’s now following his passion for web standards-based front-end development. When he isn’t
teaching about best practices or writing code professionally, he’s maintaining his personal site at
http://arapehlivanian.com/.
Scott Koon has been a professional software developer for over 13 years. He spent the majority of his
time in college working with a legacy, undocumented symbolic language (DNA), resulting in a degree in
biochemistry. He’s been writing JavaScript since it was called LiveScript and remembers when Netscape
had a big purple “N” in the upper right-hand corner. He maintains a blog at
http://lazycoder.com

and has been active in the weblogging community for about 10 years. He is often on Twitter at
http://
www.twitter.com/lazycoder
and has contributed to the development of a WPF .NET Twitter client
called Witty. He also cohosts a podcast called Herding Code
(http://www.herdingcode.com)
that
deals with a wide variety of issues in technology. He lives in Seattle, Washington, with his wife and two
daughters, adrift in a sea of pink princesses and other girly things.
Harley Jones is currently a lead technical consultant for Perficient, Inc (NASDAQ: PRFT). He graduated
from Oglethorpe University in Atlanta, Georgia with an English literature degree but has been
programming since he was 10 years old. He has been developing software professionally for more than
10 years and literally consumes programming languages. He actively supports and mentors almost
anyone serious in learning modern programming techniques. When not programming, he can be found
molding his children into evil scientists. Harley can be reached at
harley.333@gmail.com.
ffirs.indd viiffirs.indd vii 7/22/09 10:05:33 AM
7/22/09 10:05:33 AM
Acknowledgments
From Leslie Michael Orchard: This book owes its existence to the Dojo and MooTools communities
themselves for the wealth of open source code and resources made available to the Web, as well as
answers to random late night questions on IRC.
From Ara Pehlivanian: Thanks to the entire YUI team for writing such a great library. In particular,
I want to thank Eric Miraglia, Dav Glass, Nate Koechley, Douglas Crockford, and Todd Kloots for
answering my questions and helping me get my brain wrapped around certain issues. I also want to
thank the hardworking folks at Wrox for their patience and dedication to putting together a
quality product.
From Scott Koon: Thanks to the editors of my chapters for all their help and guidance. Without them,
you’d need the Rosetta Stone to read my writing. I also want to thank Brendan Eich for creating this
small but powerful language, all of the browser vendors for making JavaScript the most used
programming language in the world, and Douglas Crockford for illuminating just how powerful
JavaScript is and where there be dragons in JavaScript.
From Harley Jones: Thanks to Ryan Duclos for putting my name in the hat, Jim Minatel for getting the
ball rolling, and definitely Kenyon Brown and Scott Meyers for pushing that ball through to the finish.
I also want to thank Jack Slocum and Aaron Conran for an awesomely powerful library. And I thank
Michael LeComte, Nickolay Platonov, Jozef Sakalos, Nigel White, and the entire Ext community (way
too many to list here) for being a sounding board for any and all ideas.
ffirs.indd viiiffirs.indd viii 7/22/09 10:05:33 AM
7/22/09 10:05:33 AM
Contents
Introduction xxv
Part I: Prototype
Chapter 1: Extending and Enhancing DOM Elements 3
Extending a DOM element 3
$() — “The dollar function” 4
$$() 4
Element.extend() 5
Element as a Constructor 5
Navigating the DOM 7
adjacent 7
ancestors 8
up/down/next/previous 9
descendants/descendantOf/firstDescendant/immediateDescendants 11
getElementsBySelector/getElementsByClassName 12
childElements 12
Altering Page Content 12
insert(element, content), insert(element, {position:content) 12
remove 12
replace 13
update 13
Manipulating Element Size, Position, and Visibility 14
Positioning an Element 14
Dealing with Offsets 15
Showing/Hiding Elements 16
Sizing an Element 17
Working with CSS and Styles 17
addClassName, removeClassName, toggleClassNames 18
hasClassName, classNames 20
setStyle, getStyle 20
Extending an Element with Your Own Methods 21
Summary 22
ftoc.indd ixftoc.indd ix 7/22/09 10:05:46 AM
7/22/09 10:05:46 AM
Contents
x
Chapter 2: Handling Cross-Browser Events 23
Registering Event Handlers 23
Event.observe() 24
Responding to Events 25
Event.target, this, and Event.element 26
Event.extend(event) 28
Event.stop(event) 28
Firing Scheduled Events 29
PeriodicalExecuter 29
Summary 32
Chapter 3: Simplifying AJAX and Dynamic Data 33
Making Requests to a Server 34
Ajax.Request 34
Callbacks 36
Ajax.Response 36
Responding Globally to Changing Data 37
Ajax.Responders 38
Updating a Page Dynamically 38
Ajax.Updater 38
Ajax.PeriodicalUpdater 40
Summary 41
Chapter 4: Working with Forms 43
Manipulating Form Elements and Data 43
Form 44
How It All Works Together 45
Validating Form Data 49
Form.Elements 49
Submitting a Form Using AJAX 52
Summary 52
Chapter 5: Manipulating Common Data Structures and Functions 53
Enhancing Native Objects and Introducing Classes 53
Extensions to Object 54
Class 55
Munging and Parsing Strings 56
Generating Templated Content 59
Template.evaluate() 59
ftoc.indd xftoc.indd x 7/22/09 10:05:46 AM
7/22/09 10:05:46 AM
Contents
xi
Binding and Manipulating Functions 60
Binding Functions 60
Other Methods That Manipulate Functions 62
Improving Arrays, Hashes, and Iterators 63
Enumerable 63
Improvements to Array 67
Introducing Hash 68
Dealing with Numbers and Dates 69
Numbers 69
Dates 70
Summary 70
Chapter 6: Extending Prototype 71
Script.aculo.us 71
Effects 72
Moo.fx for Prototype 79
Fx.Tween 80
Fx.Morph 81
Fx.Transitions 81
Fx.Slide 81
Rico 81
Components 82
Accordion component 83
Animation Effects 86
Rounded Corners 86
Drag and Drop 87
Summary 87
Part II: Yahoo! User Interface Library
Chapter 7: Traversing and Manipulating the DOM with YUI 93
Traversing the DOM and Finding Elements 93
get 94
getElementsByClassName 94
getFirstChild/getLastChild 95
getFirstChildBy/getLastChildBy 96
getChildren/getChildrenBy 97
getElementsBy 98
getAncestorByTagName 100
getAncestorByClassName 102
ftoc.indd xiftoc.indd xi 7/22/09 10:05:46 AM
7/22/09 10:05:46 AM
Contents
xii
getAncestorBy 103
Element 105
Selector 106
Manipulating Content 107
insertBefore 108
insertAfter 108
Working with Class Names 108
setStyle 110
getStyle 111
setXY 111
Summary 112
Chapter 8: Handling Cross-Browser Events 113
Registering Events on Page and Element Readiness 113
onDOMReady 115
A Word on Execution Scope and Parameter Passing 117
onAvailable 119
onContentReady 120
on/addListener 121
removeListener 123
Handling Keyboard and Mouse Input 124
KeyListener 124
getCharCode 127
getXY 129
getTarget 130
getRelatedTarget 131
preventDefault 133
stopPropagation 134
stopEvent 136
Working with Custom Events 136
CustomEvent and subscribe 137
unsubscribe 140
subscribeEvent 141
Managing Browser History and Fixing the Back Button 141
Summary 145
Chapter 9: Using Animation and Drag and Drop 147
Composing Basic Animation Sequences 148
Anim 148
Motion 151
ftoc.indd xiiftoc.indd xii 7/22/09 10:05:47 AM
7/22/09 10:05:47 AM
Contents
xiii
Scroll 154
ColorAnim 155
Smoothing Animation Paths and Motion 159
Easing 159
Curved Paths (Bezier) 163
Interactive Animation with Drag and Drop 167
DD 167
DDProxy 168
Summary 172
Chapter 10: Simplifying AJAX and Dynamic Loading 173
Making HTTP Requests and Fetching Data 173
asyncRequest 174
JSON 178
Dynamically Loading Libraries and Components 181
Get Utility 181
YUI Loader Utility 183
Summary 188
Chapter 11: Building User Interfaces with Widgets (Part I) 189
Using AutoComplete with Form Fields 190
AutoComplete and DataSource 190
Building Containers for Content 195
Module 196
Overlay 198
Panel 199
Presenting Content in Tabs and Trees 202
TabView 203
TreeView 212
Summary 224
Chapter 12: Building User Interfaces with Widgets (Part II) 225
Wiring up Buttons, Sliders, and Menus 225
Buttons 225
Styling 226
Sliders 233
Menus 241
Offering Date Selection 251
A Simple Calendar 252
Events 255
ftoc.indd xiii
ftoc.indd xiii 7/22/09 10:05:47 AM
7/22/09 10:05:47 AM
Contents
xiv
Multiple Pages 257
Enabling Rich Content Editing 258
Events 265
Putting It to Use 267
Summary 268
Chapter 13: Enhancing Development with the YUI Core 269
Applying Namespaces and Modularity 269
Namespacing 269
Language Extensions 270
Simulating Classical Inheritance 271
Detecting Browser Environment and Available Modules 282
YAHOO.env.ua 282
YAHOO.env.getVersion 283
YAHOO_config 285
Logging and Debugging 287
Summary 290
Chapter 14: Dealing with Data, Tables, and Charts 291
Formatting Dates and Numbers 291
Dates 291
Numbers 293
Acquiring Sources of Data 295
Presenting Tabular Data 303
Drawing Charts and Graphs 307
Summary 316
Chapter 15: Working with YUI CSS Tools 317
Establishing Cross-Browser Consistency 317
Getting Control of Typography 320
Building Layouts from Grids 321
Templates 323
Nesting Grids 324
Summary 327
Chapter 16: Building and Deploying 329
Shared YUI Files from Yahoo! 329
Combining Files 331
Shrink and Optimize Loading Times 332
ftoc.indd xivftoc.indd xiv 7/22/09 10:05:48 AM
7/22/09 10:05:48 AM
Contents
xv
When and Where to Run It 333
Summary 334
Part III: Ext JS
Chapter 17: Architecture and Library Conventions 337
When to Use Ext JS 337
How to Use Ext JS 338
Stylistic Conventions 339
Ext JS’s Object-Oriented Design 340
Ext.namespace 340
Ext.override 341
Ext.extend and Constructor Conventions 342
Ext.apply 343
Ext.applyIf 343
Utility Functions to Take Over the World 344
Function.createCallback 344
Function.createDelegate 345
Function.createInterceptor 346
Function.createSequence 346
Function.defer 347
Ext JS’s Event-Based Design 347
Ext.util.Observable.addEvents 347
Ext.util.Observable.addListener/.on 348
Ext.util.Observable.removeListener/.un 349
Ext.util.Observable.fireEvent 349
Ext.util.Observable.hasListener 349
Ext.util.Observable.purgeListeners 349
Ext.util.Observable.relayEvents 349
Ext.util.Observable.suspendEvents/.resumeEvents 350
Ext.util.Observable.capture/.releaseCapture 350
Summary 350
Chapter 18: Elements, DomHelper, and Templates 351
Element Manipulation 351
Ext.Element 352
Ext.Element Methods 355
DOM Traversal 360
Ext.DomQuery 360
Ext.DomQuery methods 361
ftoc.indd xvftoc.indd xv 7/22/09 10:05:48 AM
7/22/09 10:05:48 AM
Contents
xvi
DOM Manipulation 363
Ext.DomHelper 363
Ext.Template 365
Ext.XTemplate 368
CSS Manipulation 369
Ext.util.CSS 369
Summary 371
Chapter 19: Components, Layouts, and Windows 373
The Ext JS Component System 374
Ext.Component 374
Ext.ComponentMgr 374
Ext.BoxComponent 376
Ext.Container 377
The Ext JS Component Life Cycle 378
Initialization 378
Rendering 379
Destruction 380
Ext.Viewport 380
Ext.Container Layouts 381
Ext.layout.ContainerLayout 382
Ext.layout.BorderLayout 383
Ext.layout.ColumnLayout 383
Ext.layout.TableLayout 384
Ext.layout.AnchorLayout 385
Ext.layout.AbsoluteLayout 385
Ext.layout.FormLayout 386
Ext.layout.FitLayout 388
Ext.layout.Accordion 388
Ext.layout.CardLayout 389
Creating Your Own Custom Layouts 390
Panels and Windows 391
Ext.Panel 391
Ext.Window 392
Ext.WindowGroup 393
Ext.WindowMgr 393
Summary 393
ftoc.indd xviftoc.indd xvi 7/22/09 10:05:48 AM
7/22/09 10:05:48 AM
Contents
xvii
Chapter 20: Handling Data and Talking with the Server 395
Getting the Data 396
Ext.data.DataProxy 396
Ext.data.HttpProxy 396
Ext.data.MemoryProxy 400
Ext.data.ScriptTagProxy 401
Remodeling the Data 402
Ext.data.Record 402
Ext.data.DataReader 404
Storing the Data Locally 408
Ext.data.Store 408
Ext.data.Record (Revisited) 412
Ext.StoreMgr 413
Putting It All Together 413
Summary 414
Chapter 21: DataViews and Grids 415
Ext.DataView 415
Manipulating the DataView 418
DataView Events 421
Ext.grid.GridPanel 422
Ext.grid.ColumnModel 423
Ext.grid.AbstractSelectionModel 426
Ext.grid.CellSelectionModel 427
Ext.grid.RowSelectionModel 427
Ext.grid.CheckboxSelectionModel 427
Ext.grid.GridView 428
Ext.grid.GroupingView 428
Other Avenues for Customization 429
Summary 429
Chapter 22: Form Controls, Validation, and a Whole Lot More 431
Introduction to the Form Controls 431
Ext.form.Label 432
Ext.form.Field 433
Ext.form.TextField 434
Ext.form.FormPanel & Ext.form.BasicForm 435
Other Form Controls 437
Ext.form.NumberField 437
ftoc.indd xviiftoc.indd xvii 7/22/09 10:05:49 AM
7/22/09 10:05:49 AM
Contents
xviii
Ext.form.TextArea 437
Ext.form.TriggerField 438
Ext.form.DateField 438
Ext.form.ComboBox 439
Ext.form.TimeField 439
Ext.form.Checkbox 440
Ext.form.Radio 440
Ext.form.CheckboxGroup 440
Ext.form.RadioGroup 441
Ext.form.HtmlEditor 442
Ext.form.Hidden 443
Field and Form Validation 443
Validation Messages 443
Advanced Validation Techniques 445
Form-Level Validation 445
The Other Stuff 446
State Management 446
Browser History 447
Visual Effects 448
Drag and Drop 448
Toolbars and Menus 449
Themes 449
Trees 449
Keyboard Navigation 449
Too Much to List 450
Summary 450
Part IV: Dojo
Chapter 23: Enhancing Development with Dojo Core 453
Getting Dojo 453
Using Dojo via the AOL CDN 453
Downloading the Latest Dojo Release 454
Trying Dojo Under Development 454
Sampling Dojo 455
Getting to Hello World 455
Examining Dojo Core 460
Declaring, Loading, and Providing Dependencies 460
Defining Classes and Using Inheritance 463
Declaring Objects in Markup 466
Summary 472
ftoc.indd xviiiftoc.indd xviii 7/22/09 10:05:49 AM
7/22/09 10:05:49 AM
Contents
xix
Chapter 24: Manipulating the DOM 473
Finding DOM Elements 474
Finding Elements with dojo.byId 474
Finding Elements with dojo.query 474
Handling Lists of DOM Elements 477
Filtering and Refining Lists of Nodes 478
Editing NodeLists in Place with splice() 486
Processing Lists of Nodes 488
Summary 497
Chapter 25: Handling Events 499
Reacting to Page Load and Unload 500
Connecting to DOM Events 501
Connecting Inline Handlers to Events 502
Connecting Global Functions to Events 503
Connecting Object Methods to Events 504
Disconnecting from Events 504
Special Event Handling and Event Objects 505
Connecting to Methods 507
Making Connections with NodeLists 509
Publishing and Subscribing to Event Topics 512
Using Event Topics with DOM Event Handlers 513
Using Object Methods as Subscribers 516
Unsubscribing from Published Messages 517
Turning Object Methods into Publishers 518
Using Dojo Behaviors 519
Using Behaviors to Find Nodes and Make Connections 520
Using Behaviors to Connect Object Methods 521
Using Behaviors to Publish Event Topics 522
Summary 524
Chapter 26: Composing Animations 525
Animating CSS Style Properties 526
Using Fade Transitions 528
Using Wipe Transitions 529
Using Slide Animations to Move Elements 531
Controlling Motion with Easings 533
Chaining Animations in Serial 536
Combining Animations in Parallel 537
ftoc.indd xixftoc.indd xix 7/22/09 10:05:49 AM
7/22/09 10:05:49 AM
Contents
xx
Using NodeList Animation Methods 538
Examining Animation Objects 541
Summary 546
Chapter 27: Working with AJAX and Dynamic Data 547
Making Simple Web Requests 548
Making Simple Requests and Handling Responses 548
Using a Single Handler for Both Error and Success 550
Handling Web Responses with Deferreds 551
Registering Handlers for Success and Error Responses 551
Registering Error and Success Handlers in One Call 553
Registering a Single Handler for both Error and Success 553
Working with Response Formats 554
Working with Text Responses 555
Working with XML Responses 555
Working with JSON Responses 556
Working with Comment-Filtered JSON Responses 557
Working with JavaScript Responses 558
Specifying Request Methods 559
Building a Server-Side Request Echo Tool 560
Trying Out Request Methods 562
Using Request Parameters and Content 565
Making GET Request with Query Parameters 565
Making POST Requests with Response Body Parameters 567
Making POST Requests with Raw Body Content 568
Augmenting Forms with In-Place Requests 569
Using Cross-Domain JSON Feeds 577
Loading JSON by Polling Variables 577
Loading JSON with Callbacks 580
Making Requests with IFrames 583
Using a Proxy Script to Package IFrame Data 583
Handling Response Formats with IFrames 584
Uploading Files with Forms and IFrames 585
Summary 593
Chapter 28: Building User Interfaces with Widgets 595
Building and Validating Forms 596
Instantiating Widgets with JavaScript 598
Declaring Widgets in HTML Markup 600
Validating Input with a Regular Expression 601
ftoc.indd xx
ftoc.indd xx 7/22/09 10:05:49 AM
7/22/09 10:05:49 AM
Contents
xxi
Enforcing Form Validation on Submit 602
Handling Numbers and Currency Values 605
Working with Date and Time Fields 607
Enhancing Radio Buttons and Checkboxes 609
Working with Selection Fields and Data Sources 611
Using Sliders to Allow Discrete Value Selection 615
Using Dynamic Textareas and Rich Text Editors 617
Managing Application Layout 619
Setting Up an Application Layout Page 620
Using ContentPanes as Layout Building Blocks 621
Managing Layout Regions with BorderContainer 622
Managing Content Visibility with StackContainer 625
Swapping Content Panes with AccordionContainer 632
Building Tabbed Content Panes with TabContainer 634
Dividing Up Layout Regions with SplitContainer 636
Creating Application Controls and Dialogs 638
Building and Scripting Clickable Buttons 640
Composing Pop-up Context Menus 642
Combining Buttons and Menus 645
Building Toolbars from Buttons and Menus 646
Giving Feedback on Completion with Progress Bars 648
Applying Themes to Widgets 650
Examining Widget DOM Structure 650
Loading and Applying a Theme to Widgets 651
Customizing and Examining Available Themes 653
Summary 654
Chapter 29: Building and Deploying Dojo 655
Explaining Dojo Builds 655
Finding the Build System 656
Creating a Custom Build Profile 656
Producing a Custom Build 659
Examining and Using a Custom Build 660
Summary 662
Chapter 30: Expanding Dojo 663
Exploring the DojoX Subproject 663
Trying Out Advanced Widgets 664
Building Fisheye Menus 664
Creating Animated Notifications with the Toaster Widget 666
ftoc.indd xxi
ftoc.indd xxi 7/22/09 10:05:50 AM
7/22/09 10:05:50 AM
Contents
xxii
Employing Advanced Form Validation Helpers 667
Producing Content from Templates 670
Drawing Shapes and Rendering Charts 674
Drawing Shapes and Lines 675
Rendering Charts and Graphs 676
Using Encoding and Crypto Routines 679
Generating MD5 Hashes 679
Encoding Data with Base64 680
Encrypting Data with Blowfish 682
Navigating JSON Data Structures 683
Exploring Further DojoX Offerings 686
Summary 687
Part V: MooTools
Chapter 31: Enhancing Development with MooTools 691
Getting MooTools 691
Downloading the Latest MooTools Release 691
Trying MooTools Under Development 694
Examining MooTools Core 694
Checking the MooTools Version 695
Determining Types 695
Checking for Defined Values 696
Picking a Defined Value 696
Choosing Random Numbers 696
Getting the Current Time 697
Clearing Timers and Intervals 697
Merging and Extending Objects 697
Using Array Extensions 699
Processing Array Items with .each() and .forEach() 699
Filtering and Mapping Array Items 701
Checking the Content of Array Items 702
Converting Array Items into Object Properties 704
Extending and Combining Arrays 704
Flattening Nested Arrays 705
Applying Selection Rules with .link() 706
Using Hash Data Structures 706
Defining Hashes and the Hash Shortcut 707
Getting and Setting Keys and Values 707
Mapping and Filtering Hashes 708
Checking Hashes with .every() and .some() 709
ftoc.indd xxii
ftoc.indd xxii 7/22/09 10:05:50 AM
7/22/09 10:05:50 AM
Contents
xxiii
Extending and Combining Hashes 709
Converting Hashes into URL Query Strings 710
Using String Extensions 710
Checking String Contents 710
Converting Strings to Numbers and Colors 711
Using Simple Substitution Templates 712
Performing Miscellaneous Transformations 712
Using Function Extensions 713
Binding Functions to Object Contexts 713
Delaying and Setting Function Calls on Intervals 714
Attempting Function Calls with Potential Exceptions 715
Using Object-Oriented Programming 715
Building Classes and Subclasses 716
Injecting Methods and Properties into Existing Classes 718
Implementing Mixin Classes 719
Summary 723
Chapter 32: Manipulating the DOM and Handling Events 725
Finding Elements in the DOM 725
Finding Elements with $() and IDs 726
Finding Elements with $$() and CSS Selectors 726
Navigating the DOM Structure 728
Manipulating Styles and Properties 730
Manipulating Element CSS Classes 731
Manipulating Element Visual Styles 733
Manipulating Element Properties and Attributes 735
Manipulating Extended Element Properties 738
Using Element Storage to Safely Manage Metadata 742
Modifying DOM Structure 743
Creating New Elements 744
Cloning Elements 744
Grabbing Elements 745
Injecting Elements 746
Creating and Appending Text Nodes 746
Replacing and Wrapping Elements 746
Adopting Elements 747
Destroying and Emptying Elements 748
Attaching Listeners and Handling Events 748
Reacting to Page Load and Unload 748
Adding and Removing Event Handlers 750
Investigating the Event Wrapper Object 755
Summary 761
ftoc.indd xxiii
ftoc.indd xxiii 7/22/09 10:05:50 AM
7/22/09 10:05:50 AM
Contents
xxiv
Chapter 33: Simplifying AJAX and Handling Dynamic Data 763
Manipulating Browser Cookies 763
Using Cookie Functions 764
Using Cookie-Backed Hashes 766
Dynamically Loading Page Assets 767
Loading JavaScript and JSON Feeds 767
Including Additional CSS Style Sheets 769
Fetching Images and Image Sets 769
Making Web Requests 772
Performing Basic Web Requests 773
Fetching and Updating HTML Content 780
Requesting and Using JavaScript and JSON Data 782
Summary 786
Chapter 34: Building User Interfaces and Using Animation 787
Composing Animations 787
Examining Element Size and Position 789
Using MooTools Fx to Compose Animations 791
Exploring Pre-Built Animations and Effects 796
Using Fx.Slide Animations 797
Using Fx.Scroll Animations 799
Exploring MooTools Fx.Transitions 800
Exploring Animation Events 804
Animating Multiple Properties with Fx.Morph 807
Animating Multiple Elements with Fx.Elements 809
Using User Interface Widgets 811
Building Accordion Layouts 811
Adding Smooth Scrolling to Page Navigation 815
Enabling Draggable Elements 816
Automatically Scrolling the Window and Elements 821
Enabling Drag-and-Drop Targets 822
Building Sortable Lists 824
Using Tool Tips 827
Building Slider Controls 830
Summary 833
Index 835
ftoc.indd xxivftoc.indd xxiv 7/22/09 10:05:51 AM
7/22/09 10:05:51 AM
Introduction
JavaScript is the industry standard client-side scripting language that is used in web applications.
Professional JavaScript Frameworks: Prototype, YUI, Ext JS, Dojo and MooTools offers an examination of some
of the top JavaScript (JS) frameworks that are available, with practical examples and explanations of
what each does best.
Over the past few years, there’s been a small renaissance in JavaScript as a language. A variety of projects
have sprung up to build reusable JS libraries and frameworks — and at this point, a good number of
them have matured and shown staying power that they’re worth taking a serious look at and relying on
in professional projects.
JavaScript has grown in popularity in parallel with the Web and today is supported by all major
browsers and new web technologies. JavaScript has been extended over time to deliver high-performing
and incredibly impressive Web user experiences, using technologies including Adobe Flash, AJAX, and
Microsoft Silverlight.
As JavaScript is used increasingly for “serious” development on the Web, the lessons that have been
learned and the tools that have been invented along the way are being consolidated and shared by
developers in the form of libraries and frameworks. However, since JavaScript is such a flexible
and dynamic language, each framework can present very different approaches to the problems of web
development — each with its own pros and cons.
Whom This Book Is For
This book is for web developers who want to get straight into JavaScript and explore the tools and
productivity gains offered by the frameworks. A working knowledge of HTML, CSS, and JavaScript are
assumed — and also of use will be some experience with object-oriented programming, server-side PHP
scripting, and knowledge of web development modern techniques such as AJAX.
What This Book Covers
This book is meant to be a concise and handy companion while you’re working, deferring to other
sources online and otherwise to fill you in on the more advanced, experimental, and in-progress facets of
the JavaScript frameworks.
What You Need to Use This Book
A browser, a text editor, and web hosting are pretty much all you need to make use of the examples in
this book. Using Mozilla Firefox as your browser with the Firebug extension installed is highly
recommended, since that combination offers a very powerful in-browser development environment with
JavaScript logging and DOM exploration tools.
flast.indd xxvflast.indd xxv 7/22/09 10:06:02 AM
7/22/09 10:06:02 AM
Introduction
xxvi
You can download Mozilla Firefox at
http://getfirefox.com/
and Firebug is available at
http://
getfirebug.com/
once you’ve gotten Firefox running.
Additionally, a few examples in this book require a server-side script to fully work, and the example
code is in PHP. So, having access to PHP on your web server would help, though the scripts should work
on pretty much any version from PHP 4 and up.
Conventions
To help you get the most from the text and keep track of what’s happening, the following conventions
are used throughout the book:
Filenames, URLs, and code within the text are formatted like so:
persistence.properties.
Code is presented in two different ways:
In code examples, new and important code is highlighted with a gray background.
The gray highlighting is not used for code that’s less important in the present
context, or has been shown before.
Source Code
As you work through the examples in this book, you may choose to either type in all the code manually
or use the source code files that accompany the book. All of the source code used in this book is available
for download
at
http://www.wrox.com.

Once at the site, simply locate the book’s title (either by using
the Search box or by using one of the title lists) and click the Download Code link on the book’s detail
page to obtain all the source code for the book.
Because many books have similar titles, you may find it easiest to search by ISBN; this book’s ISBN is
978-0-470-38459-6.
Once you download the code, just decompress it with your favorite compression tool. Alternately, you
can go to the main Wrox code download page at
http://www.wrox.com/dynamic/books/download.
aspx
to see the code available for this book and all other Wrox books.
Errata
We make every effort to ensure that there are no errors in the text or in the code. However, no one is
perfect, and mistakes do occur. If you find an error in one of our books, such as a spelling mistake or
faulty piece of code, we would be very grateful for your feedback. By sending in errata, you may save
other readers hours of frustration and at the same time you will be helping us provide even higher
quality information.


flast.indd xxviflast.indd xxvi 7/22/09 10:06:02 AM
7/22/09 10:06:02 AM
Introduction
xxvii
To find the errata page for this book, go to

http://www.wrox.com
and locate the title using the Search
box or one of the title lists. Then, on the book details page, click the Book Errata link. On this page you
can view all errata that has been submitted for this book and posted by Wrox editors. A complete book
list including links to each book’s errata is also available at
http://www.wrox.com/misc-pages/
booklist.shtml.
If you don’t spot “your” error on the Book Errata page, go to
http://www.wrox.com/contact/
techsupport.shtml
and complete the form there to send us the error you have found. We’ll check the
information and, if appropriate, post a message to the book’s errata page and fix the problem in
subsequent editions of the book.
p2p.wrox.com
For author and peer discussion, join the P2P forums at
http://p2p.wrox.com.
The forums are a
Web-based system for you to post messages relating to Wrox books and related technologies and interact
with other readers and technology users. The forums offer a subscription feature to e-mail you topics of
interest of your choosing when new posts are made to the forums. Wrox authors, editors, other industry
experts, and your fellow readers are present on these forums.
At
http://p2p.wrox.com
you will find a number of different forums that will help you not only as
you read this book, but also as you develop your own applications. To join the forums, just follow
these steps:
1.
Go to
http://p2p.wrox.com
and click the Register link.
2.
Read the terms of use and click Agree.
3.
Complete the required information to join as well as any optional information you wish to
provide and click Submit.
4.
You will receive an e-mail with information describing how to verify your account and complete
the joining process.
You can read messages in the forums without joining P2P but in order to post your own messages, you
must join.
Once you join, you can post new messages and respond to messages other users post. You can read
messages at any time on the Web. If you would like to have new messages from a particular forum
e-mailed to you, click the Subscribe to this Forum icon by the forum name in the forum listing.
For more information about how to use the Wrox P2P, be sure to read the P2P FAQs for answers to
questions about how the forum software works as well as many common questions specific to P2P and
Wrox books. To read the FAQs, click the FAQ link on any P2P page.
flast.indd xxviiflast.indd xxvii 7/22/09 10:06:03 AM
7/22/09 10:06:03 AM
flast.indd xxviii
flast.indd xxviii 7/22/09 10:06:03 AM
7/22/09 10:06:03 AM
Part I
Prototype
Chapter 1: Extending and Enhancing DOM Elements
Chapter 2: Handling Cross-Browser Events
Chapter 3: Simplifying AJAX and Dynamic Data
Chapter 4: Working with Forms
Chapter 5: Manipulating Common Data Structures
and Functions
Chapter 6: Extending Prototype
c01.indd 1c01.indd 1 7/22/09 9:33:14 AM
7/22/09 9:33:14 AM
2
Part I: Prototype
Prototype was one of the first JavaScript libraries to gain prominence during the Web 2.0 resurgence.
When the term AJAX was first coined in 2005, making cross - browser XMLHttpRequests was a minefield
of browser - specific code. Prototype assists you in your quest for cross - browser compatibility by
smoothing out the rough edges of event handling by providing a common method for binding events to
their respective handlers and providing a common interface for creating AJAX requests that work in all
browsers. It also gives you a cross - browser way to manipulate the DOM, by handling the special cases in
all browsers, and allowing you to focus on just writing code without cluttering up your code with
browser - specific “ if - else ” statements.
Prototype extends the JavaScript language as well as the elements. The native JavaScript Object is
extended to include methods for determining the type of data the object represents as well as helpful
serialization methods. The Enumerable class allows you to easily traverse and manipulate your arrays of
both JavaScript objects and DOM elements by providing useful methods such as
each()
and
map()

directly on your arrays. The native Function object is also extended with useful methods, such as

wrap()
, which let you write interceptors for your methods that provide useful features like logging.
Prototype eases inheritance with the Class object. You can easily extend your objects and create
hierarchies without the headaches associated with normal inheritance in statically typed languages. All
of these features make Prototype the best choice for writing logic in JavaScript, and it provides you with
an excellent base for writing your own JavaScript library. Since Prototype does all of the heavy lifting for
you, you can focus on the fun parts of library development — creating new widgets and data structures.
c01.indd 2c01.indd 2 7/22/09 9:33:15 AM
7/22/09 9:33:15 AM

Extending and Enhancing
DOM Elements

Prototype is an excellent framework to use either as your main JavaScript library or as the
foundation of another library. Part of the magic of Prototype is the extension of DOM elements
by the framework. By adding new methods to elements, Prototype makes it easier to write
cross - browser code in a more eloquent manner. There are also several methods for taking care of
the dirty details involved in positioning elements. It is easier to write unobtrusive JavaScript by
taking advantage of helper methods such as
getElementsByClassName
and

getElementsBySelectors
, making it easy to apply styling or events to groups of elements with
something in common.
In this chapter, you ’ ll learn about:
Extending a DOM element with Prototype
Altering and manipulating content and size
Using CSS to style an element
Extending a DOM element
Before Prototype came along, cross-browser code often looked a lot like a road map: a lot of
branches and a lot of the same checks over and over again. By extending the elements you are
working on, Prototype is able to centralize all of the cross - browser hacks that make JavaScript
programming such a chore. Prototype keeps its extension methods for all elements in the

Element.Methods
and
Element.Methods.Simulated
object. If the element is an
input
,

select
, or
textarea
tag, the methods in
Form.Element.Methods
are also included. Form
elements themselves are extended with the methods in
Form.Methods
. Most of these methods
return the original element, so you can chain together methods like so:
$(myElement)
.update( “ updated ” ).show();
. It is important to note that not only is the element you choose
extended, but all of the child elements of that element are also extended.



c01.indd 3c01.indd 3 7/22/09 9:33:15 AM
7/22/09 9:33:15 AM
4
Part I: Prototype
In browsers that support modification of the
HTMLElement.prototype
, Prototype adds the methods to

HTMLElement
for you. That means you don ’ t have to call
Element.extends()
on any element you
create by hand. You can start using Prototype methods immediately.

var newDiv = document.createElement(“div”);
newDiv.update(“Insert some text”);
newDiv.addClassName(“highlight”);
Internet Explorer doesn ’ t support modifying
HTMLElement
, so you have to call
Element.extends()
or
get a reference to the element using the
$()
or
$$()
methods.
$() — “ The dollar function ”
The easiest way to extend a DOM element is to use the
$()
function to get a reference to the element
rather than using
document.getElementById
or some other method. When you obtain a reference this
way, Prototype automatically adds all of the methods in
Element.Methods
to the element. If you pass a
string to the method, it will get a reference to the element with the ID you specify for you. If you pass in
a reference to the element, it will return the same reference but with the extension methods. This is the
most common way to extend an element.

< body >
< div id=”myId” > Hello Prototype < /div >
< script type=”text/javascript” >
$(“myId”).hide();
< /script >
< /body >
$$()
This works in a similar manner to the
$()
function. It takes a CSS selector as an argument and returns an
array of elements that match the selector. CSS selectors are a powerful tool for getting a specific element
back from the DOM. The elements in the array will be in the same order as they appear in the DOM and
each will be extended by Prototype.

$$(‘input’);
// select all of the input elements

$$(‘#myId’);
//select the element with the id “myId”

$$(‘input.validate’);
//select all of the input elements with the class “validate”
Prototype does not use the browser ’ s built - in CSS selector parsing, so it is free to implement selectors
specified in newer versions of CSS than the browser supports. As a result, version 1.5.1 and higher of
Prototype includes support for almost all of CSS3.

c01.indd 4c01.indd 4 7/22/09 9:33:16 AM
7/22/09 9:33:16 AM
Chapter 1: Extending and Enhancing DOM Elements
5
$$(‘#myId > input’);
//select all of the input elements that are children of the element with the id “myId”

$$(‘table < tr:nth-child(even)’);
//selects all of the even numbered rows of all table elements.
Element.extend()
This method accepts an element and extends the element using the methods found in
Element
.Methods
. It is very similar to
$()
except it only accepts references to DOM objects and will not fetch
a reference for you if you pass it an id.
Here is a simple example of using
Element.extend()
:

Var newDiv = document.createElement(“div”);
Element.extend(newDiv);
newDiv.hide();
Element as a Constructor
You can also use the
Element
object as a way to construct new DOM elements rather than using the
built - in DOM methods. New elements created in this way are automatically extended by Prototype and
can be used immediately.

< head >
< meta http-equiv=”Content-Type” content=”text/html; charset=utf-8” >
< title > untitled < /title >
< style >
.redText { color: red;}
< /style >
< /head >
< body >
< div id=”myDiv” class=”main” > Here is my div < /div >

< textarea id=”results” cols=”50” rows=”10” > < /textarea >
< script type=”text/javascript” src=”prototype-1.6.0.2.js” > < /script >
< script type=”text/javascript” >
Event.observe(window,”load”, function(e) {
$(“results”).value = “”;
$(“results”).value += $(“myDiv”).id + “\n”;
$(“results”).value += $$(“.main”)[0].id + “\n”;
var newEl = new Element(“h1”,{“class”: “redText”});
$(“myDiv”).insert(newEl);
newEl.update(“I’m new here”);

var manuallyCreated = document.createElement(“h2”);
$(“myDiv”).insert(manuallyCreated);
Element.extend(manuallyCreated);
manuallyCreated.update(“I was extended”);
});
< /script > < /body >
c01.indd 5c01.indd 5 7/22/09 9:33:16 AM
7/22/09 9:33:16 AM
6
Part I: Prototype
Since
$$()
returns a DOM - ordered array of elements, you have to refer to the first element in the array
by the ordinal 0.
Here you see some of the ways you can extend an element. First, you use the
$()
method to grab the
element by ID and extend the element. Next, you use the
$$()
method and pass in a CSS selector to get
the element by class name. Now you will use the
Element
object as a constructor and create a new H1
element with a class of
redText
, inserting it into the myDiv element and setting the text of the newly
created element. Finally, you create an element the old - fashioned way and use
Element.extend()
to
extend the element, as shown in Figure 1 - 1.
Figure 1 - 1
c01.indd 6
c01.indd 6 7/22/09 9:33:16 AM
7/22/09 9:33:16 AM
Chapter 1: Extending and Enhancing DOM Elements
7

Navigating the DOM
Trying to figure out where the element you are interested in is located in the DOM and what elements
are surrounding that element is no easy task. Prototype ’ s
Element
object provides a multitude of ways
to traverse the DOM. Several methods allow you to specify CSS rules to narrow your search. All of
Prototype ’ s DOM navigation methods ignore white space and only return element nodes.
adjacent
This method finds all of an element ’ s siblings that match the selector you specify. This method is useful
for dealing with lists or table columns.

< body >
< ul id=”PeopleList” >
< li class=”female” id=”judy” > Judy < /li >
< li class=”male” id=”sam” > Sam < /li >
< li class=”female” id=”amelia” > Amelia < /li >
< li class=”female” id=”kim” > Kim < /li >
< li class=”male” id=”scott” > Scott < /li >
< li class=”male” id=”brian” > Brian < /li >
< li class=”female” id=”ava” > Ava < /li >
< /ul >
< textarea id=”results” cols=”50” rows=”10” > < /textarea >
< script type=”text/javascript” src=”prototype-1.6.0.2.js” > < /script >
< script type=”text/javascript” >
Event.observe(window,”load”, function(e) {
var els =$(“kim”).adjacent(“li.female”);
$(“results”).value = “”;
for(var i = 0;i < els.length; i++) {
$(“results”).value += els[i].id + “\n”;
}
});
< /script >
< /body >
Here you start with the list element with the ID “ kim ” and gather the
li
elements adjacent with the class
name
female
, as shown in Figure 1 - 2.
c01.indd 7c01.indd 7 7/22/09 9:33:17 AM
7/22/09 9:33:17 AM
8
Part I: Prototype
ancestors
This collects all of the element ’ s ancestors in the order of their ancestry. The last ancestor of any given
element will always be the HTML element. Calling this method on the HTML element will just return an
empty array. Given the following HTML snippet:

< html >
< body >
< div id=”myDiv” >
< p id=”myParagraph” > Hello pops < /p >
< /div >
< /body >
< /html >
The array would be returned with the elements in the following order:

DIV @-- > BODY @-- > HTML
Figure 1-2
c01.indd 8c01.indd 8 7/22/09 9:33:17 AM
7/22/09 9:33:17 AM
Chapter 1: Extending and Enhancing DOM Elements
9
You can use the following code to verify this behavior:

< html >
< body >
< div id=”myDiv” >
< p id=”myParagraph” > Hello pops < /p >
< /div >
< textarea id=”results” cols=”50” rows=”10” > < /textarea >
< script type=”text/javascript” src=”prototype-1.6.0.2.js” > < /script >
< script type=”text/javascript” >
Event.observe(window,”load”, function(e) {
var a = $(‘myParagraph’).ancestors();
$(‘results’).value = “”;
for(var i = 0;i < a.length;i++) {
$(‘results’).value += a[i].tagName + “\n”;
}
});
< /script >

< /body >
< /html >
up/down/next/previous
These four methods comprise Prototype ’ s core DOM traversal functionality. They allow you to define a
starting element, and then walk around the DOM at your leisure. All of the methods are chainable,
allowing you to call each in succession on whatever element was returned by the preceding function. If
no element can be found that matches the criteria you define,
undefined
is returned. Each method
accepts two arguments: a CSS selector or a numeric index. If no argument is passed, the first element
matching the criteria is returned. If an index is passed, the element at that position in the element ’ s
corresponding array is returned. For example, the resulting array used for the
down()
method will
match the element ’ s descendants array. If a CSS selector is passed in, the first element that matches that
rule is returned. If both an index and a CSS rule are passed in, the CSS rule is processed first and then the
index is used to select the element from the array defined by the CSS rule.
up
Returns the first ancestor matching the specified index and/or CSS rule. If no ancestor matches the
criteria,
undefined
is returned. If no argument is specified, the element ’ s first ancestor is returned. This
is the same as calling
element.parentNode
and passing the parent through
Element.extend
.
down
Returns the first descendant matching the specified index and/or CSS rule. If no descendant matches the
criteria,
undefined
is returned. If no argument is specified, the element ’ s first descendant is returned.
next
Returns the element ’ s siblings that come after the element matching the specified index and/or CSS rule.
If no siblings match the CSS rule, all the following siblings are considered. If no siblings are found after
the element,
undefined
is returned.
c01.indd 9c01.indd 9 7/22/09 9:33:17 AM
7/22/09 9:33:17 AM
10
Part I: Prototype
previous
Returns the element ’ s siblings that come before the element matching the specified index and/or CSS
rule. If no siblings match the CSS rule, all the previous siblings are considered. If no siblings are found
before the element,
undefined
is returned.
Take a fragment of HTML that looks like the following example. Here you are defining four elements
that relate to each other like this:

< div id=”up” >
< p id=”prevSibling” > I’m a sibling < /p > < div id=”start” > < p id=”down” > Start
Here < /p > < /div > < span id=”nextSibling” > I’m next < /span >
< /div >
This code starts at the start DIV and looks at the previous, next, up, and down elements. You start at the
element with the ID start. The paragraph element containing the text “ Start Here ” is the first child of
the starting element and is returned by calling the
down
method. The
up
method returns the
topDiv

div. The
previous
method returns the
sibling
paragraph element and
next
returns the
nextSibling
span
, as shown in Figure 1 - 3.

< body >
< div id=”up” >
< p id=”prevSibling” > I’m a sibling < /p > < div id=”start” > < p id=”down” > Start
Here < /p > < /div > < span id=”nextSibling” > I’m next < /span >
< /div >
< textarea id=”results” cols=”50” rows=”10” > < /textarea >
< script type=”text/javascript” src=”prototype-1.6.0.2.js” > < /script >
< script type=”text/javascript” >
Event.observe(window,”load”, function(e) {
var startEl = $(‘start’);
var previousEl = startEl.previous();
var upEl = startEl.up();
var downEl = startEl.down();
var nextEl = startEl.next();

var resultTextArea = $(“results”);
resultTextArea.value = “”;
resultTextArea.value += “start =” + startEl.id + “\n”;
resultTextArea.value += “previous =” + previousEl.id + “\n”;
resultTextArea.value += “next =” + nextEl.id + “\n”;
resultTextArea.value += “down =” + downEl.id + “\n”;
resultTextArea.value += “up =” + upEl.id + “\n”;
});
< /script >
< /body >
c01.indd 10c01.indd 10 7/22/09 9:33:17 AM
7/22/09 9:33:17 AM
Chapter 1: Extending and Enhancing DOM Elements
11
descendants/descendantOf/firstDescendant/
immediateDescendants
All of these methods allow you to work with the children of a given element. The methods

descendants
and
immediateDescendants
return arrays of child elements.
descendants — This method returns an array containing the children of the element. If the
element has no children, an empty array is returned.
descendantOf — This method returns a Boolean telling you whether or not the given element is
a descendant of the given ancestor.
firstDescendant — This method returns the first child of a given element that is itself an
element.
immediateDescendants — (deprecated) This method returns an array of the elements one level
down and no further.




Figure 1-3
c01.indd 11c01.indd 11 7/22/09 9:33:18 AM
7/22/09 9:33:18 AM
12
Part I: Prototype
getElementsBySelector/getElementsByClassName
These methods allow you to select groups of elements based on their attributes or position and
manipulate the elements however you choose. Both of these methods have been deprecated and you
should use the
$$()
method in place of them.
childElements
This useful function gathers up all the children of an element and returns them as an array of extended
elements. The elements are returned in the same order as they are in the DOM. So, the element at index 0
is the closest child to the parent element and so forth.
Altering Page Content
Prototype provides four methods for changing content on a page: insert, remove, replace, and update.
These methods can be called using the
Element
object and are added to any element that is extended.
They all take an optional argument, which is the element to be altered. The insert and replace methods
call
eval()
on any script tags contained in the content passed to them. Any of these methods that take a
content argument will accept plain text, an HTML fragment, or a JavaScript object that supports

toString()
.
insert(element, content), insert(element,
{position:content)
Insert takes the content you provide and inserts it into an element. If you do not specify a position (such
as top, bottom, before, or after), your content will be appended to the element. This method is useful for
dynamically inserting content retrieved from a web service or for loading elements into a page one piece
at a time for performance reasons.

< script type=”text/javascript” >

function insertSample() {
$(“MainDiv”).insert(“New Content added at the end by default”);
$(“MainDiv”).insert({top:”Added at the top”});
$(“MainDiv”).insert({before:”Added before the element”})
$(“MainDiv”).insert({after:”Added after the element”});
$(“MainDiv”).insert({bottom:”Added at the bottom”});
};
insertSample();
< /script >
remove
Calling remove on an extended element removes it completely from the DOM. The function returns the
removed element. This method is most often used to remove an element after a user has chosen to delete
whatever item the element represents in the UI.

c01.indd 12c01.indd 12 7/22/09 9:33:18 AM
7/22/09 9:33:18 AM
Chapter 1: Extending and Enhancing DOM Elements
13
< body >
< table id=”myTable” >
< tr id=”firstRow” > < td > First Row < /td > < /tr >
< tr id=”secondRow” > < td > Second Row < /td > < /tr >
< tr id=”thirdRow” > < td > Third Row < /td > < /tr >
< /table >
< script type=”text/javascript” src=”prototype-1.6.0.2.js” > < /script >
< script type=”text/javascript” >

function removeRow() {
$(“secondRow”).remove();
};
removeRow();
< /script >
< /body >
replace
Replace takes away the element specified and replaces it with the content provided. This removes the
element and its children from the DOM.

< body >
< div id=”MainDiv” >
< div id=”tempDiv” > Place holder < /div >
< /div >
< script type=”text/javascript” src=”prototype-1.6.0.2.js” > < /script >
< script type=”text/javascript” >
//simulate loading content from a web service
setTimeout(function () {
$(“MainDiv”).replace(“ < h1 > Replaced Content < /h2 > ”);
}, 1000);
< /script >
< /body >
update
Update replaces the content of an element with the specified content. It does not remove the element
from the DOM, although it does remove any children of the element.

< body >
< div id=”MainDiv” > Here is some content to be updated < /div >
< script type=”text/javascript” src=”prototype-1.6.0.2.js” > < /script >
< script type=”text/javascript” >

//simulate loading content from a web service
setTimeout(function() {
$(“MainDiv”).update(“updated the content”);
}, 1000);
< /script >
< /body >
c01.indd 13c01.indd 13 7/22/09 9:33:18 AM
7/22/09 9:33:18 AM
14
Part I: Prototype

Manipulating Element Size, Position,
and Visibility
One of the hardest things about working with the DOM in different browsers is getting the dimensions
of the elements contained in the DOM. Each browser has quirks relating to how it sizes elements in the
DOM and how its size affects the flow of the surrounding elements.
Positioning an Element
Setting an element ’ s position is one of the cornerstones of modern web page design. Often when
designing dynamic web pages, you need to be able to move elements around and place them on the
page exactly where you want them. To place an element precisely on the page, you should first set its
position CSS style. Setting the position style rule to absolute means that the element ’ s top and left
coordinates are calculated from the top - left corner of the document. Setting the position to relative
allows you to position the element using numbers calculated to the containing block ’ s top - left corner.
Prototype provides a few methods for easily setting an element ’ s position style.
makePositioned, undoPositioned
These methods allow you to easily make CSS - positioned blocks out of elements in your DOM. Calling

makePositioned
on an element sets its
position
to
relative
if its current position is static or

undefined
. The
undoPositioned
method sets the element ’ s
position
back to what it was before

makePositioned
was called.

$(“myElement”).makePositioned();
$(“myElement”).undoPositioned();
absolutize, relativize
These methods change the positioning setting of the given element by setting the position style to either
absolute or relative, respectively.

$(“myElement”).absolutize();
$(“myElement”).relativize();
clonePosition
This method creates a new element with the same position and dimensions as the current element. You
specify what settings are applied to the new element by using an optional parameter containing the
following options:
Setting Description
setLeft Applies the source ’ s CSS left property. Defaults to true.
setTop Applies the source ’ s CSS top property. Defaults to true.
setWidth Applies the source ’ s CSS width property. Defaults to true.
setHeight Applies the source ’ s CSS height property. Defaults to true.
offsetLeft Lets you offset the clone ’ s left CSS property by n value. Defaults to 0.
offsetTop Lets you offset the clone ’ s top CSS property by n value. Defaults to 0.
c01.indd 14c01.indd 14 7/22/09 9:33:19 AM
7/22/09 9:33:19 AM
Chapter 1: Extending and Enhancing DOM Elements
15
Dealing with Offsets
Prototype has a couple of different methods on its
Element
object that make finding the offset of an
element easier.
cumulativeOffset, positionedOffset, viewportOffset
Each of these methods returns two numbers, the top and left values of the given element in the form
{ left: number, top: number}
. The
cumulativeOffset
method returns the total offset of an
element from the top left of the document. The positionedOffset method returns the total offset of
an element ’ s closest positioned (one whose position is set to
‘ static ’
) ancestor. The viewportOffset
method returns the offset of the element relative to the viewport.
getOffsetParent
This method returns the nearest positioned ancestor of the element, and returns the body element if no
other ancestor is found.
The following code illustrates how the different offsets are calculated. In it, you have two elements: a
parent
DIV
with one child. The parent has its
position
set to
absolute
and is positioned 240 pixels
from the top and 50 pixels from the left side of the document. When you call the
getOffsetParent

method of the element with the ID of
start
, the positioned element
positionedParent
is returned.
The
results
textarea has no positioned ancestors. If you call
getOffsetParen
t on it, the
BODY
element
is returned. Since the
start
element itself is not positioned, calling
positionedOffset
returns 0,0, as
shown in Figure 1 - 4.

< body >
< div id=”positionedParent” style=”position:absolute;border:1px solid black;
top:240px;left:50px;” >
< div id=”start” > Start Here < /div >
< /div >

< textarea id=”results” cols=”50” rows=”10” > < /textarea >
< script type=”text/javascript” src=”prototype-1.6.0.2.js” > < /script >
< script type=”text/javascript” >
Event.observe(window,”load”, function(e) {
$(“results”).value = “”;
$(“results”).value += “offsetParent = “ + $(“start”).getOffsetParent()
.id + “\n”;
$(“results”).value += “cumulativeOffset = “ + $(“start”)
.cumulativeOffset() + “\n”;
$(“results”).value += “positionedOffset = “ + $(“start”)
.positionedOffset() + “\n”;
$(“results”).value += “parent positionedOffset = “ + $(“start”)
.parentNode.positionedOffset() + “\n”;
});
< /script >
< /body >
c01.indd 15c01.indd 15 7/22/09 9:33:19 AM
7/22/09 9:33:19 AM
16
Part I: Prototype
Showing/Hiding Elements
Showing and hiding an element has been part of your web developer ’ s toolkit since you typed in your
first script tag.
show/hide
These methods allow you to quickly change an element ’ s visibility. They do this by setting the
elements
display
CSS style to
none
. Setting the display to none removes the element from the flow
of the document and causes the browser to render the other elements in the page as if the element were
not present.

$(“myElement”).show();
$(“myElement”).hide();
Figure 1-4
c01.indd 16c01.indd 16 7/22/09 9:33:19 AM
7/22/09 9:33:19 AM
Chapter 1: Extending and Enhancing DOM Elements
17
setOpacity
This method sets the opacity of a given element, while relieving you of the burden of dealing with
various browser inconsistencies. It takes a floating - point number, with 0 being totally transparent and 1
being completely opaque. Using this method is the equivalent of setting the opacity via a CSS class or
using the
setStyle
method, passing in a value for opacity.

$(“myElement”).setOpacity(0.5);
Sizing an Element
Every browser has some kind of quirk associated with the way it represents elements on the screen and
how it calculates the element ’ s dimensions. Different browsers calculate an element ’ s computed style
differently. Prototype equalizes the differences and returns the correct computed style for the browser.
getDimensions, getHeight, getWidth
Using these methods, you can get the computed dimensions of an element at run time. The

getDimensions
method returns an object containing the computed height and width of the element.
When you call
getDimensions
, it ’ s best to save the returned value in a local variable and refer to that
rather than making multiple calls. If you just want the width or height, it ’ s best to just call the
appropriate method.

Var dimensions = $(‘myDiv’).getDimensions();
Var currentWidth = dimensions.width;
Var currentHeight = dimensions.height;
makeClipping, undoClipping
The CSS
clip
property allows you to define whether or not the element ’ s content should be shown
if the content is wider or taller than the element ’ s width and height will allow. Since the
clip
property
is poorly supported amongst the browsers, Prototype provides this method that will set an element ’ s

overflow
property to
hidden
for you. You can use
undoClipping
to allow the element to resize
normally.
Working with CSS and Styles
CSS classes are useful for marking elements in response to some event. Say you are creating an online
survey form and you want to mark several fields as required, but you don ’ t want to get each element
that is required by ID and check them one by one to make sure the user has entered a proper value. You
can create a CSS class called “ required ” and apply it to each of the elements you need the user to enter a
value into. Sometimes you need to change an element ’ s style or class at run time in response to a user- or
data-driven event, say if you are changing a table row from read - only to editable. Classes are an
invaluable tool in any web developer ’ s toolkit. Prototype makes it easier for you to apply and remove
CSS classes from elements in your DOM.
c01.indd 17c01.indd 17 7/22/09 9:33:20 AM
7/22/09 9:33:20 AM
18
Part I: Prototype
addClassName, removeClassName, toggleClassNames
These three methods all alter the className property of a given element. All of them check to make sure
the element has the given class name. These methods are useful when you need to set classes on an
element or need to turn a CSS style on or off. Their names are self - explanatory.

< head >
< meta http-equiv=”Content-Type” content=”text/html; charset=utf-8” >
< title > untitled < /title >
< style >
.invalid { background:red;}
< /style >
< /head >
< body >
< form id=”myForm” method=”post” >
First Name: < input type=”text” id=”firstName” class=”required” > < br/ >
Last Name: < input type=”text” id=”lastName” class=”required” > < br/ >
Age: < input type=”text” id=”age” > < br/ >
< input type=”button” id=”submitButton” value=”submit” >
< /form >
< script type=”text/javascript” src=”prototype-1.6.0.2.js” > < /script >
< script type=”text/javascript” >

function init() {
var requiredInputs = $$(“.required”);
for(i = 0;i < requiredInputs.length;i++) {
$(requiredInputs[i]).insert({“after”:”*required”});
Event.observe(requiredInputs[i], “change”, function(e) {
if(this.hasClassName(“invalid”)) { this.removeClassName
(“invalid”)};
});
};
Event.observe(“submitButton”, “click”, validateUserInput);

};

function validateUserInput() {
var requiredInputs = $$(“.required”);
for(var i = 0; i < requiredInputs.length; i++) {
if(requiredInputs[i].value == “”) {
requiredInputs[i].addClassName(“invalid”);
} else {
if (requiredInputs[i].hasClassName(“invalid”)) {
requiredInputs[i].removeClassName(invalid);
};
};
};
}; Event.observe(window, ‘load’, init);
< /script >
< /body >
c01.indd 18c01.indd 18 7/22/09 9:33:20 AM
7/22/09 9:33:20 AM
Chapter 1: Extending and Enhancing DOM Elements
19
One common task for JavaScript is form validation. Here, you ’ ve set up a simple form and defined a
simple rule; users have to enter some text into elements that have the “ required ” class. You can enforce
that rule by collecting all of the elements who have the required class using the
$$()
method and
passing in a CSS selector. Once you have an array containing those elements, you iterate over the array
and check that the value property of each element does not equal an empty string. If it does, you use the

addClass
method to add the
invalid
class to the element. You then also check to see if the class already
has the
invalid
class and the user has entered text. If an element contains text and has the
invalid

class, you remove the class since it passes the validation rules, as shown in Figure 1 - 5 and Figure 1 - 6,
respectively.
Figure 1-5
c01.indd 19c01.indd 19 7/22/09 9:33:20 AM
7/22/09 9:33:20 AM
20
Part I: Prototype
hasClassName, classNames
These methods tell you what classes have been applied to the element in question. The
hasClassName

method allows you to determine if a given element has the class name in its
className
property. The

classNames
method has been deprecated; it returns an array containing the classes that have been
applied to the element.
setStyle, getStyle
These methods allow you to quickly set styles on your elements and get values for specific styles. You
may only query for styles defined by the Document Object Model (DOM) Level 2 Style Specification. To
set a style on your element, you pass in an object hash of key - value pairs of the styles you wish to set.

El.setStyle( { “font-family”: “Arial”, “color” : “#F3C” });
To get the value for a specific style, pass in the style ’ s name as an argument.

El.getStyle(“font-size”);

Figure 1-6
c01.indd 20c01.indd 20 7/22/09 9:33:20 AM
7/22/09 9:33:20 AM
Chapter 1: Extending and Enhancing DOM Elements
21
Internet Explorer returns the literal value while all other browsers return the computed value for styles.
For example, if you specify the font - size as 1em, that is what IE will return. Other browsers may
return a pixel value for the font - size.
Extending an Element with Your
Own Methods
Prototype makes it easy to add your own methods to the
Element
object using the
addMethods
method.
The
addMethods
method takes a hash of the methods you want to add. Suppose you want to add a
method to any element that will allow you to strip all the whitespace out of the element ’ s text. Here ’ s
what that function might look like:

function removeWhiteSpace(element) {
if(element.innerText) {
return element.innerText.replace(“ “, “”, “gi”);
} else if(element.textContent){
return element.textContent.replace(“ “, “”, “gi”);
}
};
First, you need to rewrite the method a little to match what Prototype expects. Then you can call

Element.addMethods
.

< body >
< div id=”myDiv” > Remove the whitespace < /div >
< script type=”text/javascript” src=”prototype-1.6.0.2.js” > < /script >
< script type=”text/javascript” >
var myFunc = {
removeWhitespace : function (element) {
if(element.innerText) {
return element.innerText.replace(“ “, “”, “gi”);
} else if(element.textContent){
return element.textContent.replace(“ “, “”, “gi”);
}
}
};

Element.addMethods(myFunc);

alert($(“myDiv”).removeWhitespace());
< /script >
< /body >
What you did here was wrap your function with an intrinsic object so that addMethods can work its
magic. You can take this one step further and return the element itself to allow for chaining.

c01.indd 21c01.indd 21 7/22/09 9:33:21 AM
7/22/09 9:33:21 AM
22
Part I: Prototype
var myFunc = {
removeWhitespace : function (element) {
if(element.innerText) {
element.innertText = element.innerText.replace(“ “, “”, “gi”);
} else if(element.textContent){
element.textContent = element.textContent.replace(“ “, “”, “gi”);
}
return element;
}
};
So now your method is ready to be used by Prototype.
Summary
In this chapter, you looked at how Prototype makes it easy to obtain a reference to DOM elements by ID,
CSS class, and their position relative to other elements. Prototype automatically adds helper methods to
your elements when possible, and adds the methods when you use the
Element.extends()
,
$()
, or

$$()
methods to get a reference to the element. Prototype also smoothes out some of the bumps
associated with positioning elements and finding out the dimensions of a given element.
c01.indd 22c01.indd 22 7/22/09 9:33:21 AM
7/22/09 9:33:21 AM

Handling Cross - Browser
Events

Event handling is one of the stickier parts of writing modern web applications. Internet Explorer
and the W3C have different event handling models. Internet Explorer supports a method called

attachEvent
for adding event handlers to elements. The W3C standard defines a method
called
addEventListener
to do the same thing. Prototype provides a cross - browser method for
wiring up your event handlers and extends the event object with several useful methods.
In this chapter, you ’ ll learn about:
Using
Event.observe
to wire up your event handlers
Responding to events, including keyboard and mouse events
Periodically firing off events
Registering Event Handlers
Prior to the rise of JavaScript frameworks, most web developers had to wire up event handlers
like so: