Errata Pro jQuery 2.0 2nd Edition By Adam Freeman

Last reviewed/updated: 06 Mar 2015 | Published: 20 Jan 2014 | Status: Active
Web browser support: Internet Explorer 10+, Edge 12+, Firefox 6+, Chrome 30+, Opera 17+

1. Introduction

Unfortunately, Apress Pro jQuery 2.0 2nd Edition by Adam Freeman (ISBN-13: 9781430263883) was not properly edited. Moreover, Apress has not published any submitted errata/suggestions. Otherwise, it would be an excellent book.

In many cases:

  • errata for the source code book listings also applies to the corresponding source code download files.
  • when a block of source code is used in multiple listings, errata for the initial block of source code also applies to the subsequent blocks of source code.

2. Chapter 1: Putting jQuery In Context

  1. Ch1 p1.

    Text reads:  I can do more work with much code.

    Change to:  I can do more work with less code.

    Why:  The wrong word is used.

  2. Ch1 p1.

    Text reads:  When I don't understand how something works or I don't quite get the result I expect, I can read through the JavaScript code and, if needed, make changes.

    Change to:  When I don't understand how something works or I don't quite get the result I expect, I can read through the jQuery source code, which is written in JavaScript, and make any needed changes.

    Why:  To clarify that jQuery is written in JavaScript.

  3. Ch1 p6.

    Text reads:  The very first thing you need is the jQuery library, which is available from http://jquery.com.

    Change to:  The source code download for the book examples includes the jQuery library. Therefore, if you are using the source code download for the book examples, then you already have the jQuery library. If you are not using the source code download for the book examples, then you need to download the jQuery library, which is available from http://jquery.com.

    Why:  To clarify that if you are using the source code download for the examples in this book, then you do not need to download the jQuery library.

  4. Ch1 p7.

    Text reads:  If you want to re-create the examples in this book, you will need a web server so that the browser has somewhere from which to load the example HTML document and related resources (such as images and JavaScript files).

    Change to:  To recreate the examples for the majority of this book, simply open the source code download .html files in a web browser. To recreate the examples for Chapters 14 and 15, you will need a web server.

    Why:  To clarify that the majority of the book does not require a web server. Instead, simply open the source code download .html files in a web browser.

    Note:  As I read more of the book, this note will be updated to include any additional chapters that require a web server.

  5. Ch1 p8.

    Text reads:  Starting in Part 3, you’ll be using Node.js in addition to a regular web server.

    Change to:  Starting in Part 3, you’ll be using Node.js.

    Why:  The majority of the book does not require a web server. Instead, simply open the source code download .html files in a web browser.

  6. Ch1 p8.

    Text reads:

    The simplest way to test Node.js is with a simple script....You should see something very similar to Figure 1-2, indicating that everything is as expected.

    Change to: 

    To install Node.js:

    1. Download Node.js from Node.js (nodejs.org). (For Windows, download the Windows Installer .msi file.)
    2. Install Node.js. (For Windows, double click the downloaded .msi file and use the default settings.)

    To test the Node.js installation, run nodetest.js:

    1. Open the terminal (Linux)/command prompt (Windows).
    2. Navigate the terminal/command prompt to the drive/directory containing nodetest.js.
    3. Type node.exe nodetest.js and press Enter.
    4. If the Ready on port 80 report appears, Node.js is properly installed and nodetest.js is running and listening on port 80. To confirm, open your web browser to http://localhost/. You should see a web page very similar to Figure 1-2.

    Why:  To clarify how to install Node.js. To clarify how to test the Node.js installation. The source code download file is nodetest.js, not Nodetest.js. The command to run nodetest.js is issued at the terminal/command prompt, not at the console prompt. The node.exe nodetest.js command to run nodetest.js requires that the terminal/command prompt is navigated to the drive/directory containing nodetest.js. Otherwise, the command to run nodetest.js requires the path to nodetest.js.

    Note:  To stop nodetest.js from running, close the terminal/command prompt.


