template

Index :: Javascript :: Datum/Zeit :: Kalender

Im Umfeld von Terminen, Datumslisten oder sonstigen zeitlichen Planungen wird oft eine interaktive Kalenderseite - z.B. eine Monatsübersicht - angeboten, die dem Besucher eine visuelle Orientierung ermöglicht. Solche Module erlauben i.d.R. das monats- und jahresweise Blättern und können auch als Instrument zur Datumsauswahl dienen.
<<<.>>>
|<<.>>|
KWMoDiMiDoFrSaSo
........
........
........
........
........
........
Das Beispiel zeigt eine einfache Variante mit Blätterfunktion und Anzeige der Kalenderwoche (gemäß ISO 8601). Ist der aktuelle Monat sichtbar, dann wird der aktuelle Tag farblich hervorgehoben.
Beim Jahresbereich liegt die untere Grenze bei 1600, die obere bei etwa 8000. In der Demo findet allerdings kein Clipping statt, dieses müsste bei Bedarf nachgerüstet werden.
Theoretisch ließe sich der Kalender auch noch erweitern, etwa um eine ComboBox zur direkten Monatswahl. Desweiteren könnte man mittels hinterlegter Listen auch feste Feier/Sondertage, oder per Kalkulation bewegliche Feiertage und Mondphasen abbilden.

Intern werden diverse Funktionen zur Berechnung von Schalttagen, Wochennummern und Tagen benötigt, wobei die Monate von 1 bis 12 zählen und der Tagestyp (Mo, Di, ... So) als Enum [0...6] definiert ist.
  • LeapDay(y) : liefert den Schalttag (0 oder 1) des Jahres y.
  • YrWeeks(dt,lp) : liefert die Wochenanzahl eines Jahres. Benötigt in dt den Tagestyp des 1. Januars und in lp den Schalttag (0/1).
  • PreYrWeeks(dt,plp) : liefert die Wochenanzahl des Vorjahres. Benötigt in dt den Tagestyp des 1. Januars im Ist-Jahr und in plp den Schalttag (0/1) des Vorjahres.
  • MonProps(y,m) : liefert ein Array mit 3 Werten. [0] Tagestyp des Jahresersten, [1] Tagestyp des Monatsersten und [2] Wochennummer des Monatsersten. Benötigt in y das Jahr und in m den Monat des Datums.
  • PreMoDays(y,m) : liefert die Tagesanzahl des Vormonats. Benötigt in y das Jahr und in m den Ist-Monat.
Das Interface besteht aus zwei Funktionen zum Setzen/Ändern des Datums.
  • KalSet(y,m) : Stellt Jahr y und Monat m ein. Ohne Parameter wird das aktuelle Datum eingestellt.
  • KalStep(y,m) : Erwartet in y (Jahr) einen postiven oder negativen Offset. Ist y gleich Null, dann wird m (Monat) ausgewertet; hier wird dann entweder 1 (Folgemonat) oder -1 (Vormonat) erwartet. Der resultierende Monat wird eingestellt.
