JavaScript Application Cookbook by Jerry Bradenbaugh Unconfirmed error reports are from readers. They have not yet been approved or disproved by the author or editor and represent solely the opinion of the reader. This page was updated June 26, 2002. Here's a key to the markup: [page-number]: serious technical mistake {page-number}: minor technical mistake : important language/formatting problem (page-number): language change or minor formatting problem ?page-number?: reader question or request for clarification UNCONFIRMED errors and suggestions from readers: [xiii] About the Code, 3rd paragraph: It says to download the code, look for the DOWNLOAD link on the web page. THERE IS NOT ONE. There is an examples page but the corresponding ZIP file does not have all of the code referenced in the book. [3] The acronym EMCA should actually be ECMA (European Computer Manufacturers Association). Also needs to be changed in the index. {10} First bullet on the page: Now reads: "Placing a plus sign (+) before your string of query term(s) matches only those records containing all of the terms you enter (Boolean AND). This is incorrect. If a user enters something like this into the search engine: +javascript books the search engine code will not isolate a record with javascript and books; instead it will find all records with either "javascript" or "books." The code provided by the book and downloadable does not do a correct AND Boolean search. {12-17} Under heading "nav.html": if (searchType == (SEARCHANY | SEARCHALL)) { requireAll(searchArray); } MUST BE if (searchType == (SEARCHALL)) { requireAll(searchArray); } var refineAllString = allString.substring(0,allString.indexOf('|HTTP')); MUST BE var refineAllString = allString.substring(1,allString.indexOf('|HTTP')); In the book is the example of records.js incorrect. It starts with the url. The source ends with the url. {12-17} Under heading "nav.html": If there is a search with + the script won't work because the + isn't omitted form the compare After line 22 20 function validate(entry) { 21 if (entry.charAt(0) == "+") { 22 entry = entry.substring(1,entry.length); 23 document.forms[0].query.value = entry; //NEW!!!! 24 searchType = SEARCHALL; 25 } [13] validate method; Problem #1 on line 24 (from the text) the first argument to substring should be 4, not 5. Otherwise the first character of the first keyword is truncated. Problem #2 document.forms[0].query.value is only updated to the new values of entry inside the two while loops (lines 30 and 34). Instead it should be updated once after the second while loop (between lines 35 and 36). Otherwise trucation of + and url: are not displayed. Problem #3 line 46 in the text is correct in the current printing, but still has the incorrect code in the downloadable archive Problems #1 and #2 also need to be corrected in the downloadable archive. (13) line 45/46: Ease adding "search string" feature to the search engine. For example, if you enter "application+cookbook" (with + and no spaces between the words) the engine will find (for example) "JavaScript application cookbook" and not "New JavaScript application for cookbook." Simply add the following code in the convertString function AFTER (not before!) line 45 (line 45 is: var searchArray = reentry.split(" "); ). for (i = 0; i <= searchArray.length - 1; i++) { if (searchArray[i].indexOf('+') > -1) searchArray[i] = searchArray[i].split('+').join(' '); } [13] line 56 (also page 14 lines 60 and 80): Instead of using indexOf('|HTTP') it's better to use lastIndexOf('|'). Now you can add links to ftp:, mailto:, etc. {14} Program line #85: In the inner "for" loop, wouldn't it be more efficient to simply "break" out of the loop at this point, as the Boolean AND fails on the first occurance? The way it is written, it will continue to compare the tokenized elements of the search string to the database record, rather than just move on to the next record. {16} Code line 187 seems to be extraneous: 187 (18) The delimited strings technique. The justification seems somewhat thin. In an efficient JavaScript implementation, the memory requirements of a (global) delimited string with the same content as a global array shouldn't be significantly lower than those of the array. If profiles was a global array of arrays rather than strings, it shouldn't make any great difference, should it? Or am I missing the point here? If anything, I'd expect the constant splitting an variable declaration/disposal to be performance-degrading. [19] Paragraph beginning with "validate() determines...": Maybe I'm not experienced enough yet, but I never knew that 1, 4 and 2 represent true, false, and null, respectively. (Read that paragraph, compare the words to the global variable definitions, and that's what you may conclude). [19] Validate(): As noted by others, the syntax +HTML browser does not provide a correct AND operation....While doing the fix, perhaps the syntax can be extended to something more conventional HTML browser finds the exact match only ie words must be in sequence! +HTML browser finds HTML OR browser &HTML browser finds HTML AND browser makes the whole thing more useable for many. {24} 6th paragraph: The example that builds out the web safe color palette gives "AA" as one of the two-digit components for hex codes. "AA" is incorrect -- "00" is omitted in its place. (28) The paragraph above enumeration: second-to-last sentence is incomplete. {29} Code listing: The code is bulky. The if block is exactly the same as the else block, except for a difference in the indices. This should be reduced to a single for loop - the indices should be sorted out by ternary operator or if/else statement. {36} Potential Extensions: 1] Currently only the database is searched. this requires a lot of manual entry to make thorough searching available. A utility to generate urls.js is needed. This program will walk through a folder, adding records for each file (maybe user can limit valid file extentions) and data from that file. A simple way is to add only the meta contents area ie. stuff sent to commercial search engines. A bigger project is to condense entire page, limiting to keywords etc. I am going to do this in a regular programming language but interested if this can be done in javascript... 2] Another utility for manual or automagically produced url.js is a verifier to make sure it is correct syntax before use ..... ie paired symbols, enough delims, required fields not null , commas on all but last entry. {36} Potential Extensions/Making it harder to break: If JavaScript capabilities are turned off in browser, there is no signal to user that search will not work! Is there a method of checking browser config and issuing warning! (37) In the top paragraph, second sentence: Format "profiles". {37} "Display Banner Ads": You have used variable adImages in line one and variable ads in second line. [37] Dispaly banner: Do we write to elaborate this command to run ads? It is not clear. I used the command and it didn't work. {46} Example 2-2 line 16; Line 16 of the example closes the array with } This is incorrect and will not work. You need to use ); after the final question. This is correct in the downloadable zip of the same file. {46} Sidebar - Cheating the SRC Attribute; I really don't think that the technique described actually works. 1) If you remove the location.replace() in the cleanSlate() method then you'll see that setting the SRC attribute in the frameset to self.dummy1 does nothing. 2) If you set the value of SRC to something else [like "about:blank"] and change cleanSlate() to return some other value [rather than evaluating dummy1 & 2], the code still seems to work. It looks to me like you can't "cheat the SRC". (46) 3rd paragraph from top: using the changing of the background color of the document as an example of a method isn't incorrect, but nevertheless an unfortunate example because it's usually a setter method for a property. Not optimal if you want to explain the difference between properties and methods. {54} section on shuffle(): The formula used to calculate the number of combinations is wrong. The number of possible combinations C of K questions from a question pool with N questions (N>K) is given by: C = N!/(N-K)! where n! = 1 x 2 x 3 x ... x (n-1) x n. E.g., if you have to pick 5 questions from a pool of 10, there are 10 possible picks for the first question, 9 for the second, 8 for the third, 7 for the fourth and 6 for the fifth: C = 6 x 7 x 8 x 9 x 10 = 10!/(10-5)! = 10!/5! = 30240. If N=K, the formula simplifies to C=N! as 0!=1 by definition. Hence, the section needs a re-write. (60) second paragraph after table: The book is sold in countries throughout the world, and marking scales differ between countries (New Zealand, for example, knows no "F" rank). Others don't use letter grades at all. Generally, it is not a good idea to use examples that don't work across cultural boundaries: I once despaired over a mathematics assignment at university in Australia - not because of my ignorance of mathematics, but because I didn't know the finer aspects of cricket (similar to baseball, but less exciting - and just as unknown as baseball in most parts of Europe). (62) second paragraph: I'd like to see an explanation for why the onMouseOver event handler returns true at the end - to indicate that the event has been dealt with and does not require further handling (i.e., to prevent the status bar from being overwritten again). (66) Doing a survey is no picnic either from a server scripting point of view. (74) "Owl's box": somewhat confusing, as you sort of say "Don't confuse two things that are the same." (75) top paragraph: "document object model" is mentioned here, but no mention is made of its abbrevation "DOM", which is used later on the same page. (76) section on image-related variables: This section talks at length about absolute pathnames. While the material isn't technically incorrect, I wonder whether it is prudent to include it here. It somehow evokes the impression that the local absolute paths used here could be used in web applications. They can't - they will only work for files that are opened on a local web browser, and even there they're usually not necessary. Absolute paths are generally a bad idea and their use should be discouraged in most circumstances. (79) JavaScript Technique box: This suggests using document.all for browser detection. OK. But why is it then that almost everywhere else in the book, document.layers is used for the job? document.layers isn't mentioned here at all. Not very consistent IMHO. (88) second paragraph from top: From the text it isn't clear what "all those members" refers to. The reader is left guessing. In the fifth sentence of the bottom paragraph, the "each" is inappropriate. (93) second paragraph (the one before "Potential Extensions"), second sentence: The order of rollover and rollback is wrong - the rollback should come first. (108) top paragraph: You say that determining lyrCount is important - the reader is left wondering why? Because it's needed right away in the next line. {109} Maths vs. Memory: What about extra maths tying down the CPU? {155} Example 6-3 declaration of expiry and function SetCookie: At the bottom of pate 154, you have a declaration for expiry. However, in the function SetCookie on page 155, you appear to be using expires as the variable/object name (expires.toGMTString()). The simplest approach would appear to be to change expires.toGMTString() to expiry.toGMTString in the definition of SetCookie. {155} function SetCookie: (refer also other unconfirmed error report on same item) It seems to me that the 'expiry' variable defined on p. 154 should have been used as default expiration of the cookie, as per the discussion in the subsequent text. The program as written uses the input parameter for expiry, or "". This could be achieved, with something like: ... ((expires) ? "; expires=" + expires.toGMTString() : "; expires=" + expiry.toGMTString() ) + allowing user to override the default. (159) footnote: Sounds a bit like as if this was the only solution. However, you can give the DIV an ID and then talk to it via the ID inside the STYLE tags or wherever. By the way - did Bill G. pay you anything for saying that Netscape would have to come "on board" ;-)? (164) first paragraph, last sentence: The processes shown in the referenced figures refer to the happenings discussed in the following paragraph, not this one. In the bottom paragraph, second sentence, "current frame" presumes that we are in a frame and not in a window of our own. (169) The second item on the bulleted list: formula is wrong (typo) - see code for correct formula {In the Chapter 6 Code}: cookies.html: a "go" missing in the popup window? people.html, science.html, astronomy.html,: LANGUAGE attribute typo: "LANGAUGE"... Seems to work regardless, perhaps because Netscape only performs string matching on the first part of the attribute... Haven't checked MSIE... (194) first paragraph in "Preferences Form" section: Delete "a" in front of "text field" in first sentence and zap extra space before "list" in the same line. {198} list at top, second item: Checkboxes aren't supposed to have a third element here - that's what you say later on and from what I can tell that's how the code expects it. Format newNames() ? (203) paragraph after bullet list, fourth sentence ff.: Logic is back to front here... (211) line before newsNames list half-way down the page: "generated" is somewhat inaccurate - the code gets executed but is never explicitly generated. Following three body lines on page refer to the things above them. Also, the "layout" variables don't just refer to layout parameters. {243} end of line 89 the tag should be a {244} line 178 the line is missing the opening ' mark {245} line 202 the end of the line is missing a closing ' just before the ; {246} line 252 the + 1 at the end of the line is not needed - this makes the calculation display the wrong info {248} lines 368,371,374,377, and 380 the closing tags should be {270} Checkout and Change Bag Functions: If you just change a quantity and forget to click the change bag button, the display shows automatically all the new calculations, etc. Nevertheless, if you do the check out (not following the warning), since the bag was not updated correctly you get everything OK except the quantitites. This could generate many problems. A simple solution is to include in the Check out button the change bag so you will always change bag before the check out really proceeds. For example: {273} under 2. In line 279...; U forgot to include the name of the file where Action form parameter refers to. Pointer to bag.cgi is located in manager.html file. It is concluded from the reading that pointer is in bag.cgi file [273] no location -- outdated version, bag.cgi; Since this book is still latest version of jscookbook, you should consider the fact that, once user installs Perl (Active Perl for example)and tries to run bag.cgi perl script it will never work. Why? Because cgi-lib.pl is deprecated and CGI should be used to invoke ReadParse method. Users will have hard time figuriung this one out. bag.cgi ########## Require cgi-lib.pl use CGI; ########## Read input and assign variables CGI::ReadParse(*input); ... [284] Figure 9-6: Arrow missing from block "Cipher" to block "Transition Cipher" as in Figure 9-5. (Look at the picture, and this will make more sense). (288) first paragraph, seventh sentence, second phrase (after first comma), first word: "... except for ..." is written "... expect for ...", i.e. except is mispelled. The "p" and the "c" are reversed. (320) errata to the errata for first edition!: There were a few minor typos in the errata for the first edition but this was the most heinous, since it referenced the wrong page! Errata for p322 should actually be for page 320! p322 is a source listing so there is no paragraph, I had to look before and after (hopefully..) to find it as I did on p320. [381] Table A-43: The descriptions of the reload and replace methods are transposed. {383} "Navigator" object: The first line defines "Number" object instead of defining "Navigator" object. [387] Table A-44: The table is wrong. This is the same table as A-33 - Location, not Option Methods. {394} Table A-59 the Method indexOf is incorrectly printed as "indexof". (412) second sentence of onUnload description: The sentence reads "Executes JavaScript code when a submit event occurs; that is, when a user submits a form." This does not seem appropriate to the onUnload handler. This sentence appears to be a mistaken copy of the previous handler description, onSubmit. [INDEX] escape() function is on p.112, not p.109. ECMA is on p.3, not p.2.