Application Walkthrough

Now, it's time to take a look at the code in this application, step-by-step. First, we'll show you how the WAP header changes when dealing with Web application platforms, such as JSP, ColdFusion, or ASP. Next, we'll walk through the application in the sequence a real-world user would view the cards and decks involved, demonstrating how that user can access database tables from WML.

Changing the WAP Header—home.asp

To begin coding home.asp, we'll use the standard WAP header, but we'll include one additional line of text as the preamble. This line of text makes the transition from ASP to WML. If we were to leave the content type as just asp the WAP device would probably present the user with an error message complaining about the type. Therefore, we include the following header with a preamble to make the transition to an acceptable MIME-type using ASP:

<% Response.ContentType = "text/vnd.wap.wml" %>
<!--- Defines XML Version and Document Data Type --->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.2//EN"
"http://www.wapforum.org/DTD/wml12.dtd">

From this point on, any time we discuss an additional file, we will not explain the WAP header because it rarely changes.

Tip

Your WAP header will almost always be exactly the same. If your programming envi ronment supports macros, it's a good idea to assign the WAP editor to a hot key for faster development.


Tip

Most integrated debugging environments offer some sort of modularity whether it be through code snippets, custom tags, or module files. It would be advisable to put this header into an easily referenced, common file location.


To create this application, we first agreed on what our home card was going to look like. The following code is the first deck the user will view. It will allow the user to select how he wants to sort the directory's listings: by company, first name, or last name. After the user selects the top-level menu item, he will move through other cards within the deck and further narrow the selections, eventually reaching the information needed.

Tip

Planning the architecture and navigational feel of a WAP application is like designing a set of Web pages. First design the home "page" or card. This card will dictate the overall look-and-feel of the application, which will be carried through each subsequent card.


After our header, the next piece of code is the <wml> tag, after which we can begin to code the first card.

The first card's title is "Choose an option." Because many WAP devices will display the title, it is important to use a title that clearly communicates something about the page to the user. For example, "Option" would not be a good title because it does not give the user any specific information about how to respond to the card. The User Directory home display is shown in Figure 16.3.

<wml>

  <card id="home" title="Choose an option">

   <p align="center">
     View:<br/>
     <a href="#company">By company</a><br/>
     <a href="stafflist.asp?type=fname">By first name</a>
     <a href="stafflist.asp?type=lname">By last name</a>
   </p>

  </card>

Figure 16.3. The User Directory application home card.


In the preceding card, there are three options for the user. The user can either view directory entries "By company," "By first name," or "By last name." You will notice that before each of the search options we've included an anchor tag <a href="...">. This tag will serve as our hyperlink tag. Therefore, when the user chooses "By company," our WAP device will move to the card with the id="company".

Tip

Just as with a card title, the clarity of a card ID is important. IDs are primarily used to link between cards, so meaningful but short names are ideal. Choosing an ID like "Sort_information_by _company_name" is too long and makes the code look confusing.


Each of our next three cards corresponds to a viewing option that was presented on the first card. First we'll look at the card that would appear if the user chose to view the names in the directory by the company for which they work.

Tip

Because the WAP device only needs to download a deck once, it is best to create many cards in a single deck rather than creating many decks with only a few cards each; doing so reduces transmission times.


Select by Company

The next part of this card defines a second soft key, called Back, which allows the user to go back to the home card.

<do type="accept" label="Back">
       <go href="#home"/>
     </do>

The last section of this card presents options for viewing the names that correspond to each company in the database (for example, Gearworks.com, Allaire, and Phone.com). The company names are being pulled from the Company table in our database. For each record that this resultset returns, we establish an anchor tag that passes the record's company identification number. You will also notice that we are calling the same link. This is due to the dynamic nature of the application. We leave it to the card to create the WML content based on the passed company_id parameter. This section first prompts the user to select the company for which she would like to view information.

<%
    set dbConn = Server.CreateObject("ADODB.Connection")
         dbConn.open("dsn=staffdir")
    company_sqlStr = "SELECT * from company"
    set company = dbConn.execute(company_sqlStr)
    %>
  <card id="company" title="View by Company">

     <do type="accept" label="Back">
       <go href="#home"/>
     </do>

    <p align="center">
    Select a company:<br/>

    <%
        While not company.eof
    %>

            <a href="staff.asp?company_id=<%=company  ("company_id")%>"><%=company("name")
