Simplifying Date Data Entry with Calendars, Part I

here are numerous reasons why building data entry forms can cause an ASP developer headaches. If you are building a form that captures a date (for example, a date of birth for a sign-up form, or even a project’s beginning and ending dates for a more complicated form), you know that the odds are high of getting inaccurate data if you leave it to the user to fill in the date in a text box. Users can enter dates as mm/dd/yyyy, dd/mm/yyyy, or even as mmm, dd yyyy. Abbreviations and punctuations are further opportunity for inconsistency.

Trying to replace a single text box date entry with three drop down combo boxes is even worse. The user now has to click and select one year, one month, and one day, which offers too much opportunity for users to misenter their data. It may be easier to program, but it is a usability nightmare.

The best interface for entering dates in a form is to click-and-select dates from a pop-up or to use a drop-down calendar a la Microsoft Outlook. This gives the user a visual metaphor to select the dates, which cuts down on errors.

This is the first of two solutions that will help you program such date entry techniques. In this first installment, we willproduce the calendar page that is used to select dates. Next month, we will tie it together with the data entry page.



The most common ways of collecting dates via HTML forms opens too many opportunities for miskeyed data or inconsistent date formats, requiring additional validation code on the server.



Allow users to pick dates from a visual calendar metaphor.

Getting All the Pieces Together
Let’s consider an example. You have a Web form that has four different date fields to be filled in. These are the estimated and actual beginning and ending dates of a project.

To get users to select the dates from your calendar interface?you should provide four “browse” buttons next to the text boxes. Clicking on the buttons brings up a calendar page that the user can select a date from. The interface will look like this:

If you want to get fancy and improve user comprehension, you can replace the four buttons with a calendar icon. Here’s an example:

 

Below is the page that displays when the icon is clicked. They can select any date and even navigate from month to month.

When the user selects a date, the calendar window closes and the text box on your original form is populated with their selection.The user shouldn’t be able to type anything in the text box.

My calendar is actually two separate HTML tables. The top table is the gray one containing the month and the arrow graphics. The bottom table contains the dates, two horizontal lines and the “Today” button. When the arrows in the top table are clicked, the page refreshes with the same table for the previous or following month. So at all times, the ASP page needs to know two things?what month and what year to display. These two values are sent as arguments via the query string to the page when the ASP page is called.

I began with a new ASP page called “calpop.asp”

<%@ LANGUAGE="VBSCRIPT" %><%   Option Explicit'----------- WEB SITE: YOUR WEB SITE NAME ------------' File Name: calpop.asp''   Purpose:'   Displays a pop up Calendar''   Arguments:'   m = month to display, default to current month'   y = year to display, default to current year''   Author: Rama Ramachandran'           Imperium Solutions'           http://www.imperium.com'           Internet: [email protected]''   Date Created:'   11/20/2000''   Modification History:'%>

Now you are ready to begin coding for the page. First, declare a few variables:

'------------------------------------------------------' All your ASP preprocessing code goes here'------------------------------------------------------   ' -- Declare Variables   Dim intM       ' Cur Month   Dim intY      ' Cur Year   Dim intFDay      ' First day of the month   Dim intNoDays   ' Number of days in the month      Dim intMPrev   ' Previous Month   Dim intYPrev   ' Previous Year   Dim intMNext   ' Next Month   Dim intYNext   ' Next Year

Now, figure out what month and year you wish to display. You get this value from the Request object and if it is blank, you can assume the current month and current year.

' -- What month and year are we displaying the calendar for   intM = Request("m")   ' -- if blank, use current month   If intM = ""  Then      intM = Month(Date())   End If   intY = Request("y")   ' -- if blank, use current year   If intY = "" Then      intY = Year(Date())   End If

In order to draw a calendar, the only other information needed is to figure out what day of the week the month begins on and how many days there are in that month. Stay away from ASP calendar code on the Web or in textbooks where these values are unnecessarily hard-coded or coded with a lot of if statements and select case statements. VBScript has built in functions that can make it very easy to calculate the days.

