Entwickelt man eine ASP-Anwendung für das Internet oder das Intranet möchte man oft auch einen Kalender in das Angebot stellen. Das schwierigste ist, für manchen Entwickler, den Algorithmus zu finden - wenn nicht klauen.
Mein Beispiel unten enthält eine Funktion die (fast) alles implementiert hat was man für einen kleinen Kalender so alles braucht.
Steckt man die Funktion in eine include Datei, wird der HTML/ASP Code sehr übersichtlich. Das wichtigste aber ist es, dass das Control in sich abgeschlossen ist und modular aufgebaut ist. Das einzige was man der Funktion übergeben muss ist das Datum (-> Monat) das es anzeigenl soll.
Hier der HTML/ASP Code zum anzeigen des Kalenders:
<html> <head> <title>ASP Calendar Control</title> </head> <body> <table align="center" border="0" cellPadding="2" cellSpacing="2" width="200"> <tr> <td align="center" width="25%" valign="top"> <% calendar( date() )%><% %> </td> </tr> </table> </body> </html> |
Das Calender-Control wird mit der Funktion >>calendar( date())<< aufgebaut. Das ganze verpacke ich noch in das Seitenlayout meiner ASP-Page das hier aus einer einfachen Tabelle besteht.
Gehen wir nun auf die Funktion >>calendar<< etwas genauer ein:
Die Funktion benötigt für den hier dargestellten Algorithmus das aktuelle Datum (dtNow) und das Datum des Parameters (dtParam) den wir später noch genauer betrachten werden. Außerdem errechnen wir mit dateadd den ersten des akuellen Monats.
<% sub calendar( dtParam ) dtNow = date() dtActMonth = dateadd( "d" , ( -day( dtParam ) + 1 ), dtParam ) %> |
Den Rand des Kalenders verpacke ich einmal in eine Tabelle um später mit dem Design etwas spielen zu können.
<table cellpadding="3" cellspacing="1" border="0"> <tr> <td colspan="7" valign="top"> |
Als nächstes erzeugen wir den Kopf des Kalenders mit Hilfe einer weiteren Tabelle.
Möchte man zusätzlich noch durch die Monate blättern kann man wie unten gezeigt wird mit Hyperlinks arbeiten.
Ich verwende hier die VBScript - Funktionen dateadd, month und monthname. Im linken Teil der Tabelle ziehe ich vom aktuellen Monat einen Monat ab, auf der rechten Seite zähle ich einen Monat dazu. Zwischen den beiden Navigationselementen gebe ich den Namen des Monats und das Jahr aus.
<tr> <td colspan="7" valign="top"> <table cellpadding="0" cellspacing="0" width="100%" border="1" bgcolor="#777777"> <tr> <td width="10%" align="center" bgcolor="lightgrey">< BR> <ahref="cal.asp?actDte=<% = dateadd( "m" , -1 , dtActMonth ) %>"><</a> </td> <td width="80%" align="center"> <b><small><% = MonthName( Month( dtActMonth ) ) & " " & Year( dtActMonth )%></small></b> </td> <td width="10%" align="center" bgcolor="lightgrey">< BR> <ahref="cal.asp?actDte=<% = dateadd( "m" , 1 , dtActMonth ) %>">></a> </td> </tr> </table> </td> </tr> |
Da ich hier mit Querystrings arbeite muss ich vor dem Aufruf der Funktion >>calendar<< etwas Vorarbeit leisten.
Der HTML/ASP-Code sieht dann folgendermaßen aus:
<% dtReq = Request("actDte") if dtReq = "" then dtReq = date() %> <html> <head> <title>ASP Calendar Control</title> </head> <body> <table align="center" border="0" cellPadding="2" cellSpacing="2" width="200"> <tr> <td align="center" width="25%" valign="top"> <% calendar( dtReq )%> </td> </tr> </table> </body> </html> |
Machen wir wieder mit der Funktion >>calendar<< weiter. Nachdem ich den Kopf des Kalenders entwickelt habe,
die auch noch eine Navigation enthält kommen als nächstes die Wochennamen an die Reihe.
<tr valign="top" align="center"> <% For iDay = vbSunday To vbSaturday %> <th width="14%"><small><% = left( WeekDayName( iDay ) , 2 )%></small></th> <% Next %> </tr> |
Hier gebe ich einfach Table-Header aus und als Text die beiden ersten Buchstaben des Wochennamens. Diese Wochenamen bekomme ich mit Hilfe der VBScript-Funktion weekdayname(index). Möchte man sich das Leben ein wenig vereinfachen verwendet man als Index die vorhandenen VBS-Konstanten die man dann mit einer for-Schleife einfach durcharbeitet.
Als nächstes machen wir und klar, dass ein (professioneller) Kalender die Form eines Rechtecks besitzt und die Felder evtl. füllen möchte. D.h. ich brauche eine Funktion, die mir den ersten vorhergehenden Sonntag meines aktuellen Monats liefert und mit dem mein Programm zu zählen beginnt.
Diese Funktion werden wir weiter unten in Angriff nehmen.
<% dtActDay= dtFirstSunday( dtActMonth ) %> |
Üblicherweise hat ein Kalender je zugehörige Woche eine eigene Zeile und je Wochentag eine Spalte. Hier aber muss man Acht geben. Rechnen wir einmal damit, dass ein Monat vier Wochen besitzt. In unserem Beispiel ist es aber so, daß der erste eines Monats auf einen Samstag fällt. Somit kommt eine zusätzliche Zeile ins Spiel.
Das Gedankenmodell ist aber noch unvollständig, denn es kann ja auch vorkommen, dass der letzte eines Montas auf einen Sonntag und der erste eines Monats auf einen Samstag fällt (worst case), also zwei zusätzliche Zeilen für einen Monat. Das heißt für uns, daß wir die Zeilen in unserem Kalender von 0 bis 5 aufbauen müssen.
Mit den Tagen, also die Spalten in unserem Kalender tun wir uns schon wesenlich leichter. Eine Woche hat sieben Tage und somit sieben Spalten. Mit der Variable sColor peppen wir den Kalender optisch ein wenig auf. Die Standard -Farbe mit der die Tage eines Monats angezeigt werden ist in diesem Beispiel die Farbe grey.
<tr valign="top"> <% for iDay = 0 to 6 sColor = "gray" |
Die Tage, die nicht zum aktuellen Monat gehören sollen in unserem Beispiel mit der Farbe lightgrey markiert werden.
if Month( dtActDay) <> Month( dtActMonth ) then sColor = "lightgrey" end if |
Der aktuelle Tag wird hier mit white angezeigt.
if cdate( Replace( dtActDay, "/" , "-" ) ) = cdate( dtNow ) then sColor = "white" |
Die Tage des Monats werden nun in die Felder mit der oben ausgewählten Farbe geschrieben.
%> <td height="20" bgcolor="<% = sColor %>"> <b><% = Day( dtActDay) %></b> </td> |
Somit haben wir unseren Kalender fast fertig. Da wir mit einer for - Schleife die Tage eines Monats durchlaufen, müssen wir natürlich zum Schluss noch den Tag incrementieren.
<% dtActDay= DateAdd( "d" , 1 , dtActDay) next %> </tr> <%next%> </table> <% end sub %> |
Da wäre zu guter letzt noch die Funktion dtFirstSunday zu besprechen. Liegt der erste Tag eines Monats zum Beispiel auf einem Freitag, wird hier Tag für Tag bis zum Sonntag ein dekremetielles dateadd vollzogen und das Datum des ersten Sonntags zurückgegeben
function dtFirstSunday( byval dt ) while WeekDay( dt ) > vbSunday dt = DateAdd( "d" , -1 , dt ) wend dtFirstSunday = dt end function |
Viel Spass beim testen !!!-)