3. Chapter 13: Working With Forms

  • Chapter 13 does not require a web server. Instead, simply open the source code download .html files in a web browser. If you decide to install a web server, the web server can be installed on your local computer. It is not necessary to install the web server on a separate server computer.
  • Chapter 13 requires Node.js. Node.js can be installed on your local computer. It is not necessary to install Node.js on a separate server computer.
  • It is strongly recommended that a computer does not have two processes listening on the same port. By default, web servers listen on port 80. By default, the Node.js formserver.js script also listens on port 80. Therefore, if you install a web server and Node.js on your local computer, either the web server or the formserver.js listening port must be changed. It is strongly recommended, and typically easiest, to keep the web server on port 80, which means changing the formserver.js listening port. Port 8080 is the typical first alternate to port 80.
  • Chapter 13 does not require a web server, but does require Node.js. Therefore, if you do not install a web server on your local computer, there should be no problem installing Node.js on your local computer and running the Node.js formserver.js script to listen on port 80. Regardless, instead of running formserver.js to listen on port 80, it will be changed to listen on port 8080. There are two reasons for this. First, if you decide to install a web server on your local computer, the formserver.js listening port will already be changed. Second, chapters 14 and 15 require a web server and Node.js, and if you decide to install the web server and Node.js on your local computer, the formserver.js listening port must be changed. Either way, to possibly avoid confusing matters even worse by configuring formserver.js to listen on a different port in chapter 13 (port 80) and chapters 14 and 15 (port 8080), it was decided to write this note and to configure formserver.js to listen on port 8080 throughout.
  1. Ch13 p310.

    Listing 13-1 reads:  var port = 80;

    Change to:  var port = 8080;

    Why:  Per the note to change the Node.js formserver.js script listening port to 8080 (above).

    Note:  Listing 13-1 is source code download formserver.js.

  2. Ch13 p311.

    Text reads:

    To run this script, I enter the following at the command line: node.exe formserver.js

    Change to:

    To run the Node.js formserver.js script:

    1. If you installed Node.js on your local computer, first change the Node.js formserver.js script to listen on port 8080 per 1. Ch13 p310 (above).
    2. Open the terminal (Linux)/command prompt (Windows).
    3. Navigate the terminal/command prompt to the drive/directory containing formserver.js.
    4. Type node.exe formserver.js and press Enter.
    5. If the Ready on port 8080 report appears, the Node.js formserver.js script is running and listening on port 8080.

    Why:  To clarify that the node.exe formserver.js command requires that the terminal/command prompt is navigated to the drive/directory containing formserver.js. Otherwise, the command to run formserver.js requires the path to formserver.js.

    Note:  To stop the Node.js formserver.js script from running, close the terminal/command prompt. Unlike nodetest.js in Chapter 1, formserver.js does not display a Node.js is working confirmation web page.

  3. Ch13 p311.

    Text reads:  I will use the example document shown in Listing 13-2, which I saved as example.html.

    Change to:  I will use the example document shown in Listing 13-2, which I saved as Listing-02.html.

    Why:  Listing 13-2 corresponds to source code download Listing-02.html, not example.html. Source code download example.html is not used in Chapter 13 and should be deleted.

  4. Ch13 p311.

    Listing 13-2 reads:

    {{#each flowers}}
    ...
    {{/each}}
    

    Change to:

    {{#flowers}}
    ...
    {{/flowers}}
    

    Why:  The Handlebars #each helper is not used and should be deleted.

  5. Ch13 p312.

    Listing 13-2 reads:  <form method="post" action="http://node.jacquisflowershop.com/order">

    Suggestion:  If you installed Node.js on your local computer, and if you changed the Node.js formserver.js script to listen on port 8080 per 1. Ch13 p310 (above), change to:  <form method="post" action="http://localhost:8080/order">

    Why:  Unless you installed Node.js on a computer that is assigned hostname node.jacquisflowershop.com, submitting the forms in Chapter 13 (by clicking Place Order) will actually submit them over the Internet to node.jacquisflowershop.com, which is not recommended.

    Note:  If you installed Node.js on your local computer, and if you changed the Node.js formserver.js script to listen on port 8080 per 1. Ch13 p310 (above), you can change all Chapter 13 instances of http://node.jacquisflowershop.com/order to http://localhost:8080/order or http://localhost:8080/. Both http://localhost:8080/order and http://localhost:8080/ work.

  6. Ch13 p312.

    Text reads:  I am using two different servers...you can see that I have entered some values into the input elements in the document.

    Change to:  Delete the text.

    Why:  Per the note on Chapter 13 requirements (above).

  7. Ch13 p317.

    Listing 13-4 reads:  $("<div id=bbox />").appendTo("body").append(total).css("clear: left");

    Change to:  Delete the line.

    Why:  The line is unnecessary and stops the form from being submitted.

  8. Ch13 p318.

    Listing 13-6 reads:

    $("form").submit(function (e) {
     if ($("input").val() == 0) {
      e.preventDefault();
     }
    });
    $("<button>jQuery Method</button>").appendTo("#buttonDiv").click(function (e) {
     $("form").submit();
     e.preventDefault();
    });
    $("<button>DOM API</button>").appendTo("#buttonDiv").click(function (e) {
     document.getElementsByTagName("form")[0].submit();
     e.preventDefault();
    });
    

    Change to:

    $("form").submit(function (e) {
     if ($("input").val() == 0) {
      e.preventDefault();
     }
    });
    $("<button>jQuery Method</button>").appendTo("#buttonDiv").click(function (e) {
     $("form").submit();
    });
    $("<button>DOM API</button>").appendTo("#buttonDiv").click(function (e) {
     document.getElementsByTagName("form")[0].submit();
    });
    

    Why:  For the jQuery Method button code, the $("form").submit(); line and the e.preventDefault();line are independent statements. The $("form").submit(); line is executed, and finishes executing, before the e.preventDefault(); line is executed. As a result, it is impossible for the e.preventDefault(); line to prevent the $("form").submit(); line from submitting. For the DOM API button code, the JavaScript submit() method does not trigger the JavaScript submit event. Therefore, it is impossible for the e.preventDefault(); line to prevent the JavaScript submit() method from submitting. In both cases, the e.preventDefault(); lines are unnecessary, serve no purpose except possibly to confuse, and, therefore, should be deleted. In sum, the only benefit to Listing 13-6 over Listing 13-5 is that Listing 13-6 demonstrates that the jQuery Method button code calls the jQuery submit() method function in the code above.

  9. Ch13 p320.

    Text reads:  As I write this, the current version is 1.1.1.

    Change to:  As I write this, the current version is 1.11.1.

    Why:  Source code download jquery.validate.js is version 1.11.1, not 1.1.1.

  10. Ch13 p321.

    Text reads:  Copy the jquery.validate.js file from the dist folder so that it is in the same directory as the example.html file.

    Change to:  Copy the jquery.validate.js file from the dist folder so that it is in the same directory as the Listing-07.html file.

    Why:  Source code download example.html is not used in Chapter 13 and should be deleted. The file used in conjunction with the jQuery Validation Plugin is Listing-07.html.

  11. Ch13 p322.

    Text reads:  The first thing I have to do is bring the template plug-in JavaScript file into the document with a script element...

    Change to:  The first thing I have to do is bring the validation plug-in JavaScript file into the document with a script element...

    Why:  The jQuery Validation Plugin is a validation plug-in, not a template plug-in.

  12. Ch13 p322.

    Text reads:  I have specified values for four options (highlight, unhighlight, errorElement, and errorClass)...

    Change to:  I have specified values for four properties (highlight, unhighlight, errorElement, and errorClass) of the options configuration object that is passed to the jQuery Validation Plugin validate() method...

    Why:  To clarify that highlight, unhighlight, errorElement, and errorClass are properties of the options configuration object that is passed to the jQuery Validation Plugin validate() method.

  13. Ch13 p324.

    Table 13-3 reads:  max: maxVal The value must be at least as large as maxVal.

    Change to:  max: maxVal The value must be no larger than maxVal.

    Why:  The description is incorrect.

  14. Ch13 p325.

    Listing 13-11 reads:

    <input name="{{product}}" value="0" required />
    ...
    required: true,
    

    Change to:

    <input name="{{product}}" value="0" />
    ...
    required: true,
    

    Why:  In order to demonstrate the required: true validation rule, the input element required attribute must be removed.

  15. Ch13 p326.

    Text reads:  As shown, you call the addClassRules method on the validator property of the main jQuery $ function.

    Change to:  The jQuery Validation Plugin validate() method returns a Validator object that is defined as a property of the main jQuery $ function ($.validator). The jQuery Validation Plugin provides a number of methods on the validator property. As shown, the jQuery Validation Plugin addClassRules() method is called on the validator property to assign validation rules to a CSS class.

    Why:  To explain what $.validator is and where it comes from.

  16. Ch13 p329.

    Listing 13-13 reads:  digits: true,

    Change to:  Delete the line.

    Why:  The validation rule specified by the line is never used because the form validation never reaches the line.

    Note:  Alternatively, to use the line, move it to after the required: true, line as shown in Listing 13-11.

  17. Ch13 p329.

    Add Tip/Note:  Please do not confuse rules (short for validation rules) with the jQuery Validation Plugin rules() method. In short, the jQuery Validation Plugin provides a number of ways to apply rules (short for validation rules) to elements. One of these is the jQuery Validation Plugin rules() method, which is used to apply rules (short for validation rules) directly to elements, as demonstrated in Listing 13-13.

    Why:  To clarify that the terms rules and validation rules are being used interchangeably. To clarify the difference between rules (short for validation rules) and the jQuery Validation Plugin rules() method.

  18. Ch13 p329.

    Text reads:  Rules applied to elements using the rules methods are evaluated before those applied using a class. For my example, this means the input elements on the top row will be checked using a min value of 10 and a max value of 20, while the other input elements will use values of 0 and 100, respectively.

    Change to:  The rules specified by the jQuery Validation Plugin rules() method and the jQuery Validation Plugin addClassRules() method are applied to elements. However, if both methods specify the same jQuery Validation Plugin check for an element, the value specified by the jQuery Validation Plugin rules() method is applied, and the value specified by the jQuery Validation Plugin addClassRules() method is not applied. For my example, this means all input elements are required, the input elements in row1 will be checked using a min value of 10 and a max value of 20, and the other input elements will be checked using a min value of 0 and a max value of 100.

    Why:  To clarify that the rules from the jQuery Validation Plugin rules() method and the jQuery Validation Plugin addClassRules() method are applied to elements. To clarify that if both methods specify the same jQuery Validation Plugin check for an element, the value specified by the jQuery Validation Plugin rules() method is applied, and the value specified by the jQuery Validation Plugin addClassRules() method is not applied. In other words, to clarify that if both methods specify the same jQuery Validation Plugin check for an element, the application of the value is a matter of one value overriding (i.e., negating) another value, not a matter of one value being evaluated before another value.

    Note:  Switching the position of the jQuery Validation Plugin rules() method and the jQuery Validation Plugin addClassRules() method in the source code does not matter.

  19. Ch13 p331.

    Listing 13-14 reads:  max: data.flowers[index].stock,

    Change to:  max: Number(data.flowers[index].stock),

    Why:  It is necessary to convert the value assigned to the max check from a string to a number. Otherwise, for example, for Aster, entering 2 through 9 results in the erroneous validation error message, Please enter a value less than or equal to 10.

  20. Ch13 p331.

    Description for Listing 13-14:  Missed opportunity to point out that the validation rules for the second argument of the jQuery Validation Plugin rules() method are defined in a variable, not as the second argument of the jQuery Validation Plugin rules() method as done in Listing 13-13.

  21. Ch13 p333.

    Text reads:  I added rules that rely on element names using the rules property of the configuration object I pass to the validate method when I set up form validation.

    Change to:  I added rules that rely on element names using the rules property of the options configuration object that is passed to the jQuery Validation Plugin validate() method.

    Why:  To clarify that rules is a property of the options configuration object that is passed to the jQuery Validation Plugin validate() method. For consistency with 12. Ch13 p322. (above)

  22. Ch13 p333.

    Description for Listing 13-15: 

    Missed opportunity to show the rulesList object:

    var rulesList = {
     aster: { max: 10, min: 0 },
     daffodil: { max: 12, min: 0 },
     rose: { max: 2, min: 0 },
     peony: { max: 0, min: 0 },
     primula: { max: 1, min: 0 },
     snowdrop: { max: 15, min: 0 }
    }
    

    Missed opportunity to show what the rules property (i.e., rules: rulesList) is interpreted as:

    rules: {
     aster: { max: 10, min: 0 },
     daffodil: { max: 12, min: 0 },
     rose: { max: 2, min: 0 },
     peony: { max: 0, min: 0 },
     primula: { max: 1, min: 0 },
     snowdrop: { max: 15, min: 0 }
    }
    
  23. Ch13 p333.

    Listing 13-16 reads:

    <input name="{{product}}" value="0" required min="0" max="{{stock}}"/>
    ...
    { name: "Peony", product: "peony", stock: "0", price: "1.50" },
    

    Issue:  max="0" is not recognized as a valid validation rule by the jQuery Validation Plugin. As a result, Peony validation against max="0" does not work and the Please enter a value less than or equal to 0. validation error message never appears. This apparent bug in the jQuery Validation Plugin is not mentioned.

    Note:  If change <input name="{{product}}" value="0" required min="0" max="{{stock}}"/> to, for example, <input name="{{product}}" value="0" max="0"/>, validation against max="0" still does not work.

  24. Ch13 p334.

    Text reads:  Please enter a value less than or equal to 12

    Change to:  Please enter a value less than or equal to 10

    Why:  The validation error message is incorrect.

  25. Ch13 p334.

    Text reads:  ...you can change the messages displayed to the user by adding a messages property to the options object passed to the validate method.

    Change to:  ...you can change the messages displayed to the user by using the messages property of the options configuration object that is passed to the jQuery Validation Plugin validate() method.

    Why:  To clarify that messages is a property of the options configuration object that is passed to the jQuery Validation Plugin validate() method. For consistency with 12. Ch13 p322. (above) and 21. Ch13 p333. (above)

  26. Ch13 p335.

    Text reads:  Within the messages object, I define a property using the name of the element I am interested in and set the value of this property to be a map between the check and the new message you want to use. In this example, I have changed the message for the max check on the elements with the names rose and primula.

    Change to:  The messages object is a property of the options configuration object that is passed to the jQuery Validation Plugin validate() method. Within the messages object, I define a property using the value assigned to the name attribute of the element I am interested in and set the value of this property to be a map between the check and the new message you want to use. In this example, I have changed the message for the max check on the elements with the names rose and primula.

    Why:  To clarify that the messages property of the options configuration object is, itself, an object. In other words, to clarify that messages is an object that is defined as a property of the options configuration object that is passed to the jQuery Validation Plugin validate() method. To clarify that you are using the value (rose and primula) assigned to the name attribute of the element, not the name of the element (which is input, not rose and primula).

  27. Ch13 p337.

    Figure 13-11:  Inexplicably, the Peony validation against max="0" is shown not working. For more on this apparent bug in the jQuery Validation Plugin, see 23. Ch13 p333. (above).

  28. Ch13 p338.

    Tip reads:  ...as shown in Listing 13-17.

    Change to:  ...as shown in Listing 13-16.

    Why:  The Handlebars template is shown in Listing 13-16, not Listing 13-17.

  29. Ch13 p339.

    Listing 13-20 reads:  return Number(value) < Number(args);

    Change to:  return Number(value) <= Number(args);

    Why:  The validation error message should not appear if the entered value is less than or equal to the stock value. The last sentence in p340 confirms it should be less than or equal to.

  30. Ch13 p340.

    Text reads:  Custom checks are created using the addMethod method, which is called on the validator property of the $ function. The arguments to this method are the name you want to assign the check, a function that is used to perform validation, and a message to show if validation fails. In this example, I have defined a check called stock, which I explain in the sections that follow.

    Change to:  Custom jQuery Validation Plugin checks are created using the jQuery Validation Plugin addMethod() method, which is called on the validator property of the $ function. The arguments to the jQuery Validation Plugin addMethod() method are a user defined name (a valid JavaScript identifier) for the check, a custom validation function that is used to perform validation, and a validation error message to show if validation fails. In this example, the first argument of the jQuery Validation Plugin addMethod() method is "stock", which means the custom jQuery Validation Plugin check is named stock. The custom jQuery Validation Plugin validation check named stock is explained further in the following sections.

    Why:  To clarify that the custom check is a custom jQuery Validation Plugin check. To clarify that the first argument of the jQuery Validation Plugin addMethod() method specifies a user defined name for the custom jQuery Validation Plugin check.

  31. Ch13 p340.

    Code reads:  min: 0,

    Change to:  Delete the line.

    Why:  Although min: 0 is a useful validation rule for this example; 1.) it does not appear in Listing 13-20, 2.) it does not appear in source code download Listing-20.html, 3.) it is not mentioned in the discussion of Listing 13-20/Listing-20.html in p340, and 4.) the first paragraph of p340 confirms it should be deleted.

  32. Ch13 p340.

    Text and code read:

    The arguments to the custom validation function are the value entered by the user, the HTMLElement object representing the form element, and any arguments that were specified when the check is applied to an element for validation, like this:

    $(elem).rules("add", {
     min: 0,
     stock: data.flowers[index].stock
    })
    

    When I applied the rule, I specified the value of a stock property from the flower data object that corresponds to the input element as the argument to the check. This is passed as is to the custom validation function:

    function(value, elem, args) {
     return Number(value) <= Number(args);
    }
    

    The value and the arguments are presented as strings...

    Change to:

    The second argument to the jQuery Validation Plugin addMethod() method is a custom validation function. The arguments to the custom validation function are the value entered by the user, the HTMLElement object representing the form element, and any arguments that were specified when the check is applied to an element for validation, like this:

    function(value, elem, args) {
     return Number(value) <= Number(args);
    }
    

    The first argument of the jQuery Validation Plugin addMethod() method ("stock") is a user defined name for a custom jQuery Validation Plugin check (stock). The jQuery Validation Plugin rules() method is passed a validation rule with a check named stock. As a result, the jQuery Validation Plugin passes the stock property value to the third argument of the custom validation function. In other words, in this example, the value of data.flowers[index].stock is passed to the custom validation function args argument.

    $(elem).rules("add", {
     stock: data.flowers[index].stock
    })
    

    In the custom validation function, the value and the arguments are presented as strings...

    Why:  The first text paragraph describes the second block of code, not the first block of code, and the second text paragraph describes the first block of code, not the second block of code. In other words, the two blocks of code need to be switched. To clarify the connection between the first argument of the jQuery Validation Plugin addMethod() method and the third argument of the second argument of the jQuery Validation Plugin addMethod() method; specifically, that the first argument of the jQuery Validation Plugin addMethod() method is a user defined name for a custom jQuery Validation Plugin check, that the second argument of the jQuery Validation Plugin addMethod() method is a custom validation function, and that the jQuery Validation Plugin passes the custom check property value to the third argument of the custom validation function.

    Note:  return Number(value) < Number(args); was changed to return Number(value) <= Number(args); per 29. Ch13 p339. (above). min: 0 was deleted per 31. Ch13 p340. (above)

  33. Ch13 p341.

    Text reads:  You can specify the message that is displayed in two ways.

    Change to:  The third argument of the jQuery Validation Plugin addMethod() method specifies a validation error message to display if validation fails. The validation error message can be specified in two ways.

    Why:  To clarify that the third argument of the jQuery Validation Plugin addMethod() method specifies the validation error message.

  34. Ch13 p344.

    Text reads:  The highlight and unhighlight options specify functions that will be used to highlight elements that contain invalid values.

    Change to:  The highlight and unhighlight options specify functions that will be used to highlight and unhighlight, respectively, elements that contain invalid values.

    Why:  Only the highlight option, not the unhighlight option, was described.

  35. Ch13 p345.

    Text reads:  I have applied a border to the parent element...

    Change to:  I have applied a border to the invalid element and its parent element...

    Why:  The jQuery selector is $(element).add($(element).parent()), not $(element).parent().

  36. Ch13 p346.

    Code reads:  index: index,

    Change to:  Delete the line.

    Why:  The line is unnecessary.

  37. Ch13 p347.

    Text reads:  I use these values to generate a specific error message using the function feature of the custom check, like this:

    Change to:  Notice that the order of the flowers in the plurals object and the data object is the same. This syncs the objects, which means that portions of validation error message text can be generated by juxtaposing references to the plurals object and the data object in a function defined as the third argument of the jQuery Validation Plugin addMethod() method, like this.

    Why:  To clarify that the order of the flowers in the plurals object and the data object is the same. To clarify that this syncs the objects, which means that portions of validation error message text can be generated by juxtaposing references to the plurals object and the data object, such as in plurals[args.data.product]. To clarify that a function, not a string, is being used to generate the validation error message from the third argument of the jQuery Validation Plugin addMethod() method.

  38. Ch13 p348.

    Text reads:  In this case, I have passed the index, the data array, and the element itself, all of which I use to piece together the message to display to the user.

    Change to:  In this case, stock is an object and the stock object is passed to the custom validation function args argument. As a result, args is an object, the properties of the stock object become properties of the args object, and I can now use the args object to generate portions of validation error message text to display to the user.

    Why:  To clarify that the properties of the stock object become properties of the args object. To clarify that the args object can be used to generate portions of validation error message text.

    Note:  index: index was deleted per 36. Ch13 p346. (above)