Hier der Quellcode:
CSS im Header
.ptr {CURSOR:pointer;} .KalH {BACKGROUND:#E0E0E0;TEXT-ALIGN:center;} /* Kopfzeile */ .KalD {BACKGROUND:#FFF;TEXT-ALIGN:center;} /* Datenzeile */ .KalH TD, .KalD TD {FONT-SIZE:11px;} .KalTi {FONT-WEIGHT:bold;} /* Titel */ .KalW {FONT-STYLE:italic;BACKGROUND:#E0E0E0;} .KalD0 {FONT-WEIGHT:normal;COLOR:#999;} /* Tag grau */ .KalD1 {FONT-WEIGHT:bold;COLOR:0;} /* Werktag */ .KalD2 {FONT-WEIGHT:bold;COLOR:#F00;} /* Wochenende */
Javascript im Header
function $(id) { return document.getElementById(id); } //--- Kalender var LongMon=['','Januar','Februar','M\xE4rz','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember'], MonDays=[0,31,28,31,30,31,30,31,31,30,31,30,31],MonOffs=[0,0,31,59,90,120,151,181,212,243,273,304,334], KalYa,KalMa,KalDa,KalY,KalM; function LeapDay(y) { if (y&3) return 0; if (y%100) return 1; return (y%400)?0:1; } function YrWeeks(dt,lp) { if (dt==2) return 52+lp; if (dt==3) return 53; return 52; } function PreYrWeeks(dt,plp) { if (dt==4) return 53; if (dt==5) return 52+plp; return 52; } function MonProps(y,m) { //ret:[dtyp(Jahreserster),dtyp(Monatserster),Wnr(Monatserster)] var a=[],lp=LeapDay(y),i=y-1600; a[0]=(6+i+(i>>2)-Math.floor(i/100)+Math.floor(i/400)-lp)%7; var moff=MonOffs[m]; if (m>2) moff+=lp; a[1]=(a[0]+moff)%7; a[2]=Math.floor((moff+a[0])/7); if (a[0]<4) ++a[2]; else if (!a[2]) a[2]=PreYrWeeks(a[0],LeapDay(y-1)); return a; } function PreMoDays(y,m) { if (--m<1) return 31; if (m==2) return 28+LeapDay(y); return MonDays[m]; } function KalSet(y,m) { var d=new Date(); KalYa=d.getFullYear(); KalMa=d.getMonth()+1; KalDa=d.getDate(); if (m) { KalY=y; KalM=m; } else { KalY=KalYa; KalM=KalMa; } $('KalYr').firstChild.data=KalY; $('KalMo').firstChild.data=LongMon[KalM]; var w,c,td,a=MonProps(KalY,KalM),di=1-a[1],wmax=YrWeeks(a[0],LeapDay(KalY-1)), dmax=MonDays[KalM],dpre=PreMoDays(KalY,KalM); if (KalM==2) dmax+=LeapDay(KalY); for (w=0;w<6;++w) { td=$('KalW'+w); td.firstChild.data=a[2]++; if (a[2]>(w?wmax:51)) a[2]=1; for (c=0;c<7;++c) { td=td.nextSibling; if (di<1) { td.firstChild.data=dpre+di; td.className='KalD0'; td.style.background='#FFF'; } else if (di>dmax) { td.firstChild.data=di-dmax; td.className='KalD0'; td.style.background='#FFF'; } else { td.firstChild.data=di; td.className='KalD'+(c>4?2:1); td.style.background=(KalY==KalYa&&KalM==KalMa&&di==KalDa)?'#FF0':'#FFF'; } ++di; }}} function KalStep(y,m) { if (y) { KalSet(KalY+y,KalM); return; } y=KalY; if ((m+=KalM)==13) { ++y; m=1; } else if (!m) { --y; m=12; } KalSet(y,m); }
Weiter unten, im BODY, der Kalender:
<table bgcolor='#A0A0A0' cellspacing='1' cellpadding='2' style='FONT:11px verdana,arial,helvetica,sans-serif'> <tr class='KalH'><td class='ptr' onClick='KalStep(-10)' title='10 Jahre zur&uuml;ck'>&lt;&lt;</td> <td class='ptr' onClick='KalStep(-1)' title='1 Jahr zur&uuml;ck'>&lt;</td> <td id='KalYr' class='KalTi' colspan='4'>.</td> <td class='ptr' onClick='KalStep(1)' title='1 Jahr weiter'>&gt;</td> <td class='ptr' onClick='KalStep(10)' title='10 Jahre weiter'>&gt;&gt;</td></tr> <tr class='KalH'><td class='ptr' onClick='KalSet(KalY,1)' title='Januar'>|&lt;</td> <td class='ptr' onClick='KalStep(0,-1)' title='1 Monat zur&uuml;ck'>&lt;&lt;/td> <td id='KalMo' class='KalTi' colspan='4'>.</td> <td class='ptr' onClick='KalStep(0,1)' title='1 Monat weiter'>&gt;</td> <td class='ptr' onClick='KalSet(KalY,12)' title='Dezember'>&gt;|</td></tr> <tr class='KalH'><td class='KalW'>KW</td><td>Mo</td><td>Di</td><td>Mi</td><td>Do</td><td>Fr</td><td>Sa</td><td>So</td></tr> <tr class='KalD'><td id='KalW0' class='KalW'>.</td><td>.</td><td>.</td><td>.</td><td>.</td><td>.</td><td>.</td><td>.</td></tr> <tr class='KalD'><td id='KalW1' class='KalW'>.</td><td>.</td><td>.</td><td>.</td><td>.</td><td>.</td><td>.</td><td>.</td></tr> <tr class='KalD'><td id='KalW2' class='KalW'>.</td><td>.</td><td>.</td><td>.</td><td>.</td><td>.</td><td>.</td><td>.</td></tr> <tr class='KalD'><td id='KalW3' class='KalW'>.</td><td>.</td><td>.</td><td>.</td><td>.</td><td>.</td><td>.</td><td>.</td></tr> <tr class='KalD'><td id='KalW4' class='KalW'>.</td><td>.</td><td>.</td><td>.</td><td>.</td><td>.</td><td>.</td><td>.</td></tr> <tr class='KalD'><td id='KalW5' class='KalW'>.</td><td>.</td><td>.</td><td>.</td><td>.</td><td>.</td><td>.</td><td>.</td></tr> </table>
Javascript zur Initialisierung:
<SCRIPT type='text/javascript'>KalSet();</SCRIPT>

Index :: Javascript


template