To enable the user to locate a day and month in their schedule
easily, I need to create a calendar on their screen. This is
achieved by the code in MPA.asp, which you'll find in the
accompanying material, and looks like this:


Let's now dissect the code to see how this interface is created.
First, there's the standard header for WML content:
<% Response.ContentType = "text/vnd.wap.wml" %>
<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
Next comes the card that enables the user to select the month
and year, as follows:
<card id="card1" title="Welcome to MPA">
<p>
Month
<select name="Month">
<option value="1">Jan</option>
<option value="2">Feb</option>
<option value="3">Mar</option>
<option value="4">Apr</option>
<option value="5">May</option>
<option value="6">Jun</option>
<option value="7">Jul</option>
<option value="8">Aug</option>
<option value="9">Sep</option>
<option value="10">Oct</option>
<option value="11">Nov</option>
<option value="12">Dec</option>
</select>
Year <select
name="Year">
<option value="2000">2000</option>
<option value="2001">2001</option>
<option value="2002">2002</option>
<option value="2003">2003</option>
</select>
Once the month and the year have been selected, they are sent to
the DrawDates.asp document using the GET method. A
<postfield> element is used to accomplish this:
<do
type="accept" label="View Calendar">
<go href="DrawDates.asp#card2" method="get">
<postfield name="Month" value="$Month" />
<postfield name="Year" value="$Year" />
</go>
</do>
</p>
</card>
</wml>
The href attribute instructs the WAP device to load up card2 in
drawdates.asp.
The DrawDates.asp Document
I need to draw the calendar on the user's screen, so that they
can select the day in which to enter their schedule. The
generateDate() function is used to generate a table containing all
the days in a particular month and year:
<%
Function generateDate(mm, yy)
'----------------------------------------------------------
'--- Determine the 1st of the
month starts on which day
dateStr = mm & "/" & "7"
& "/" & yy
startday = Weekday(dateStr)
'--- The calendar will start from
Sunday(1), Monday(2)...
outStr = "<table
columns='7'>"
outStr = outStr & _
"<tr><td>S</td><td>M</td><td>T</td><td>W</td>"
& _
"<td>T</td><td>F</td><td>S</td></tr>"
outStr = outStr &
"<tr>"
'--- Writes the filler
Counter = 1
While Counter < startday
Counter =
Counter + 1
outStr = outStr
& "<td></td>"
Wend
For i = 1 To 31
dateStr = mm
& "/" & i & "/" & yy
If
isDate(dateStr) Then
outStr = outStr & "<td>"
outStr = outStr & "<a href='Activity.asp?dd=" & _
i & "&mm=" & mm & "&yy=" & _
yy & "'>" & i & "</a>"
outStr = outStr & "</td>"
If Counter Mod 7 = 0 Then
outStr = outStr & "</tr><tr>"
End If
Else
Exit For
End If
Counter =
Counter + 1
Next
outStr = outStr &
"</tr></table>"
generateDate = outStr
End Function
'-------------------------------------------------------------
'--- Draws the calendar
Dim mm
Dim yy
mm = Request.QueryString("Month")
yy = Request.QueryString("Year")
%>
<card id="card2" title="Calendar">
<p>
<%
If mm=""
Then
mm = month(date)
yy = year(date)
End If
Response.Write
"Date :" & mm & "/" & yy
Response.Write
generateDate(mm,yy)
%>
<do
type="accept" label="Reselect Date">
<go href="MPA.asp#card1" method="get" />
</do>
</p>
</card>

Note that I'm creating links for each and every day, all of
which point to the document Activity.asp. I also pass the values of
the day, month, and year.
Dealing with Ampersands
In the conventional HTML anchor tag, if I want to pass multiple
(name, value) pairs to a document, I use something like this:
Activity.asp?dd=1&mm=2000
In WML, however, the & character has a special meaning, and
we can't use it to separate pairs. That's why we find ourselves
writing code like this, which uses & to represent the &
character:
outStr = outStr & "<a href='Activity.asp?dd=" & i
& _
"&mm=" & mm & "&yy=" & yy
& "'>" & i & "</a>"
The Activity.asp Document
Once the user has selected a day, they can click on the Follow
Link option to retrieve the activity page:


Without further ado, let's take a look at the code that
generates this card:
<% Response.ContentType = "text/vnd.wap.wml" %>
<% Response.Expires=0 %>
<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
<%
Dim dd
Dim mm
Dim yy
Dim conn, rs
dd = Request.QueryString("dd")
mm = Request.QueryString("mm")
yy = Request.QueryString("yy")
Set conn =
Server.CreateObject("ADODB.Connection")
Set rs =
Server.CreateObject("ADODB.Recordset")
'===Connect to the database===
conn.open "Provider=Microsoft.Jet.OLEDB.3.51;"
& _
"Persist
Security Info=False;" & _
"Data Source=C:\InetPub\WroxArticle2\pim.mdb"
As this is a self-calling document (the code in this document is
going to call itself, as we will see later on), I need to check
at load time whether it is performing an update on the user's
activity. If the Request.QueryString("TimeActivity") collection
contains a non-empty string, I can be sure that I am updating the
activities. A comma separates the activities of the user, so
this:
Breakfast,,,,Lunch,,,,,,,,
indicates that I have events "Breakfast at 0800 hours" and
"Lunch at 1200 hours". I then use the Split() function to separate
each individual activity, and assign them to an array:
'===Check to see if modification is needed===
If Request.QueryString("TimeActivity") <> ""
Then
Dim arrTimeActivity
arrTimeActivity = _
Split(Request.QueryString("TimeActivity"), ",")
Counter = 0
This array is then used to update the database:
For i = 800 To 2000 Step 100
strTimeActivity
= trim(arrTimeActivity(counter))
If
strTimeActivity <> "" Then
sql = "INSERT INTO Activity Values (" & dd & _
"," & mm & "," & yy & "," & i & _
",'" & strTimeActivity & "')"
On Error Resume Next
conn.Execute(sql)
If Error.Number > 0 Then '===Record already
exists
sql = "UPDATE Activity Set Activity='" & _
strTimeActivity & "' WHERE day=" & dd & _
" AND month=" &
mm & " AND year=" & _
yy & " AND Time=" & i
conn.Execute(sql)
End If
If the user clears away the activity, I need to delete it from
the database:
Else '===See if
a deletion is in order
sql = "DELETE FROM Activity WHERE day=" & dd & _
" AND month=" & mm & " AND year=" & yy & _
" AND Time=" & i
conn.Execute(sql)
End If
Counter =
Counter + 1
Next
End If
After all the updating (if necessary), I proceed to display all
the current activities for the day.
'===Show activities===
sqlQuery = "SELECT * FROM Activity WHERE Day="
& dd & _
" AND Month=" & mm & _
" AND Year=" & yy & " ORDER BY Time"
set rs = conn.Execute(sqlQuery)
%>
<card id="card1" title="Activity">
<p>
Date : <%
=dd %>/<% =mm %>/<% =yy %>
<table
columns="2">
<tr><td>Time</td><td>Activity</td></tr>
</table>
With the snippets above, I'm generating all the different time
intervals from 8am to 10pm. The time interval is one hour. I use an
<input> element to let users modify their activities, and at
the same time retrieve the previously saved activity from the
database.
Notice that in our case we have thirteen different time
intervals, and each <input> element has a different name. The
first one has the name TimeActivity800, the second one is
TimeActivity900, and so on.
<%
For i = 800 To
2000 Step 100
break = False
While(Not rs.EOF) and Not break
If i=cInt(rs("Time")) Then
activity = rs("Activity")
break = True
Else
activity=""
End If
If i > cInt(rs("Time")) Then
rs.MoveNext
Else
break = True
End If
Wend
%>
<% =i
%> <input name="TimeActivity<% =i %>"
type="text"
value="<% =activity %>" />
<br/>
<%
Activity=""
Next %>
Once the user has keyed in their activities, they can proceed to
save the activity into the database:


<do
type="accept" label="Update">
<go href="Activity.asp" method="get">
<postfield name="dd" value="<% =dd %>" />
<postfield name="mm" value="<% =mm %>" />
<postfield name="yy" value="<% =yy %>" />
<postfield name="TimeActivity"
value="$(TimeActivity800),$(TimeActivity900),
$(TimeActivity1000),$(TimeActivity1100),
$(TimeActivity1200),$(TimeActivity1300),
$(TimeActivity1400),$(TimeActivity1500),
$(TimeActivity1600),$(TimeActivity1700),
$(TimeActivity1800),$(TimeActivity1900),
$(TimeActivity2000)" />
</go>
</do>
A link must be provided to bring the user back to reselect
another date:

<do
type="option" label="View Calendar">
<go href="drawDates.asp#card2" method="get">
<% For j=800 To 2000 Step 100 %>
<setvar name="TimeActivity<% =j %>" value="" />
<% Next %>
</go>
</do>
</p>
</card>
</wml>
That's it! You've seen a dynamic WAP application written using
ASP. Note, though, that I haven't been concerned with user
authentication, which is something you definitely have to take care
if you want to deploy in the real world. To best appreciate the
application described in this article, I suggest that you download
the source code and try it on your machine!