4. Chapter 14: Using Ajax: Part I

  • Chapter 14 requires a web server. The web server can be installed on your local computer. It is not necessary to install the web server on a separate server computer.
  • Chapter 14 requires Node.js. Node.js can be installed on your local computer. It is not necessary to install Node.js on a separate server computer.
  • It is strongly recommended that a computer does not have two processes listening on the same port. By default, web servers listen on port 80. By default, the Node.js formserver.js script also listens on port 80. Therefore, if you install a web server and Node.js on your local computer, either the web server or the formserver.js listening port must be changed. It is strongly recommended, and typically easiest, to keep the web server on port 80, which means changing the formserver.js listening port. Port 8080 is the typical first alternate to port 80.
  1. Ch14 p353.

    Listing 14-1 reads:  <form method="post" action="http://node.jacquisflowershop.com/order">

    Suggestion:  If you installed Node.js on your local computer, and if you changed the Node.js formserver.js script to listen on port 8080 per 3. Ch14 p360 (below), change to:  <form method="post" action="http://localhost:8080/order">

    Why:  Unless you installed Node.js on a computer that is assigned hostname node.jacquisflowershop.com, submitting the forms in Chapter 14 (by clicking Place Order) will actually submit them over the Internet to node.jacquisflowershop.com, which is not recommended.

    Note:  If you installed Node.js on your local computer, and if you changed the Node.js formserver.js script to listen on port 8080 per 3. Ch14 p360 (below), you can change all Chapter 14 instances of http://node.jacquisflowershop.com/order to http://localhost:8080/order or http://localhost:8080/. Both http://localhost:8080/order and http://localhost:8080/ work.

  2. Ch14 p358.

    Text reads:  For this example, this means you request the following: http://www.jacquisflowershop.com/jquery/flowers.html?country=US&state=New+York

    Change to:  For this example, this means you request the following: http://www.jacquisflowershop.com/jquery/mydata.json?country=US&state=New+York

    Why:  In Listing 14-8, Figure 14-4, and source code download Listing-08.html, the first argument to the jQuery Ajax shorthand get() method is mydata.json, not flowers.html.

    Suggestion:  If you installed the web server on your local computer, unless you assigned it a hostname, change further to: http://localhost/jquery/mydata.json?country=US&state=New+York

    Why:  If you installed the web server on your local computer, unless you assigned it a hostname, you are likely accessing the web server on your local computer using hostname localhost.

  3. Ch14 p360.

    Listing 14-9 reads:  var port = 80;

    Change to:  var port = 8080;

    Why:  Per the note to change the Node.js formserver.js script listening port to 8080 (above).

    Note:  Listing 14-9 is source code download formserver.js.

  4. Ch14 p360.

    Listing 14-9 reads:  "Access-Control-Allow-Origin": "http://www.jacquisflowershop.com"

    Source code download formserver.js reads:  "Access-Control-Allow-Origin": "*"

    Suggestion:  Leave source code download formserver.js as is.

    Why:  "*" gives the best chance for success.

    Note:  Listing 14-9 is source code download formserver.js. As described in p363, in a production environment, do not use "*".

  5. Ch14 p362.

    Text reads:

    As before, I run the script by entering the following at the command prompt: node.exe formserver.js

    Change to:

    To run the Node.js formserver.js script:

    1. If you installed Node.js on your local computer, first change the Node.js formserver.js script to listen on port 8080 per 3. Ch14 p360 (above).
    2. Open the terminal (Linux)/command prompt (Windows).
    3. Navigate the terminal/command prompt to the drive/directory containing formserver.js.
    4. Type node.exe formserver.js and press Enter.
    5. If the Ready on port 8080 report appears, the Node.js formserver.js script is running and listening on port 8080.

    Why:  To clarify that the node.exe formserver.js command requires that the terminal/command prompt is navigated to the drive/directory containing formserver.js. Otherwise, the command to run formserver.js requires the path to formserver.js.

    Note:  To stop the Node.js formserver.js script from running, close the terminal/command prompt. Unlike nodetest.js in Chapter 1, formserver.js does not display a Node.js is working confirmation web page.

  6. Ch14 p362.

    Text reads:  So, for example, if I selected one aster, two daffodils, and three roses...{"aster":"1","daffodil":"2","rose":"2","total":5}

    Change to:  So, for example, if I selected one aster, two daffodils, and three roses...{"aster":"1","daffodil":"2","rose":"3","total":6}

    Why:  The description says three roses, not two roses. The total is 6, not 5.

  7. Ch14 p364-5.

    Listing 14-10 reads:  $.post("http://node.jacquisflowershop.com/order",

    Suggestion:  If you installed Node.js on your local computer, and if you configured formserver.js to listen on port 8080 per 3. Ch14 p360 (above), change to:  $.post("http://localhsot:8080/order",

    Why:  Unless you installed Node.js on a computer that is assigned hostname node.jacquisflowershop.com, submitting the forms in Chapter 14 (by clicking Place Order) will actually submit them over the Internet to node.jacquisflowershop.com, which is not recommended.

  8. Ch14 p365.

    Text reads:  I start by using the getJSON method to obtain the mydata.json file that contains details of the flower products and then use a data template to generate elements and add them to the document.

    Change to:  I start by using the jQuery Ajax shorthand get() method to obtain the flowers.html file that contains details of the flower products and then use the jQuery slice() and appendTo() methods to generate elements and add them to the document.

    Why:  The jQuery Ajax shorthand get() method, not the jQuery Ajax type-specific convenience getJSON() method, is used. The flowers.html file, not the mydata.json file, is obtained. The jQuery slice() and appendTo() methods, not a Handlebars data template, is used to generate elements and add them to the document.

  9. Ch14 p366.

    Text reads:  For the values I entered into the input elements, the serialize method generates a string as follows: aster=12&daffodil=20&rose=0&peony=0&primula=4&snowdrop=0

    Change to:  For the values I entered into the input elements, the serialize method generates a string as follows: aster=12&daffodil=20&rose=0&peony=0&primula=4&snowdrop=4

    Why:  In Figure 14-5 and Figure 14-6, the entered value for Snowdrop is 4, not 0.

  10. Ch14 p366.

    Text reads:  In this example, I take the response from the server and pass it to the processServerResponse function, which is defined as follows:

    Change to:  In this example, the response from the server is: {"aster":"12","daffodil":"20","primula":"4","snowdrop":"4","total":40}. The response from the server is passed it to the processServerResponse() function, which is defined as follows:

    Why:  To show what the response from the server is, which is not only informative, but helps in understanding how the processServerResponse() function for loop uses the response from the server to generate the cell level div elements that are displayed in Figure 14-6.

  11. Ch14 p371.

    Listing 14-14 reads:

    <script type="text/javascript">
     $(document).ready(function () {
      $("#row1").load("flowers.html");
     });
    </script>
    

    Missed opportunity to show a side-by-side comparison that gives identical results: 1.) the jQuery Ajax type-specific convenience load() method (above), and 2.) the jQuery Ajax shorthand get() method with the jQuery append() method (below).

    <script type="text/javascript">
     $(document).ready(function () {
      $.get("flowers.html", function (data) {
       $("#row1").append(data);
      });
     });
    </script>
    
  12. Ch14 p377.

    Text reads:

    jQuery has convenient support for JSONP. All you have to do is use the getJSON method and specify a URL that contains callback=? in the query string. jQuery creates a function with a random name and uses this when communicating to the server, meaning you don't have to modify your code at all. Listing 14-22 demonstrates how to make a JSONP request.

    Change to:

    jQuery has convenient support for JSONP. As a result, compared to sending data with the jQuery Ajax shorthand post() method (Listing 14-10), all you have to do is use the jQuery Ajax type-specific convenience getJSON() method and specify a URL that contains callback=? in the query string. jQuery creates a function with a random name and uses this when communicating to the server, meaning you don't have to modify any other code as shown:

    From Listing 14-10. Sending Data With The jQuery Ajax Shorthand post() Method:

    $("button").click(function (e) {
     var formData = $("form").serialize();
     $.post("http://localhost:8080/order", formData, processServerResponse);
     e.preventDefault();
    });
    
    function processServerResponse(data) {
     var inputElems = $("div.dcell").hide();
     for (var prop in data) {
      var filtered = inputElems.has("input[name=" + prop + "]")
       .appendTo("#row1").show();
     }
     $("#buttonDiv").remove();
     $("#totalTmpl").template(data).appendTo("body");
    }
    

    From Listing 14-22. Making A JSONP Request Using The jQuery Ajax Type-Specific Convenience getJSON() Method:

    $("button").click(function (e) {
     var formData = $("form").serialize();
     $.getJSON("http://localhost:8080/order?callback=?", formData, processServerResponse);
     e.preventDefault();
    })
    
    function processServerResponse(data) {
     var inputElems = $("div.dcell").hide();
     for (var prop in data) {
      var filtered = inputElems.has("input[name=" + prop + "]")
       .appendTo("#row1").show();
     }
     $("#buttonDiv").remove();
     $("#totalTmpl").template(data).appendTo("body");
    }
    

    Notice that the callback functions are identical, and that the only required code modification involves the jQuery Ajax type-specific convenience getJSON() method, itself. Listing 14-22 demonstrates how to make a JSONP request.

    Why:  To clarify that you don't have to modify your code is in reference to Listing 14-10: Sending Data With The jQuery Ajax Shorthand post() Method. To show the relevant code from Listing 14-10 Listing 14-22 side by side. To clarify that the callback functions are identical. To clarify that the only required code modification involves the jQuery Ajax type-specific convenience getJSON() method.

    Note:  In Listing 14-10 and Listing 14-22, node.jacquisflowershop.com changed to localhost:8080 per 1. Ch14 p353 (above). In Listing 14-22, .has("input[name=' + prop + ']") changed to .has("input[name=" + prop + "]") per 13. Ch14 p378 (below). In Listing 14-22, $("#buttonDiv, #totalDiv").remove(); changed to $("#buttonDiv").remove(); per 14. Ch14 p378 (below).

  13. Ch14 p378.

    Listing 14-22 reads:  var filtered = inputElems.has("input[name=' + prop + ']")

    Change to:  var filtered = inputElems.has("input[name=" + prop + "]")

    Why:  A string concatenation operation, not a string nesting and concatenation operation, is needed. The mismatched quotes stop any flowers in the server response JSON data from being displayed.

  14. Ch14 p378.

    Listing 14-22 reads:  $("#buttonDiv, #totalDiv").remove();

    Change to:  $("#buttonDiv").remove();

    Why:  When the line is read, the divelement with id="totalDiv" attribute does not exist in the DOM.


