Building an E-Commerce Shop Front

The ordering system

The online ordering system's information gathering takes place over three pages with a fourth page at the end displaying a final summary of the order which the user can accept or go back and alter if they are not happy. At some point in the checkout process, prior to any credit card details being transmitted to the server, we would normally switch to a secure connection using Secure Sockets Layer (SSL) which encrypts all data before it's sent to the web server.

The first of the four screens splits the main frame into two more frames

  • The top frame contains the 'welcome to the online ordering system' blurb and buttons to go to the next screen.
  • The bottom frame contains our shopping basket and serves the dual purpose of confirming what the user is about to buy and giving them an opportunity to change their mind about the quantities.

First we need to create the frameset page and save it as checkout_frame.htm

<HTML>
<FRAMESET FRAMEBORDER=0 BORDER=0 ROWS="140,*">
   <FRAME SCROLLING="NO" SRC="checkout.asp" FRAMEBORDER="NO" 
          NAME="fraCheckoutTop" NORESIZE>
   <FRAME SCROLLING="AUTO" SRC="checkoutbasket.asp" FRAMEBORDER="NO" 
          NAME="fraCheckoutBottom" NORESIZE>
</FRAMESET>
</HTML>

Now lets create Checkout.asp, which is displayed in the top part of the frameset. For the cmdNext button a function has been created for the onClick event. Here we check that there is still something left in the basket to buy (after user changes to the basket's contents) using the shopping basket in the lower frame. If there is still something in the basket then we continue to the next page.

The cmdBrowse button gives the shopper another opportunity to shop themselves penniless by going back to the category list page. The JavaScript has been included in the event definition itself as it's just one line so there's little point creating a separate function.

<!--#include file="ServerSideGlobalDef.inc"-->
<HTML>
<HEAD>
<SCRIPT language='javascript'>
function cmdNext_onClick()
{
   // if as a result of changes to the basket it's empty, inform user
   if (parent.parent.getCookie("Basket") == "")
   {
      alert("Your basket is empty  - click Continue Shopping to fill it _
             up with our excellent bargains");
   }
   else
   {
      // go to page 2 of checkout process
      this.parent.location.href="personaldetails.asp";
   }
   return true;
}
</SCRIPT>
</HEAD>
 
<BODY>
<CENTER>
<FONT FACE="Comic Sans MS" SIZE="3" color="Navy">
   Welcome to our secure online ordering system.  
   Your current basket contents are listed below. 
<FORM>
   Once you're happy with its contents click 
   <INPUT NAME="cmdNext" TYPE="button" VALUE="Next" ALIGN=top 
          onClick="cmdNext_onClick()">
   to continue <BR>
   or click 
   <INPUT NAME="cmdBrowse" TYPE="button" VALUE="Continue Shopping" 
          ALIGN=top onClick="parent.location.href='home.asp'"> 
   to return to the main screen.
</FORM> 
</FONT>
</CENTER>
</BODY>
</HTML>

Save the page as Checkout.asp

The final page in the checkout frameset is the shopping basket. It's very similar to the main shopping basket and uses the same code by incorporating the Basket.inc file, which does most of the work of displaying the basket. bReadOnly has been set to false so that the user can update the contents of the basket.

<!--#include file="ServerSideGlobalDef.inc"-->
<%
   bReadOnly = false;
%>
<HTML>
<HEAD>
</HEAD>
<BODY>
<FORM METHOD=POST ACTION="UpdateQty.asp" NAME="frmItems" 
 onSubmit="return checkQtys(this)">
<!--#include file="basket.inc"-->

</FORM>
</BODY>
</HTML>

Save the page as CheckoutBasket.asp

Obtaining the User's Details

The next two pages obtain the necessary information about the customer to process their order.

The first page obtains information regarding name and delivery address. We also obtain their e-mail address as we use that later to send them conformation of their order.

 


In between the <HEAD> tags we include a new include file - checkout_validate.inc - into this page which we'll create shortly. As its name suggests, this file contains a number of client-side JavaScript functions which will be used to validate the form's content when the user clicks the submit button. We have added an event handler for the form's onSubmit event which calls one of the validate functions inside checkout_validate.inc. The value returned by this function will prove important: if false is returned then the form's submit action will be cancelled. Also note that in the onSubmit event handler we call checkCompleted and pass it one argument - this, which in this context refers to the element that is the cause of the event firing. Here, it is the form itself.

<% @LANGUAGE="JScript" %>
<HTML>
<HEAD>
   <!--#include file="checkout_validate.inc"-->
</HEAD>

<BODY>
<CENTER>
<FORM METHOD=POST ACTION="checkoutcredit.asp" 
      onSubmit="return checkCompleted(this)">

The remainder of the page consists of the form elements contained within a table for formatting. At the top is a group of radio buttons for selecting the customer's title. When the form is submitted only the value of the radio button that has been selected by the user will be sent.

The remainder of the form consists of input boxes, each of which has its maxlength property set to match the maximum size of the relevant database field which acts as a basic form of validation. At least we know the user has not entered a string value length greater than we can store. The problem comes if we change the size of the database fields, as we must remember to update the page. This problem could be overcome by building the page dynamically using ASP script. Using ADO we could obtain the correct sizes of each field and populate the maxlengths on the basis of this information. This would increase maintainability but at the expense of scalability as server processing load would be increased significantly. Here I have gone for scalability by having static values.

The last input element in the form is a text box for the customer's country. It would help ensure valid data if we changed this to a select element with a drop down list of countries rather than a text box. For this example I kept it as a text box to save typing a long list of countries!

   <FONT FACE="Comic Sans MS" SIZE="3" color="Navy">
      Please enter your NAME, address and e-mail address below.<BR> 
   </FONT> 
   <TABLE>
   <TR>
      <TD><FONT FACE="Comic Sans MS" SIZE="2">Title</FONT></TD>
      <TD>
         <FONT FACE="Comic Sans MS" SIZE="2">
         Mr<INPUT NAME="radTitle" TYPE="radio" VALUE="Mr">
         Mrs<INPUT NAME="radTitle" TYPE="radio" VALUE="Mrs">
         Miss<INPUT NAME="radTitle" TYPE="radio" VALUE="Miss">
         Ms.<INPUT NAME="radTitle" TYPE="radio" VALUE="Ms.">
         Dr.<INPUT NAME="radTitle" TYPE="radio" VALUE="Dr.">
         </FONT>
      </TD>
   </TR>
   <TR>
      <TD><FONT FACE="Comic Sans MS" SIZE="2">First Name</FONT>
      <TD><INPUT TYPE="Text" NAME="txtFirstName" maxlength="50">
   </TR>
   <TR>
      <TD><FONT FACE="Comic Sans MS" SIZE="2">Last Name</FONT>
      <TD><INPUT TYPE="Text" NAME="txtLastName" maxlength="50">
   </TR>
   <TR>
      <TD><FONT FACE="Comic Sans MS" SIZE="2">E-mail Address</FONT>
      <TD><INPUT TYPE="Text" NAME="txtEmail" maxlength="75">
   </TR>
   <TR>
      <TD><FONT FACE="Comic Sans MS" SIZE="2">Street</FONT>
      <TD><INPUT TYPE="Text" NAME="txtStreet" maxlength="75">
   </TR>
   <TR>
      <TD><FONT FACE="Comic Sans MS" SIZE="2">City</FONT>
      <TD><INPUT TYPE="Text" NAME="txtCity" maxlength="50">
   </TR>
   <TR>
      <TD><FONT FACE="Comic Sans MS" SIZE="2">County/State</FONT>
      <TD><INPUT TYPE="Text" NAME="txtLocality" maxlength="50">
   </TR>
   <TR>
      <TD><FONT FACE="Comic Sans MS" SIZE="2">Post/Zip Code</FONT>
      <TD><INPUT TYPE="Text" NAME="txtPostCode" maxlength="15">
   </TR>
   <TR>
      <TD><FONT FACE="Comic Sans MS" SIZE="2">Country</FONT>
      <TD><INPUT TYPE="Text" NAME="txtCountry" maxlength="50">
   </TR>
   <TR>
      <TD COLSPAN=2>
         <INPUT TYPE="reset" NAME="cmdReset" VALUE="Clear form">
         <INPUT TYPE="button" NAME="cmdPrevious"  VALUE=" Back " 
                onClick="window.location.href='checkout_frame.htm'">
         <INPUT TYPE="submit" NAME="cmdSubmit" VALUE="Continue">
      </TD>
   </TR>
   </TABLE>
</FORM>
</CENTER>
</BODY>
</HTML>

Save the page as PersonalDetails.asp

The final page, as far as inputting user details is concerned, is CheckoutCredit.asp which gets that all important information we need to get our hands on the user's money!

It's smaller in terms of number of visible page elements, but more complex in terms of validation as we have a radio group, a couple of select elements with dates that need validating and a text box which must contain a valid number only. Again, all of the validation functions are in the checkout_validate.inc file we include inside the head of this page. Because there is more to check in this form than on the personal details page form, a separate function has been created to handle the onSubmit event. Using functions defined in checkout_validate.inc, it checks that the form is fully completed, the credit card number actually contains numbers and that the card expiry date is valid. If any of these checks fails then the form submit event is cancelled by returning false. As in the previous page's onSubmit, we are passing a reference to the form as a parameter of the function handling the onSubmit.

<% @LANGUAGE="JScript" %>
<HTML>
<HEAD>
<!--#include file="checkout_validate.inc"-->
<SCRIPT LANGUAGE="JavaScript">
 
function frmCredit_onsubmit(theForm)
{
   // Check form fully filled in
   if (checkCompleted(theForm) == false)
   {
      return false;
   }
 
   // Remove everything except numbers from CardNo
   theForm.txtCardNo.VALUE = numericOnly(theForm.txtCardNo.VALUE);
   
   // If removing all but numbers results in nothing then alert user
   if (theForm.txtCardNo.VALUE == "")
   {
      alert("Your have entered your credit card number incorrectly");
      theForm.txtCardNo.focus();
      return false;
   }
 
   // check credit card expiry date is valid
   if (checkCardExpDate(theForm.cboExpMonth,theForm.cboExpYear) == false)
   {
      return false;
   }
}
</SCRIPT>
 
</HEAD>
<BODY>
<FONT FACE="Comic Sans MS" SIZE="3" color="Navy">
   <P align="center">
      Please enter your credit card details below.
   </P>
</FONT> 
 
<FORM METHOD=POST NAME="frmCredit" ACTION="checkoutconfirm.asp"  
      onSubmit="return frmCredit_onsubmit(this)">

The next form elements are hidden input boxes that we populate using ASP script with the values the user submitted in the personal details page. This is how we maintain state over the course of the four pages involved in obtaining customer details except for the items ordered which remain in the basket cookie until the very last page.

   <INPUT TYPE="HIDDEN" NAME="txtTitle" 
          VALUE="<%=Request.Form("radTitle")%>">
   <INPUT TYPE="HIDDEN" NAME="txtFirstName" 
          VALUE="<%=Request.Form("txtFirstName")%>">
   <INPUT TYPE="HIDDEN" NAME="txtLastName" 
          VALUE="<%=Request.Form("txtLastName")%>">
   <INPUT TYPE="HIDDEN" NAME="txtEmail" 
          VALUE="<%=Request.Form("txtEmail")%>">
   <INPUT TYPE="HIDDEN" NAME="txtStreet" 
          VALUE="<%=Request.Form("txtStreet")%>">
   <INPUT TYPE="HIDDEN" NAME="txtCity" 
          VALUE="<%=Request.Form("txtCity")%>">
   <INPUT TYPE="HIDDEN" NAME="txtLocality"          
          VALUE="<%=Request.Form("txtLocality")%>">
   <INPUT TYPE="HIDDEN" NAME="txtPostCode" 
          VALUE="<%=Request.Form("txtPostCode")%>">
   <INPUT TYPE="HIDDEN" NAME="txtCountry" 
          VALUE="<%=Request.Form("txtCountry")%>">

The remainder of the page consists of the form elements into which the customers enter their credit card details. Card expiry date has been based upon two drop down select elements: one for the month and one for the year. This ensures that the user can enter only valid values, which is particularly important for dates as there are so many variations possible. For example, if we just used a text box, 11/1999, 11-99,11 01 are all valid but would cause us headaches if we had to deal with each possibility.

You might also like...

Comments

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“Anyone who considers arithmetic methods of producing random digits is, of course, in a state of sin.” - John von Neumann