%></a>

    <%
            company.MoveNext
        Wend
    %>

    </p>

  </card>

View Company Detail

At the next level of detail, the user can access company-specific information, as shown in Figure 16.4. As an example, let's suppose the user chose to view only the people in the directory that are employed by Gearworks.com. Choosing that option would send the user to the card staff.asp?company_id=1. This card will dynamically create the staff list for Gearworks.com.

The staff.asp card begins again by setting up the Select soft key. The card also sets up the Back soft key, but the Select soft key is significantly more complicated. It references an entirely different WML deck: staff-detail.asp. This passes the ID of the employee variable that is controlled by a <SELECT> input box.

The fundamental code of this card should be familiar to us now:

<card id="codetail" title="Staff Directory">
      <do type="accept" label="Select">
           <go href="staff-detail.asp?staff_id=$employee">
           </go>
      </do>

     <do type="accept" label="Back">
       <go href="home.asp"/>
     </do>

Figure 16.4. The Staff Directory card.


After the base, we have a somewhat more complicated interface. The reason for this is that we need to establish the list of users that are employed at this company with the company ID that was passed to the staff.asp card. To do this, we need a more complicated query statement, as follows:

    <%
    set dbConn = Server.CreateObject("ADODB.Connection")
         dbConn.open("dsn=staffdir")
    staff_sqlStr = "SELECT company.name,staff.* from company INNER JOIN staff on company
.company_id = staff.company where staff.company = " & Request.QueryString("company_id")
    set staff = dbConn.execute(staff_sqlStr)
    %>

You'll notice from this query that we are joining the two tables together. This is a more advanced database technique, but the result is that we are querying a merged Company and Staff table. More specifically, we are querying a merged table in which the company ID is equal to the value that was passed to the staff.asp card. Finally, we execute this query. With the results that are returned, we iterate through the query and produce a <SELECT> input tag that will list all of the users as well as offer links to the staff-detail.asp page, passing that user's ID as a parameter.

<onevent type="onpick">
        <go href="http://localhost/sams/ch16/staff-detail.asp?staff_id= <%=staff
("staff_id")%>"/>
        </onevent>

     <p align="center">
       <select name="employee">
           <%
           While not staff.EOF
           %>
           <option value="<%=staff("staff_id")%>">
                      <%=staff("fname")%>&nbsp;
                      <%=staff("lname")%>
                </option>
           <%
           staff.movenext
           Wend
           %>
     </select>
    </p>
  </card>

Dynamic Access—staff-detail.asp

Finally we're getting to the cool stuff: building some dynamic functionality into our application. By calling up the staff-detail.asp file instead of a static WML card, we can use parameters. Thus, we can take very specialized action to make the code dynamic. We will begin by establishing a dynamic card for the staff-detail.asp deck.

This card is fairly robust in terms of the features it brings to the application. You will note on this card that we are dynamically querying the database and presenting the user with the information regarding that staff member (see Figure 16.5). That information ultimately drives two soft keys. One allows the user to place a phone call to the staff member, and the other allows the user to send an email to the staff member. Both of these soft keys pass the staff_ID, which allows the email and calling pages to correctly identify the individual with whom the user would like to make contact.

  <card id="options" title="Staff Directory">

   <do type="accept" label="Call">
       <go href="call.asp?staff_id=<%=Request.QueryString("staff_id")%>"/>
   </do>

   <do type="option" label="E-mail">
          <go href="email.asp?staff_id=<%=Request.QueryString("staff_id")%>"/>
   </do>

After we present the user with the soft keys, we want to display the user specific data. To do this, we query our database for the user that has a staff_id matching the value that was fed to staff_detail.asp. From these results, we then prompt the user with the appropriate and accurate information regarding that user.

       <%
       set dbConn = Server.CreateObject("ADODB.Connection")
            dbConn.open("dsn=staffdir")
       staff_sqlStr = "SELECT * from staff where staff_id = "&Request.QueryString("staff_id")
       set staff = dbConn.execute(staff_sqlStr)
    %>

   <p>
   <%=staff("fname")%>&nbsp;<%=staff("lname")%><br/>
   E-mail: <i><%=staff("email")%></i><br/>
   Phone: <i><%=staff("number")%></i>
   </p>

  </card>

