reptile7's JavaScript blog
Friday, July 05, 2013
 
Order over the Wire
Blog Entry #294

So, a user goes to the "So, You Want A Shopping Cart, Huh?" shopping cart, adds one or more items to the cart, proceeds to the order.html page, and fills out the Customer Information / Details and Shipping Address tables. Ready to order, the user clicks the submit button at the bottom of the page.

<input type="button" value="Place Order" onclick="orderSubmit('order');">

(Technically, this button is a push button and not a submit button because its type attribute is set to button and not submit, but its purpose is to submit the order form, so I'm gonna call it a submit button.)

Clicking the button calls the order.html orderSubmit( ) function and passes it an order string argument.

function orderSubmit(type) {
    if (type == "order") {
        if ( ! (document.order.order_type.checked || checkRequired( ))) {
            window.alert("first true");
            document.order.form_action.value = type;
            document.order.submit( );
            return true; }
        else {
            window.alert("first false");
            return false; } } }


The orderSubmit( ) function gives the order argument a type identifier and then promptly checks if type and order are equal; the if (type == "order") { ... } gate can of course be removed. The rest of orderSubmit( ) comprises an if...else statement whose if clause submits the order form if the user's order.html table inputs are in order.

Go get on the phone

If the user checked the Phone Call: radio button in the Choose Order Method table, then the (document.order.order_type.checked || checkRequired( )) operation short-circuits to true, which is converted to false by the ! operator, and consequently control passes to the else clause, which pops up a first false alert( ) message and unnecessarily returns false.

Something's missing

If the user didn't check the Phone Call: radio button, then the order.html checkRequired( ) function is called.

function checkRequired( ) {
    if (!document.order.name_first.value.length ||
    !document.order.name_last.value.length ||
    !document.order.email.value.length ||
    !document.order.address1.value.length ||
    !document.order.city.value.length ||
    !document.order.state.value.length ||
    !document.order.zip.value.length ||
    !document.order.country.value.length ||
    !document.order.ship_name.value.length ||
    !document.order.ship_address1.value.length ||
    !document.order.ship_city.value.length ||
    !document.order.ship_state.value.length ||
    !document.order.ship_zip.value.length ||
    !document.order.ship_country.value.length) {
        window.alert("You have not completed all required fields:\n" +
        "Please complete the Name, Address, City,\n" +
        "County, Post Code, and Country in both the\n" +
        "Customer Info and Shipping Address sections");
        return true; }
    else { return false; } }


The checkRequired( ) function pops up the alert( ) box below
The checkRequired( ) alert( ) message
and returns true if any of the following fields in the Customer Information / Details and Shipping Address tables have been left blank:

Customer Information / Details
First Name, Last Name, Email Address, Address, City, County, Post Code, Country
Shipping Address
Recipient Name, Address, City, County, Post Code, Country

• The document.order.inputName.value.length expressions can all be shortened to document.order.inputName.value: like 0, the empty string converts to false in a boolean context.

• The alert( ) message fails to include the Email Address field of the Customer Information / Details table in its list of required fields.

Back at the orderSubmit( ) function, a true checkRequired( ) return causes the (document.order.order_type.checked || checkRequired( )) operation to return true, which is !-ed to false, sending control to the else clause, which pops up the first false alert( ) message and returns false, per the preceding section.

Submit it

If the user has entered something (not necessarily a valid something) into each of the required fields listed above, then the checkRequired( ) else clause returns false to the orderSubmit( ) function. As false || false gives false, the overall ! (document.order.order_type.checked || checkRequired( )) if condition now returns true; as a result, the if clause
(1) pops up a first true alert( ) message,
(2) assigns type/order to the value of the order form's form_action field (vide supra),
(3) submits the order form via a document.order.submit( ); command, and
(4) unnecessarily returns true.

The processing agent

<form action="mailto:youremail@address.here.com" method="post" name="order"> ... </form>

Joe sets the order form's action attribute to a mailto: URL, which would have been OK for IE 4.x or Netscape 4.x but is not OK for modern browsers: see The mailto: blues section of Blog Entry #172. For his part, Gordon much more sensibly sends the form data to a formmail.pl CGI script, which is provided in the shopcart.zip package.

<form action="http://www.mearns.org.uk/cgi-bin/formmail.pl" method="post" name="order"> ... </form>

If you're a fellow Mac user, you can open and read the formmail.pl file with the Dashcode application.

The order form's data set includes the name-value data for a set of five hidden inputs at the beginning of the form (elements[0]-elements[4]).

<input type="hidden" name="subject" value="Order Forms - NAME OF FORM HERE">
<input type="hidden" name="recipient" value="YOUR EMAIL ADDRESS HERE">
<input type="hidden" name="redirect" value="thanku.htm">
<input type="hidden" name="retailer" value="NAME OF YOUR BUSINESS HERE">
<input type="hidden" name="form_action" value="order">


The subject, recipient, and redirect name values appear in the formmail.pl code whereas the retailer and form_action names don't, and I suspect that the retailer and form_action inputs can be thrown out but I don't know for sure. Note that the form_action input's value is already order, so we can at least delete the document.order.form_action.value = type; statement in the orderSubmit( ) function.

As Joe notes in the Altering the order.html Page section of the tutorial, your role here is to replace the CAPS parts with appropriate values. The redirect input's value points to a "thank you for your order" thanku.htm page to which the user is routed after the form has been submitted; a sample thanku.htm page is provided by the shopcart.zip package.

orderSubmit( ) retool

Per the preceding discussion, the orderSubmit( ) function can be streamlined as follows:

function orderSubmit( ) {
    if (document.order.order_type.checked)
        window.alert("The 'Phone Call' radio button in the Choose Order Method section must be unchecked in order to submit the form.");
    else if (!checkRequired( )) {
        document.order.submit( );
        window.alert("Thank you!"); } }


If we're going to condition the submission of the order form on the checked status of the order_type radio button, then we should give the user a more meaningful explanation than first false for why the submission is unsuccessful when the radio button is checked, wouldn't you say? Moreover, the checkRequired( ) function pops up its own alert( ) message if the form is not complete, so there's no need to display the first false message in that case either.

An alternate checkRequired( )

It's not necessary to write out a reference expression for each required field in the checkRequired( ) function:

// From the Functional compaction subsection of the previous post:
var userInputs = document.getElementById("userTable").getElementsByTagName("input");
var shippingInputs = document.getElementById("shippingTable").getElementsByTagName("input");


function checkRequired( ) {
    var empty = 0;
    for (i = 0; i < 9; i++) {
        if (i == 4) continue;
        if (!userInputs[i].value) empty++; }
    for (i = 1; i < 8; i++) {
        if (i == 3) continue;
        if (!shippingInputs[i].value) empty++; }
    if (empty) { window.alert("Please complete all required fields."); return true; }
    else return false; }


The continue statement allows us to skip over the Address #2 field in both tables.

We'll look at the corresponding form submission code for Gordon's order.htm page in the following entry.

Comments: Post a Comment

<< Home

Powered by Blogger

Actually, reptile7's JavaScript blog is powered by Café La Llave. ;-)