5. Chapter 15: Using Ajax: Part II

  • Chapter 15 requires a web server. The web server can be installed on your local computer. It is not necessary to install the web server on a separate server computer.
  • Chapter 15 requires Node.js. Node.js can be installed on your local computer. It is not necessary to install Node.js on a separate server computer.
  • It is strongly recommended that a computer does not have two processes listening on the same port. By default, web servers listen on port 80. By default, the Node.js formserver.js script also listens on port 80. Therefore, if you install a web server and Node.js on your local computer, either the web server or the formserver.js listening port must be changed. It is strongly recommended, and typically easiest, to keep the web server on port 80, which means changing the formserver.js listening port. Port 8080 is the typical first alternate to port 80.
  1. Ch15 source code download formserver.js.

    Code reads:

    var port = 80;
    ...
    "Access-Control-Allow-Origin": "http://www.jacquisflowershop.com"
    

    Change to:

    var port = 8080;
    ...
    "Access-Control-Allow-Origin": "*"
    

    Why:  Per the note to change the Node.js formserver.js script listening port to 8080 (above). "*" gives the best chance for success.

    Note:  As described in p363, in a production environment, do not use "*".

  2. Ch15 p383.

    Listing 15-1 reads:  <form method="post" action="http://node.jacquisflowershop.com/order">

    Suggestion:  If you installed Node.js on your local computer, and if you changed the Node.js formserver.js script to listen on port 8080 per 1. Ch15 source code download formserver.js (above), change to:  <form method="post" action="http://localhost:8080/order">

    Why:  Unless you installed Node.js on a computer that is assigned hostname node.jacquisflowershop.com, submitting the forms in Chapter 15 (by clicking Place Order) will actually submit them over the Internet to node.jacquisflowershop.com, which is not recommended.

    Note:  If you installed Node.js on your local computer, and if you changed the Node.js formserver.js script to listen on port 8080 per 1. Ch15 source code download formserver.js (above), you can change all Chapter 15 instances of http://node.jacquisflowershop.com/order to http://localhost:8080/order or http://localhost:8080/. Both http://localhost:8080/order and http://localhost:8080/ work.

  3. Ch15 p383.

    Note reads:  This chapter relies on the same Node.js script used in Chapter 14.

    Change to:  This chapter relies on the same Node.js formserver.js script used in Chapter 14. To run the Node.js formserver.js script, see 5. Ch14 p362 (above).

    Why:  To clarify that the Node.js script is formserver.js. To clarify that the Node.js formserver.js script needs to be run. To clarify how to run the Node.js formserver.js script.

  4. Ch15 p384.

    Text reads:  ...adapted to work with the jQuery deferred object features that I describe in Chapter 35.

    Change to:  ...adapted to work with the jQuery deferred object features that I describe in Chapter 36.

    Why:  Using Deferred Objects is Chapter 36, not Chapter 35.

  5. Ch15 p384.

    Text reads:  Table 15-2 describes the members of the jQuery jqXHR object.

    Change to:  Table 15-2 describes the properties and methods of the jQuery jqXHR object, all of which also exist on the JavaScript XMLHttpRequest object.

    Why:  Members? To clarify that the listed properties and methods exist on the jQuery jqXHR object and the JavaScript XMLHttpRequest object.

  6. Ch15 p384.

    Tip reads:  ...which I explain in the section ....

    Change to:  ...which I explain in the section Handling Ajax Callbacks.

    Why:  To filling in the ....

  7. Ch15 p385.

    Text reads:  In this listing, I assign the result from the ajax method to a variable called jqxhr and use the setInterval method to write information about the request to the console every 100 milliseconds.

    Change to:  In this listing, I assign the result from the jQuery ajax() method (which is the jQuery jqXHR object) to a variable called jqxhr, and use the JavaScript setInterval() method with the JavaScript clearInterval() method to write information about the request to the console one time after 100 milliseconds.

    Why:  To clarify that the jQuery jqXHR object is assigned to the jqxhr variable. The information about the request is written to the console one time after 100 milliseconds, not every 100 milliseconds.

  8. Ch15 p386.

    Listing 15-4 reads:  var filtered = inputElems.has("input[name=' + prop + ']")

    Change to:  var filtered = inputElems.has("input[name=" + prop + "]")

    Why:  A string concatenation operation, not a string nesting and concatenation operation, is needed. The mismatched quotes stop any flowers in the server response JSON data from being displayed.

  9. Ch15 p391.

    Table 15-5 heading reads:  Table 15-5. The Ajax Event Settings

    Change to:  Table 15-5. The Complete Status Values

    Why:  The Table 15-3 and 15-5 headings are the same. The Table 15-5 heading is wrong.

  10. Ch15 p395.

    Listing 15-12 reads:  $("<div").append("<label>Events:<label>")

    Change to:  $("<div>").append("<label>Events:<label>")

    Why:  The <div> tag is missing the >.

  11. Ch15 p399.

    Listing 15-14 reads:

    var template = $("#flowerTmpl");
    template.tmpl(data.slice(0, 3)).appendTo("#row1");
    template.tmpl(data.slice(3)).appendTo("#row2");
    

    Change to:

    var tmplElems = $("#flowerTmpl").template({ flowers: data }).filter("*");
    tmplElems.slice(0, 3).appendTo("#row1");
    tmplElems.slice(3).appendTo("#row2");
    

    Why:  The code is nonsense.

  12. Ch15 p404.

    Listing 15-18:  The same nonsense code as in 11. Ch15 p399 (above).

  13. Ch15 p405.

    Text reads:  I convert the JSON data into a JavaScript array by using the jQuery parseJSON data...

    Change to:  I convert the JSON data into a JavaScript array by using the jQuery parseJSON() method...

    Why:  The jQuery parseJSON() is a method, not data.


6. Resources And Additional Information