</wml>

Figure 16.5. The Staff Detail card.


You'll notice in this code that we elected to surround the email and phone number in italics to separate the field definition Phone from the phone number in a visual manner.

Tip

Use font formatting to keep your choices and text easily distinguishable, otherwise, data onscreen tends to flow together due to interface characteristics of WAP devices.


Executing a Phone Call—call.asp

Because they are similar in function to those cards previously discussed, we'll let you examine the other search cards and company cards for yourself. But let's change gears and look at some of the neat functionality WAP brings to the application. In particular, let's examine the call.asp deck.

The call.asp deck allows users to call any employee in the directory without having to manually type in their phone number. The call.asp deck is quite simple, consisting of only a single card with two soft keys. Earlier, some of you might have wondered why we elected to pass the call.asp card a parameter of the employee number. This field was created so that the phone could directly call the user that was selected without requiring the user to retype the entire number.

Note

Because this is our first application, we elected to simplify the application by having it execute a database query for each "call" we make. This is not necessarily the best practice because it forces an extra interaction with the server. By embedding URL parameters in the card, we could have streamlined this process, but the code would have involved some nested queries, which we left out for clarity.


To place a call, we are making an assumption that the WAP device is a phone. Although most of the WAP devices are cellular phones, this is not always an acceptable solution because many of the PC-based WAP browsers itemized in Appendix B, "WMLScript Library Reference," do not have that functionality.

We'll skip the WAP header information here since it is identical to the previous deck in this application. After the WAP header, you'll see we establish both of our soft keys for this card as shown in Figure 16.6.

<card id="phone" title="Call">

    <%
    set dbConn = Server.CreateObject("ADODB.Connection")
         dbConn.open("dsn=staffdir")
    staff_sqlStr = "SELECT * from staff where staff _id = "&Request.QueryString("staff_id")
    set staff = dbConn.execute(staff_sqlStr)
    %>

    <do type="accept" label="Call">
       <go href="wtai://wp/mc;<%=staff("number")%>"/>
    </do>
    <do type="accept" label="Back">
       <go href="home.asp"/>
    </do>

    <p>
    Call <%=staff("fname")%>&nbsp;<%=staff("lname")%>?<br/>
    <%=staff("number")%>
    </p>

</card>

Figure 16.6. Executing a phone call with the call card.


The first soft key sends the user to

wtai://wp/mc;number

This link calls a system command that commands the phone to dial the phone number that was sent to it. Therefore, by pressing the Call soft key, the user would connect to the number that was stored in the query results called staff with a field called number. The second hot-key will send the user back to the home.asp deck to the option card and re-display the choices for searching.

Tip

If you are going to use the system command to make calls, remember to include the area code and country code in the command. Because WAP devices function in different regions of the world and country, without these codes, you will not be able to predict who the user will be calling.


Sending Email—email.asp

Switching gears again, let's examine how this user directory enables a user to email the employee of their choice (see Figure 16.7). Although this is not a standard feature of WAP, email functionality is provided to us using an additional tool, such as ASP, JSP, or ColdFusion. We'll walk through the WML code first and then take a look at the VBScript code we've included to actually send the email.

Figure 16.7. Sending an email with the email card.


In addition to the normal header information, we included a meta-tag on this page. This meta-tag governs cache control. If we set the cache control to zero, we can ensure the WAP device is not accessing the card from past memory and passing old and improper data to the card.

Note

Developers should always take advantage of caching unless absolutely necessary. Overriding caching can have a negative impact on the performance of the application. Overriding caching means that the browser is forced to return to the server for new data at every request. In this case, this is necessary, but in many cases it is not. Returning to the server to make the additional request can also place additional load on the server environment.


<head>
<meta http-equiv="Cache-Control" content="max-age=0"/>
</head>

  <card id="email" title="E-mail">