intFDay = WeekDay(intM & "/01/" & intY)   intNoDays = DateDiff("d", _              intM & "/01/" & intY, _            DateAdd("m", 1, intM & "/01/" & intY) _            )

Use the “WeekDay” function to identify the day of the week for the first of the month, then use the DateAdd and the DateDiff to fill out the rest of the days in the month. Notice the line continuation characters ( _) in the code above. This calculation automatically takes care of odd months such as February as well as leap year scenarios?all with one line of code!

To allow the user to go back and forward one month at a time you need to know the previous and next month/year values. Let us calculate them now, again, using built-in functions:

' -- Figure out the previous and next months also   intMPrev = Month(DateAdd("m",-1,intM & "/01/" & intY))   intYPrev = Year(DateAdd("m",-1,intM & "/01/" & intY))      intMNext = Month(DateAdd("m",1,intM & "/01/" & intY))   intYNext = Year(DateAdd("m",1,intM & "/01/" & intY))

Developing Routines for HTML Output
The next step is to output the HTML text to generate the page and the calendar within the page. Do this by encapsulating the task of outputting the top of the HTML page within a sub-routine called WritePageTop and then call the routine. The code at the top of your ASP page will be:

WritePageTop()

At the bottom of the page, create a new section (within ASP <% %> tags) where all your sub-routines are placed. Within this section, write the code for your WritePageTop routine?which outputs HTML text. Writing code this way makes it easy to read and maintain.

<%'------------------------------------------------------' All ASP post processing code goes here, as well as ' sub routines and functions'------------------------------------------------------Sub WritePageTop()	%>	Please Select the Date	
<%End Sub%>

Notice that the page began with the tag and ended the routine just after the tag with a

tag that aligns the contents of the body in the center of the window. You can write the remaining pieces of code?in a very similar fashion, with the HTML outputting routine at the bottom of the page and call it from within the ASP code at the top of the page.

The next task is to output the top table, which includes the name of the month and the ability to move from month to month. Let us call this routine “WriteMonthNameTable”:

Sub WriteMonthNameTable()	' -- outputs the table that displays the month name 	' -- and the prev and next buttons%>	
?m=<%= intMPrev %>&y=<%= intYPrev %>">Previous Month<%= MonthName(intM) & ", " & intY %>?m=<%= intMNext %>&y=<%= intYNext %>">Next Month
<%End Sub

You are dynamically building the previous and the next buttons and their hyperlinks in this section of the code?outputing a table with one row and three columns. Within the first column, place the graphic called "calmLeft.gif" and enclose it within a hyperlink (). The hyperlink points to the page itself by using the "Request.ServerVariables("SCRIPT_NAME")" function call. Also build a query string to be passed to the hyperlink. The query string is in this line of code:

<%= Request.ServerVariables("SCRIPT_NAME") %>?m=<%= intMPrev %>&y=<%= intYPrev %>

If the value of the variable intMPrev was 11 and the value of the variable intYPrev was 2000, then this hyperlink would resolve to the following:

Calpop.asp?m=11&y=2000

The next step is to build the actual days of the calendar. Begin by outputting a simple table tagusing a routine called WriteCalTableBegin:

Sub WriteCalTableBegin()%><%End Sub

The next section outputs the first row of the calendar that contains the labels for the days of the week as well as a horizontal line underneath. This routine is called "WriteWeekLabelRow":

Sub WriteWeekLabelRow()%>
<%End Sub

The list of routine calls you've now created is below. For each call, the ASP compiler jumps down to the routines and executes the code within them:

WritePageTop	WriteMonthNameTable	WriteCalTableBegin	WriteWeekLabelRow

Before continuing to output the days, you need to pay some attention to the code that occurs after the days are listed. You can end the calendar table with a routine called "WriteCalTableEnd" as follows:

ub WriteCalTableEnd()%>
  S M T W T F S  
 
 
 
 
 
 
<%End Sub

This code completes the calendar table by adding a horizontal line and a row containing a "Today" button.You can finish off the page by calling a routine "WritePageBottom" that mirrors the WritePageTop routine.

