![]() |
|
Developing A New Outlook - PocketASP + POOM
By Ben Gladwyn, January 31, 2002.
IntroductionActive Server Pages (ASP) has provided an excellent environment for developers to rapidly create stable, feature rich, data driven applications. PocketASP brings this power to the Pocket PC, enabling developers to apply their existing skills to an exciting new platform. In this article an example application is created that provides a replacement for the "Today" view using the Pocket Outlook Object Model. All source code for may be downloaded here (12 Kb). Replacing the Today view
Here is a typical Today view on my iPaq. (All screen shots have
been captured using IA ScreenShot).
I'd like a replacement view that lists today's active tasks, as well as
making better use of precious screen real estate. Perhaps something like this: Opening the Pocket Outlook Application objectThe Pocket Outlook Application object is the primary interface to POOM. One of these objects has to be created and logged in to before any other calls are made. At the end of each page, there should be call to polApp.Logoff(). I decided to prevent duplication of creation and logon code in each ASP page by accessing the application object through the following function,
' ---------------------------------------------------------------------------
' ---------------------------------------------------------------------------
' polApp: Hides complexity of creating object and logging on from rest of
' application
'
Dim f_polApp
Function polApp
' Check to see if object has already been created.
' If it has, return it.
' If it hasn't, create it, log in, and return it.
'
If IsEmpty(f_polApp) Then
Set f_polApp = CreateObject("PocketOutlook.Application")
f_polApp.Logon()
End If
Set polApp = f_polApp
End Function
' ---------------------------------------------------------------------------
Listing the incomplete tasksTo get a list of Outlook items via POOM we use the getDefaultFolder method, passing in the ID of the information type we querying (the folder identities and other constants are defined in an included file). A collection of the items in that folder can then be filtered and sorted before display as required. To get the tasks folder and limit it to incomplete tasks only we use,
' Get the tasks folder and then access the Items collection within it
'
Set taskfolder = polApp.getDefaultFolder(olFolderTasks)
Set taskitems = taskfolder.Items
' Limit to incomplete tasks only
'
taskquery = "[Complete] = False"
Set taskitems = taskitems.Restrict(taskquery)
' Check to see if any incomplete tasks returned
'
if (taskitems.Count > 0) then
' Sort collection by due date (ascending)
'
taskitems.Sort "[DueDate]", False
' Iterate through the collection
'
for each task in taskitems
' Output subject
'
%>
<%=htmlEncode(task.Subject)%><br>
<%
next
end if
(The htmlEncode() function takes a string and converts it to HTML so it displays correctly in the browser.) Task completion and due dateUsing the Item interface, we can add, view, modify and delete entries in Outlook. The first thing to do is to create a mechanism to mark tasks as being complete.
' Set a task to be complete
'
if (request.Form("f_action") = "completetask") then
' Get individual task
'
Set task = polApp.GetItemFromOid(request.Form("oid"))
' Set it to be completed
'
task.Complete = true
' Save it
'
task.Save
end if
The task list generated is now rendered as a form with checkboxes. As soon as a tick is placed, the page reloads and sets the task in question to be complete. While we're changing the task list, we can query the DueDate property. If one exists then we'll display it and if it's in the past we change the emphasis of the subject.
' Check to see if any incomplete tasks returned
'
if (not IsNull(taskitems)) then
' Create top of form
'
%>
<form method="post">
<input type="hidden" name="f_action" value="completetask">
<%
' Iterate through the collection
'
for each task in taskitems
' Use this boolean when formatting data
'
taskoverdue = false
' Check for empty duedate
'
if (task.DueDate = #1/1/4501#) then
taskdate = ""
else
' Format duedate for output
'
taskdate = formatDateTime(task.DueDate, 2)
' Check to see whether task is overdue
'
if (task.DueDate < Now) then taskoverdue = true
end if
' Output checkbox, subject and duedate
'
%>
<input type="checkbox" name="oid" value="<%=task.Oid%>" onClick="submit()">
<%if (taskoverdue) then Response.Write "<b>"%>
<%=htmlEncode(task.Subject)%>
<%if (taskoverdue) then Response.Write "</b>"%>
<%=taskdate%>
<br>
<%
next
' Close form
'
%>
</form>
<%
end if
Note the use of the literal date #1/1/4501#. This value is used by Outlook when a date field is empty. Task view, update and deleteEach item in the Outlook information store is uniquely identified by an assigned object ID (OID). This applies to appointments, tasks and contacts. Once we have the OID of a task, we can query its contents, alter those contents and delete it. If the task data is displayed in a pre-populated HTML form, updates can be applied and committed quickly.
' Get OID from request
'
oid = request.QueryString("oid")
if (oid = "") then oid = request.Form("oid")
' Must have an OID
'
if (oid <> "") then
' Get individual task
'
Set task = polApp.GetItemFromOid(oid)
' Is this task to be deleted?
'
if (request.Form("f_action") = "delete") then
' Delete the task
'
task.Delete
' Return to home page
'
response.Redirect("default.asp")
end if
' Is the information to be updated?
'
if (request.Form("f_action") = "update") then
' Update task details
'
task.Subject = request.Form("taskSubject")
task.Body = request.Form("taskBody")
if (request.Form("taskComplete") = "1") then
task.Complete = True
else
task.Complete = False
end if
' Save these changes
'
task.Save
end if
' Display HTML form
'
%>
<p>
<form method="post" name="taskForm">
<input type="hidden" name="f_action" value="update">
<input type="hidden" name="oid" value="<%=task.Oid%>">
<input type="text" name="taskSubject" value="<%=htmlEncode(task.Subject)%>"><br>
<input type="checkbox" name="taskComplete" value="1"
<%
if (task.Complete) then response.write(" checked")
%>
>Completed<br>
<textarea name="taskBody"><%=htmlEncode(task.Body)%></textarea><br>
<input
type="submit"
onClick= "
if (confirm('Are you sure you want to delete this task?'))
{
document.taskForm.f_action.value='delete';
return true;
}
else
{
return false;
}
"
value="Delete"
> | <input type="Submit" value="Update">
</form>
<p><br><br><a href="default.asp">Back</a>
<%
else
' Empty OID => return to home page
'
response.Redirect("default.asp")
end if
That's all our task functionality complete. More features could be added, like creating new tasks, making more fields editable or displaying different icons depending on the task status/type. However we'll move on and modify the code we've already created to list and edit appointments. Listing today's appointmentsWith a few modifications to the task list code, we can now list today's appointments. The restriction placed on the Items collection is more complex. We need to list all appointments that are either all day events for this day, timed events for today which are not in the past and current timed events which span multiple days.
' Get the calendar folder and then access the Items collection within it
'
Set calfolder = polApp.getDefaultFolder(olFolderCalendar)
Set calitems = calfolder.Items
nowdate = FormatDateTime(Now,2)
nowtime = FormatDateTime(Now,4)
calquery = ""
' Limit to today's appointments only
'
' 1. all day events
calquery = calquery + "("
calquery = calquery + "[AllDayEvent] = True"
calquery = calquery + " and [Start] <= """ + nowdate + """"
calquery = calquery + " and [End] >= """ + nowdate + """"
calquery = calquery + ")"
' 2. Timed events
calquery = calquery + "or ("
calquery = calquery + "[AllDayEvent] = False"
calquery = calquery + " and [Start] <= """ + nowdate + """"
calquery = calquery + " and [End] >= """ + nowdate + " " + nowtime+ """"
calquery = calquery + ")"
Set calitems = calitems.Restrict(calquery)
When listing the appointments we need to display different information, depending on its type. If it's a normal appointment (for today, at a specified time) we should list the start and end times. If it's an all day event, we don't need to put anything. If it's a timed appointment which spans across multiple days, we'll put "multi-day" next to its listing - just like in the Today view.
' Sort collection by Start time (ascending)
'
calitems.Sort "[Start]", False
' Iterate through the appointment list
'
for each appointment in calitems
' Use this boolean when formatting data
'
allday = appointment.AllDayEvent
appointmentstart = ""
appointmentend = ""
appointmenttimes = ""
if (not allday) then
' Does this appointment start today ?
if (appointment.Start >= DateValue(nowdate)) then
appointmentstart = FormatDateTime(appointment.Start,4)
end if
' Does this appointment end today ?
if (appointment.End < DateAdd("d",1,DateValue(nowdate))) then
appointmentend = FormatDateTime(appointment.End,4)
end if
if (appointmentstart = "" and appointmentend = "") then
appointmenttimes = "<i>multi-day</i>"
else
appointmenttimes = appointmentstart + "-" + appointmentend
end if
end if
' Output checkbox, subject and duedate
'
%>
<a href="app.asp?oid=<%=appointment.Oid%>"><%=htmlEncode(appointment.Subject)%></a>
<%=appointmenttimes%><br>
<%
next
Appointment view, update and deleteWe can use the task detail code above as the basis for our appointment detail code. By removing code that operates on task.Complete and global replacing "task" with "appointment" we have a functional page that displays and updates the subject and body of an appointment. It would be useful to see who the attendees for a particular meeting are. This can be done easily by looping through the Recipients collection of the appointment.
' Get attendee collection for this appointment
'
set appAttendees = appointment.Recipients
' Check to see if there are any attendees
'
if (appAttendees.Count > 0) then
%>Attendees: <%
' Loop through collection and render the name of each of the attendees
'
for count = 1 to appAttendees.Count
set recip = appAttendees.Item(count)
%> <%=htmlEncode(recip.Name)%><%
if (count < appAttendees.Count) then Response.Write(", ")
next
%><br><%
end if
ConclusionAttractive Pocket PC applications that need to access Outlook data can be built quickly using the combined functionality of POOM and PocketASP. The simple application created here could be expanded to query more of the task and appointment properties, as well as linking through to the contact details of an attendee. Going further, additional information could be extracted from a Pocket Access database to augment the data already held in Outlook. Web programming skills go a lot further than they used to with PocketASP! Related resources:
DiscussDiscuss this article. Here you can write your comments and read comments of other developers. |
|||||||||||||||||||||