To send an email from any device, the following fields are needed:

Sender

Email address of recipient

Subject

Message

We're going to simplify this significantly by making an assumption that the user sending the message will always go by the username WAP Device. Additionally, the user has already chosen whom he wants to email, so we do not need to collect that field. For better usability, however, we will display the field for the user to confirm. Finally, the user needs some way to enter the subject and message. Looking at the email.asp deck, we provide the user with that specific interface.

    <%
    set dbConn = Server.CreateObject("ADODB.Connection")
         dbConn.open("dsn=staffdir")
    staff_sqlStr = "SELECT * from staff where staff _id = "&Request.QueryString("staff_id")
    set staff = dbConn.execute(staff_sqlStr)
    %>

        <do type="accept" label="Send">
           <go href="email-action.asp" method="post">
              <postfield name="email" value="<%=staff("email")%>"/>
              <postfield name="subject" value="$subject"/>
              <postfield name="message" value="$message"/>
           </go>
        </do>

When we select the Send soft key, the WAP device will navigate to the email-action.asp page passing the parameters email, subject, and message. The user enters each of these fields to the input boxes set up in the following code:

    <p>
      E-mail <%=staff("fname")%>&nbsp;<%=staff("lname")%><br/>
      Subject: <input type="text" name="subject"/><br/>
      Message: <input type="text" name="message"/>
    </p>

  </card>

</wml>

Posting Email—email-action.asp

When the user enters the appropriate data and selects the Send soft key, the WAP device will navigate to the aforementioned VBScript deck. VBScript is an all-purpose active server page engine. The exceptional feature of VBScript for our application is the integrated email tags that allow us to send emails in a single server tag. Figure 16.8 shows the email confirmation displayed.

Figure 16.8. Mail confirmation card.


The next code snippet is a key piece of the email-action.asp page. This page is run from the server, and the client will only receive the results after the server parses out the parameters. The set of VBScript commands you see causes the primary action from this page. We have chosen to integrate with a third-party VBScript object for the application. This object has a demo version that is freely available, and it greatly enhances our ability to rapidly develop this application.

The first set of VBScript commands creates the server object and then fills in the required fields. Any SMTP server interface could accomplish the same task as these lines of code. You will see that we have taken the liberty of specifying from whom the email is coming. In this particular case, we are sending the email from [email protected] and the person's name is My WAP Device. The remaining portion of the code takes in the passed parameters and then sends them to the object, which ultimately is emailed to the recipient specified in the parameters.

<%

'Note: Persits Software's AspEmail Component is used to send this message...
'other components/programs, such as Microsoft's SMTP Server can be used to perform this task
Set Mail = Server.CreateObject("Persits.MailSender")
Mail.Host = "mail.mamail.com" 'Specify a valid SMTP server
Mail.From = "[email protected]" 'Specify sender's address
Mail.FromName = "My Wap Phone" 'Specify sender's name

Mail.AddAddress Request.Form("email")

Mail.Subject = Request.Form("subject")
Mail.Body = Request.Form("message")

Mail.Send

%>

Note

This application works with any SMTP mail server. Ask your administrator whether you have a server available to you. In addition, most ISPs allow you to use their server; a call to your technical service group would inform you of your server name. When sending email to a different server, alter the Mail.host variable listed above.


Then, to make our application more appealing to the user, we create a static page that simply displays the message "The e-mail has been sent" (Figure 16.8) to the user, and includes a single soft key that will take the user back to the options card of the home deck.

<card>
  <do type="accept" label="Back">
    <go href="home.asp"/>
  </do>

  <p>The e-mail has been sent</p>
</card>

</wml>

This example of an email page is fairly straightforward, but the page is an excellent candidate for a timer element. Because the page is in fact a dead-end. If you examine the card, it displays a message for information purposes and only has one exit to home.asp. Therefore, putting a three-second timer on this page that would automatically send the user back to the home.asp page is a good idea. For simplicity, we elected to not put a timer in our first sample. In our next example, you will see more advanced techniques, such as the timer function.

Tip

If you have a WML Card that has a "dead-end," it is a good candidate to deploy the timer function in WAP to move to another page.


..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.58.121.214