Sub WritePageBottom()%>
<%End Sub

The table below summarizes the routines we've built thus far in this solution and what they do. We are now ready to tackle the actual date display with a routine called "GenerateCalendar."

Routine Description
WritePageTop Displays Top of the page.
WriteMonthNameTable Displays the table with the month name and buttons to move back and forth
WriteCalTableBegin Simple routine to output the table begin tag for the calendar.
WriteWeekLabelRow Displays a row of week day labels (S, M, T, ).
GenerateCalendar Routine that displays the actual dates. We have not yet written this code.
WriteCalTableEnd Displays the bottom of the Calendar table?including a button labelled 'Today'.
WritePageBottom Displays the bottom of the page.



Writing the GenerateCalendar Routine
In order to output the calendar dates, iterate a variable from one to 42 (six rows of seven columns each). Use the following code to output the calendar:

Sub GenerateCalendar()	Dim i	' -- Row begin	Response.Write "" & vbCrLf 	' -- Left blank column	Response.Write " " & vbCrLf	' -- Dump all the days	For i = 1 to 42		' -- is it before the beginning of the month		If i < intFDay Then			' -- write a blank			WriteInActiveCalDay " "		' -- Is it after the end of the month		ElseIf i > intNoDays + intFDay - 1 Then			' -- Write a blank			WriteInActiveCalDay " "		Else			' -- Write the day			WriteActiveCalDay (i- intFDay +1)		End If		' -- Do we need to go to the next row?		if i Mod 7 = 0 Then			' -- we are at the end of the week			' -- Right blank column			Response.Write " " & vbCrLf 			' -- End of the Row			Response.Write "" & vbCrLf			' -- Do we need another row? 			If i <= intNoDays + intFDay - 1  Then				' -- Row begin				Response.Write "" & vbCrLf 				' -- Left blank column				Response.Write " " & vbCrLf			Else				' -- we have exceeded the number of days, get out				Exit For			End if		End if		Next	' -- End the row	if i Mod 7 <> 0 Then		Do While i Mod 7 > 0			WriteInActiveCalDay " "			i = i+1		Loop		' -- Right blank column		Response.Write " " & vbCrLf 		' -- End of the Row		Response.Write "" & vbCrLf	End if		End Sub

First, output the row beginning and the left blank column:

' -- Row begin	Response.Write "" & vbCrLf 	' -- Left blank column	Response.Write " " & vbCrLf

Now iterate from one to 42 using a For loop. Check to see if the value of "i" is less than the beginning of the month. If it is, output a blank cell by using the routine "WriteInactiveCalDay." Similarly, if the value of "i" is greater than the last day of the month (factored appropriately), you'll again output a blank cell. Otherwise, output the day of the month using the routine "WriteActiveCalDay" passing the date to be outputted. When you have reached the end of the week (seventh day), skip to the next line by finishing the right blank column and row and then beginning a new row. Finally, if you have exceeded the number of days in the month, get out of the loop. Outside the loop, check to make sure you have not quit in the middle of the week. If you have, you need to go back and complete the week row.

The actual task of outputting a day is handled by the routines WriteInactiveCalDay and WriteActiveCalDay. The difference in these routines is the presence or absence of a hyperlink that, when clicked, will update the text box in the date field you set out to fill. This is the code for the routines.

Sub WriteInActiveCalDay(byval sLabel)	Response.Write 	"" 	& sLabel & "" & vbCrLfEnd Sub'------------------------------------------------------Sub WriteActiveCalDay(byval sLabel)	Response.Write 	"	" & sLabel & "" & vbCrLfEnd Sub

Save your work and check the page in your browser. You should get a fully functional calendar page with hyperlinks. You can check this out in action as well as download the entire code for this article here.

For now, we are outputting a hyperlink that says "blah." The links are not operational so don't click on them.Next month I'll show you how to change the hyperlink to perform some action and to show you how to tie your calendar page to the data entry page. Until next time, good luck.

Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Overview

Recent Articles: