JavaScript Application Cookbook By Jerry Bradenbaugh Publishe r : O'Reilly Pub Date: September 1999 ISBN: 1-56592-577-7 Pages: 476 J avaScript Application Cookboo k literally hands the Webmaster a set of ready-to-go, client-side JavaScript applications with thorough documentation to help them understand and extend the applications. By providing such a set of applications, J avaScript Application Cookboo k allows Webmasters to immediately add extra functionality to their Web sites. Copyright Editor's Note Preface What You Should Know Font Conventions Book Structure About the Code Development and Testing We'd Like to Hear From You Acknowledgments Introduction JavaScript Pros Basic JavaScript Programming Strategy JavaScript Approaches in These Applications Moving On Chapter 1. The Client-Side Search Engine Section 1.1. Execution Requirements Section 1.2. The Syntax Breakdown Section 1.3. nav.html Section 1.4. Building Your Own JavaScript Database Section 1.5. Potential Extensions Chapter 2. The Online Test Section 2.1. Execution Requirements Section 2.2. The Syntax Breakdown Section 2.3. index.html—The Frameset Section 2.4. questions.js—The JavaScript Source File Section 2.5. administer.html Section 2.6. Potential Extensions Chapter 3. The Interactive Slideshow Section 3.1. Execution Requirements Section 3.2. The Syntax Breakdown Section 3.3. Application Variables Section 3.4. The Application Functions Section 3.5. Potential Extensions Chapter 4. The Multiple Search Engine Interface Section 4.1. Execution Requirements Section 4.2. The Syntax Breakdown Section 4.3. Potential Extension: Adding User Control Chapter 5. ImageMachine Section 5.1. Execution Requirements Section 5.2. The Syntax Breakdown Section 5.3. Potential Extension: Adding Attributes to the Template Chapter 6. Implementing JavaScript Source Files Section 6.1. arrays.js Section 6.2. cookies.js Section 6.3. dhtml.js Section 6.4. events.js Section 6.5. frames.js Section 6.6. images.js Section 6.7. navbar.js Section 6.8. numbers.js Section 6.9. objects.js Section 6.10. strings.js Section 6.11. Potential Extensions Chapter 7. Cookie-Based User Preferences Section 7.1. Execution Requirements Section 7.2. Syntax Breakdown Section 7.3. prefs.html Section 7.4. dive.html Section 7.5. Potential Extensions Chapter 8. The JavaScript Shopping Cart Section 8.1. Shopping Bag Walk-Through Section 8.2. Execution Requirements Section 8.3. Syntax Breakdown Section 8.4. Step 1: Loading Shopping Bag Section 8.5. Step 2: Displaying Products Section 8.6. Step 3: Showing All the Categories Section 8.7. Step 4: Adding Products to the Shopping Bag Section 8.8. Step 5: Changing the Order/Checking Out Section 8.9. Potential Extensions Chapter 9. Ciphers in JavaScript Section 9.1. How Ciphers Work Section 9.2. Execution Requirements Section 9.3. The Syntax Breakdown Section 9.4. Potential Extensions Chapter 10. Cyber Greetings: Drag-and-Drop Email Section 10.1. Execution Requirements Section 10.2. Syntax Breakdown Section 10.3. The Server Side Section 10.4. Potential Extensions Chapter 11. Context-Sensitive Help Section 11.1. Execution Requirements Section 11.2. Syntax Breakdown Section 11.3. Potential Extensions Epilogue Appendix A. JavaScript Reference Section A.1. Browser Compatibility Section A.2. Objects, Methods, and Properties Section A.3. Top-Level Properties and Functions Section A.4. Event Handlers Appendix B. Web Resources Section B.1. Cool JavaScript Sites Section B.2. JavaScript Reference Section B.3. JavaScript FAQs Section B.4. DHTML Reference Section B.5. Document Object Model Reference Section B.6. Perl/CGI Reference Section B.7. Graphics Resources Section B.8. Similar Applications Appendix C. Using Perl Scripts Section C.1. A Perl/CGI Overview Section C.2. Getting Perl Section C.3. The Shopping Bag Script—bag.pl Section C.4. The CyberGreeting Script—greet.pl Colophon Index Copyright © 1999 O'Reilly & Associates, Inc. All rights reserved. Printed in the United States of America. Published by O'Reilly & Associates, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472. O'Reilly & Associates books may be purchased for educational, business, or sales promotional use. Online editions are also available for most titles (http://safari.oreilly.com ). For more information contact our corporate/institutional sales department: 800-998-9938 or corporate@oreilly.com . The O'Reilly logo is a registered trademark of O'Reilly & Associates, Inc. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and O'Reilly & Associates, Inc. was aware of a trademark claim, the designations have been printed in caps or initial caps. The use of the hippopotamus image in association with JavaScript is a trademark of O'Reilly & Associates, Inc. While every precaution has been taken in the preparation of this book, the publisher and author assume no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein. Editor's Note Welcome to JavaScript Application Cookbook, the second book in O'Reilly's Cookbook line. This book is different enough from the Perl Cookbook, our first offering, that it seems worth explaining. In his foreword to the Perl Cookbook, Larry Wall writes that the essence of the book is "not to cook for you (it can't) or even to teach you how to cook (though it helps), but rather to pass on various bits of culture that have been found useful " Perl Cookbook is a compendium of cooking techniques. "Finding the Nth Occurrence of a Match" is roughly equivalent to "How to Brown Butter." "Sorting a Hash" can be thought of as "Peeling Roasted Red Peppers." JavaScript Application Cookbook, on the other hand, is a pure recipe book. Think of "Shopping Bag: The JavaScript Shopping Cart" as "Mini Scallion Biscuits with Smoked Salmon Spread." Each chapter provides the code and documentation for a useful web application written (mostly) entirely in JavaScript. Prepare each recipe as Jerry has written it or just take key concepts and fold them into your own creations. (Nick Heinle's Designing with JavaScript contains smaller recipes that you can drop into a single web page, whereas this book shows you how to write full client-side web applications in JavaScript, the only scripting language that browsers natively understand.) Given these two different approaches, what's our definition of a Cookbook? A Cookbook isn't content plugged into an inflexible format; it's a book that helps you "cook up code." Expect to see more Cookbooks doing that in a variety of ways. —Richard Koman, Editor Preface Something was missing. Here I was, poring through stacks of JavaScript books and screen after screen of web sites, soaking in as much code and as many concepts as possible. But after picking up some new syntax or a slick technique from the guru de jour, I didn't know what to do with it outside the scope of the example. It was as if I had a kitchen full of ingredients, but no recipes. I had all these cool JavaScript techniques and code snippets, but I wasn't sure how to apply them to solve common web site problems. Sure, some of those books had JavaScript applications, but they weren't relevant to the Web. I mean, a blackjack game is great. So is a spreadsheet app, but I'm not going to put those on a web site any time soon. So here are some recipes. Not just for checking a browser's identity or doing an image rollover, but full-blown applications that you'll actually want to use on your web site. The applications here are pretty much out of the box. You can copy them into a folder on your web server (or local computer) and run them immediately. The chapters that follow are packed with JavaScript that helps you help users perform common web tasks, such as site searching, collecting survey info, creating image rollovers, viewing online presentations, cyber shopping, and plenty more. Of course, you'll want to modify them to make them work best for you, but they're more or less ready to go. In addition, each application comes with a lengthy explanation so that you can check out what makes each one work. What You Should Know This is not a beginner's book. You will not learn JavaScript here. You will learn how to use it. You don't have to be a three-year JavaScript veteran, but if info.replace(/</g, "<"), new Image(), and var itemArray = [] seem obscure, make sure you at least have a JavaScript syntax book handy as you work. Try O'Reilly's JavaScript: The Definitive Guide, by David Flanagan. Font Conventions Italic is used for filenames, directory paths, URLs, and the names of objects, variables, arrays, and other entities. Constant Width is used for HTML tags, code examples, code fragments, functions, and other references to code. Constant Width Italic is used for text that the user enters and for replaceable text. Constant Width Bold is used for text that is displayed on the screen. Book Structure For the most part, each chapter follows a similar template with the following four sections. Execution Requirements This short section lays out the environment required to run the application. This usually means which versions of Netscape Navigator or Microsoft Internet Explorer are compatible. The section also offers some perspective by discussing any scalability or monitor resolution issues. Syntax Breakdown When you're done playing with an application and want to see what's "under the hood," check here. This is where you'll find the code discussion, mostly line-by-line. This is by far the longest section of the chapter, so get comfortable before you tackle these. JavaScript Techniques As we make our way through the syntax breakdown, there will be good points to stop and highlight a technique that you can add to your bag of web knowledge. Potential Extensions This section suggests ways you can extend each application for even more impressive functionality. Sometimes I make suggestions, sometimes I offer code. And sometimes I just can't help myself and write the code for you—which is included in a code archive that you can download. Either way, this should get the creative juices flowing so you don't get stuck, saying, "Cool, how can I put that on my site?" About the Code This book is all about applications. It's no surprise, then, that you are going to see JavaScript code— lots of it. Some applications contain several hundred lines, and most of them are on the pages following the code. In some cases, the code is even repeated so you don't have to always flip back and forth between the discussion and the code. One of the drawbacks of putting the code in the book, is, well, putting it in the book. There just isn't as much page width to fit all the code as we'd like on one line. The code often wraps onto the next line, and the next. To keep the readability higher, the comments have also been left out, though you'll find plenty of comments in the files themselves. The editing staff has gone to great pains to neatly format the code within the page constraints, but in some cases you might find looking at the files in your text editor easier on your eyes. Since we expect you to use this code, not just read it, we've made all of the applications available in a zip file that you can download from the O'Reilly web site. Go to http://www.oreilly.com/catalog/jscook /index.html and look for the "Download" link. You'll see references to this file in each chapter. Development and Testing In no particular order, I've listed the hardware and software used in developing the code for this book. For the most part, everything has been tested for a Windows environment, but Unix and Mac users should encounter few, if any, problems. Hardware: IBM ThinkPad 55/P75/16M, Compaq Presario/P233/100M, IBM Aptiva C23/P120/128M, DELL OptiPlex/P2-266/128M, Sun SPARC 20 Operating Systems: Win95, WinNT Workstation 4.0, WinNT Server 4.0, Solaris 2.5 Browsers: Netscape Navigator 3.0, 3.04 Gold, 4.0, 4.04, 4.07, 4.08, 4.5; Microsoft Internet Explorer 3.0, 3.02, 4.0, 4.01, 5.00 Resolutions: 640 x 480, 800 x 600, 1024 x 768, 1152 x 900, 1280 x 1024 Of course, not every application was tested under all these conditions. However, I tried to code defensively enough so that the vast majority of user environments would be accommodated. We'd Like to Hear From You We have tested and verified all of the information in this book to the best of our ability, but you may find that features have changed (or even that we have made mistakes!). Please let us know about any errors you find, as well as your suggestions for future editions, by writing: 707-829-0104 (fax) You can also send us messages electronically. To be put on the mailing list or request a catalog, send email to: info@oreilly.com To ask technical questions or comment on the book, send email to: bookquestions@oreilly.com Acknowledgments My name is on the cover, but it gives me great pride to credit others in the creation of this book. I'd like to extend heartfelt gratitude to these folks for making this possible. On the technical side, I'd like to thank Steve Quint and James Chan, Jim Esten, Bill Anderson, Roland Chow, Rodney Myers, Matthew Mastracci, Giorgio Braga, Brock Beauchamp and the others who have let me tap into their massive wealth of JavaScript and other programming experience whenever I got into a bind. And I must pay homage to Patrick Clark, whose code was the inspiration for the online help application. Thanks to Richard Koman, my editor, for keeping an open ear to my ideas and enabling me to put them on paper, and to Tara McGoldrick and Rob Romano for all their behind-the- scenes labors. On the emotional side, I'd like to sincerely thank my wife, Róndine Bradenbaugh, for putting up with me staring at a PC monitor and typing feverishly, night after night, for months. I'd like to thank my parents for their support and for encouraging me to develop my writing skills. I'd also like to thank someone else who often gets overlooked—you, the reader. It's you who leave your hard-earned cash at the bookstore that makes all of this possible. There are plenty of JavaScript books available. You chose mine. Thanks, big time, for giving me the opportunity to give you your money's worth. Introduction This is an unusual book. It's about writing large web applications in JavaScript. That's not what most people think JavaScript is used for. JavaScript is normally (or at least used to be) associated with just adding image rollovers, visitor hit counters, browser detection, and the like. JavaScript Pros No one language or technology has the market cornered as the best solution for developing web applications. Each has its pros and cons. Recent advances in JavaScript and other proliferating technologies, such as DHTML, Java, and even Macromedia's Flash, have positioned JavaScript to capitalize on these tools and create relatively powerful web solutions. Here are some other reasons that argue strongly for developing applications in JavaScript. Easy to Learn, Quick, and Powerful Since JavaScript is fairly easy to learn, you can begin using it right away. This is perfect for adding some quick functionality to a site. Once you have the basics down, creating full-featured applications isn't much further away. JavaScript also rates as pretty powerful for a high-level language. You can't do anything at the machine level with it, but it does expose many features of browsers, web pages, and sometimes the system on which the browser is running. JavaScript doesn't have to be compiled like Java TM or C, and the browser doesn't need to load a virtual machine to run the code. Just code it and load it. JavaScript also works from an object-oriented architecture similar to Java and C++. Features such as constructor functions and prototype-based inheritance add a layer of abstraction to the development schema. This promotes much greater code reusability. Ubiquity JavaScript is by far the most popular scripting language on the Web. Not thousands, but millions of web pages around the world contain JavaScript. JavaScript is supported by the most popular web browsers (though we're really talking about JScript in MSIE). Both Netscape and Microsoft seem to be continuously seeking ways to extend the language's functionality. This kind of support means that JavaScript stands a better chance of being supported by the vast majority of browsers used by your web site visitors. Reducing the Server Load This was one of the first reasons that web developers adopted JavaScript. It can perform many functions on the client side that used to be handled strictly on the server. One of the best examples of this is form validation. Old-school coders might remember back just a few years when the only way to validate user input of an HTML form was to submit the user information to the web server, then toss that data to a CGI script to make sure the user entered everything correctly. If the data had no errors, the CGI script processed as normal. If errors were encountered, the script returned a message to the user indicating the problem. While this is one solution, consider the overhead involved. Submitting the form requires another HTTP request from the server. That trip across the Net is also followed by executing the CGI script again. Each time the user makes a mistake in the form, this process repeats. The user has to wait until the error message arrives to learn of the mistake. Enter JavaScript. Now you can validate the elements of a form before the user sends it back to the web server. This reduces the amount of transactions via HTTP and significantly reduces the chance of user error with the form input. JavaScript can also read and write cookies , an operation once performed exclusively by the header-setting power of the web server. JavaScript Is Growing When JavaScript 1.1 came out, there was mass hysteria because of the new things called the IMAGE object and the DOCUMENT.IMAGES array that let us create image rollovers. Then JavaScript 1.2 hit the scene. The floodgates were wide open. DHTML support, layers, and a slew of other enhancements bowled over many coders. It was too good to be true. It hasn't stopped there. JavaScript has since become the design model for EMCA-262 , a standardized general-purpose scripting language. At least one company has developed an environment that runs JavaScript from the command line. Macromedia has incorporated custom JavaScript calls in its Flash technology. Allaire's ColdFusion has integrated JavaScript into its XML-based technology, Web Distributed Data Exchange (WDDX). JavaScript is getting better and better. More features. More options. More hooks. Maybe You Have No Choice Sometimes it's the only way. Suppose your ISP doesn't allow CGI scripts to be executed. Now what are you going to do if you want to add that forms-based email or take advantage of cookie technology? You have to look to client-side solutions. JavaScript is arguably the best one for adding server-side functionality to a "client-side only" web site. There Are Probably More I can think of a few more advantages, and you could surely add to the list. The point is: in spite of the advantages of server-side technology, JavaScript applications have their place on the Net. Basic JavaScript Programming Strategy Whenever you build an application, JavaScript or not, it is in your best interest to have a strategy. This helps organize your thoughts and code and also speeds the development and debugging process. There are scores of worthy publications that get down to the nitty-gritty of step-by-step application design, and you'll probably want to adopt a strategy that works best for you. So I won't spend too much time here. Keeping the following things in mind, however, before, during, and after you code your way between the <SCRIPT></SCRIPT> tags will surely save you some headaches. It's pretty simple: just answer what?, who?, and how? What Are the Application Features? First, what is the application going to do? Be as specific as possible. What will the application not offer? Suppose you want to develop an HTML form to send email. Consider these questions. • How many fields will the form include? • Will users enter the email address themselves or choose it from a select list? • Do you want to validate the form input before sending it? If so, what are you going to validate? The message? The email address? Both? • What happens after the email is sent? Do you want to redirect the user to another page or have nothing happen at all? This barrage of questions could certainly continue. The good news is that if you take the time to consider such questions, you will have a much better idea of what you want. Who Is Your Audience? Identifying who will be using the information is vital for determining the app's capabilities. Make sure you have precise answers to at least the following questions: • What browsers will people be using? Netscape Navigator? What versions: 2.x, 3.x, 4.x, or higher? • Is the application going to be used on the Internet, intranet, or locally on individual computers? • Can you determine the monitor resolution that most users will have? • What type of connectivity will most users have? 56K modem? ISDN? Fractional T-1? T-3? Other than the question about browser type, you might think that these questions have nothing to do with JavaScript. "Connectivity . . . who cares? I don't need to configure a router to do this stuff." That's true. You don't need to be Cisco-certified. Let's run through those questions, one by one, though, and see why they are important to you. The browser issue is arguably the most pressing. In general, the more recent the browser, the more recent the version of JavaScript you can use. For example, if your audience is confined to NN 2.x and MSIE 3.x (though I can't think why this would be the case), you can automatically rule out image rollovers. The versions of JavaScript and JScript in both browsers don't support the Image or document.images objects. [1] [1] Some MSIE 3.x browsers for the Mac do support image rollovers. Since most people have upgraded to at least the 4.x version of these browsers, image rollovers are acceptable. But now you have to reckon with dueling object models. That means you have to make your applications cross-browser compatible or write separate applications for each version (which can be a lesson in futility). Where will the application reside? The Internet, an intranet, or maybe on someone's PC converted into a kiosk? The answer to this question will in turn provide many more clues to what you can get away with. For example, if the application will run on the Internet, you can rest assured that just about any type of browser imaginable will hit your site and use (or at least try to use) the app. If the application is restricted to an intranet or a local machine, chances are some kind of browser standard is in place. At the time of this writing, I'm doing consulting work for a firm that is one big Microsoft shop. If my intranet code chokes in Navigator, I don't care; users must have MSIE. Monitor resolution is another major issue. If you've included a table 900 pixels wide on your page, and users only have an 800 x 600 resolution, they're going to miss out on some of your hard work. Can you count on a fixed resolution for all visitors? If this is for the Internet, your answer is no. If the audience is on an intranet, you might be in luck. Some corporations standardize PC hardware, software, browsers, monitors, and even resolutions. Connectivity issues also have an effect. Suppose you've whipped up a mind-blowing image rollover sequence that would give Steven Spielberg's movie animations a run for their money (if so, maybe you and I should . . . umm . . . collaborate). Pretty cool, but users with 56K modems could probably go out and see a movie before your code loads all those images. Most users understand that the Net can get [...]... we build a color palette in a table of all 216 web- safe colors—one in each cell? Nested for loops to the rescue This time, however, we'll only use a single-dimension array Using hexadecimal numbers, web-safe colors come in six-digit groups—two digits for each color component—such as FFFFF, 336699, and 99AACC The two-digit pairs that make up all web-safe colors are: 33, 66, 99, AA, CC, and FF Let's... decide whether JavaScript could pull off the functionality I wanted This was pretty easy If the answer was yes, then I went for it If not, it was into the JavaScript landfill Once I singled out an application, it was off to the text editor Here are some of the conventions I used for the codes Reuse as Much Code as Possible This is where JavaScript source files come into play That is, these applications... applications make use of the JavaScript source files loaded in using the following syntax: someJSFile.js contains code that can be used by multiple scripts—any one that uses the above syntax Many of the applications throughout the book use JavaScript source files This just makes sense Why reinvent the wheel? You can also use JavaScript source files... local JavaScript variables die after a function finishes executing, the memory they occupy is returned to the system If a variable doesn't need to last for the life of the application, I make it local instead of global Moving On This should give you a general picture of how to go about building your JavaScript applications, and how I built mine Now let's get to the fun stuff Chapter 1 The Client-Side... (refineAllString.indexOf(allElement) == -1 ) { allConfirmation = false; continue; } } if (allConfirmation) { findings[findings.length] = profiles[i]; } } verifyManage(findings); } JavaScript Technique: Nested for Loops Both the searching functions allowAny() and requireAll() use nested for loops This is a handy technique to iterate multidimensional arrays as opposed to single-dimension arrays (JavaScript arrays are technically one-dimensional... couple of links from the homepage will enable users with T-1 connections to load your image rollover spectacular, or users with modems to view the benign version JavaScript Approaches in These Applications Those are the basics You'll see that I incorporated a couple of these strategies in the applications in this book I should also mention the JavaScript approaches, or coding conventions That'll give... Results: ' + (reference + 1) + ' - ' ); docObj.writeln( (reference + offset > results.length ? results.length : reference + offset) + ' of ' + results.length + '' + ''); docObj.writeln('\n\n< !- Begin result set / /-> \n\n\t'); That might look more organized, but each of those method calls means a little more work for the JavaScript engine Think about it... better capacity 1.2 The Syntax Breakdown This application consists of three HTML files (index.html, nav.html, and main.html ) and a JavaScript source file (records.js) The three HTML files include a tiny frameset, a header page where you enter the search terms, and a default page in the display frame with the "how-to" instructions 1.3 nav.html The brains of the application lie in the header file named nav.html... nav.html In fact, the only other place you'll see JavaScript is in the results pages manufactured on the fly Let's have a glimpse at the code Example 1.1 leads the way Example 1.1 Source Code for nav.html 1 2 3 Search Nav Page 4 5 6 7 < !-8 9 var SEARCHANY = 1; 10 var SEARCHALL = 2;... a bit more organized to have this generated in a JavaScript source file > You can also use this database in other search applications simply by including records.jsin your code In addition, I'd hate to have all that code copied into an HTML file and displayed as source code JavaScript Technique: Using Delimited Strings to Contain Multiple Records This application relies on searching pieces of information, . ready-to-go, client-side JavaScript applications with thorough documentation to help them understand and extend the applications. By providing such a set of applications, J avaScript Application. JavaScript Application Cookbook By Jerry Bradenbaugh Publishe r : O'Reilly Pub Date: September 1999 ISBN: 1-5 659 2-5 7 7-7 Pages: 476 J avaScript Application Cookboo k . the advantages of server-side technology, JavaScript applications have their place on the Net. Basic JavaScript Programming Strategy Whenever you build an application, JavaScript or not, it