JavaScript/Tutorials/Monatskalender

Aus SELFHTML-Wiki
< JavaScript‎ | Tutorials(Weitergeleitet von Monatskalender)
Wechseln zu: Navigation, Suche

Das Beispiel schreibt in eine HTML-Datei an einer gewünschten Stelle einen frei formatierbaren Kalender des aktuellen Monats.

Der aktuelle Tag wird darin hervorgehoben dargestellt. Ein kleines Schmuckstück für Web-Seiten. Anhand des Beispiels können Sie lernen, wie man dynamisch Tabellen erzeugen kann, aber ebenso den praktischen Umgang mit dem Date-Objekt von JavaScript.

Tabellen dynamisch erzeugen

Auch wenn es üblicher ist Elemente mit der createElement()-Methode zu erzeugen, können Sie bei Tabellen die Eigenschaften und Methoden des tableObject nutzen.[1]

Beispiel ansehen …
function ueberschriftEinfuegen () {
  const tabelle = document.getElementById('tabelle');
  // schreibe Tabellenüberschrift
  const caption = tabelle.createCaption();
  caption.innerHTML = 'Überschrift';
}
  
function zeileEinfuegen () {
  const tabelle = document.getElementById('tabelle');
  // schreibe Tabellenzeile
  const Reihe = tabelle.insertRow(0);
  for (let i = 0; i < 7; i++) {
    let inhalt = 'Zelle ' + (i+1),
        zelle = reihe.insertCell();
    zelle.innerHTML = inhalt;	
  }
}

In diesem Beispiel erhält die schon vorhandene, aber leere Tabelle bei Klick auf den ersten Button durch createCaption eine Überschrift (falls Sie den Button zweimal klicken, gibt createCaption() das bestehende caption Element zurück)

An den zweite Button wird mit addEventListener eine Funktion zeileEinfuegen() angehängt, die bei einem Click-Event die Tabelle mit document.getElementById aufruft und mit insertRow() eine neue Zeile einfügt. An diese werden in einer Zählschleife 7 Tabellenzellen dynamisch eingefügt. Sie erhalten mit innerHTML einen Text als Inhalt.

Der Kalender

Das Beispiel zeigt eine vollständige HTML-Datei, in der das JavaScript für den Monatskalender eingebunden ist.

Beispiel ansehen …
// dm und dj sind Monat und Jahr, die im Kalender dargestellt werden
// insbesondere könnte auch ein Monat gewählt werden, in dem das aktuelle Datum nicht vorkommt
const d = new Date(),
      dm = d.getMonth() + 1,
      dj = d.getFullYear();

Kalender(dm, dj, 'kalender');

function Kalender (Monat, Jahr, KalenderId) {

  const Monatsname = ["Januar", "Februar", "März", "April", "Mai", "Juni",
                      "Juli", "August", "September", "Oktober", "November", "Dezember"],
        Tag = ["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"];

  // aktuelles Datum für die spätere Hervorhebung ermitteln
  const jetzt = new Date();
  let DieserTag = -1;
  if ( (jetzt.getFullYear() == Jahr) && (jetzt.getMonth() + 1 == Monat) )
    DieserTag = jetzt.getDate();
	  
  // ermittle Wochentag des ersten Tags im Monat halte diese Information in Start fest
  // getDay liefert 0..6 für So..Sa. Wir möchten aber Mo=0 bis So=6, darum +6 und mod 7.
  const Zeit = new Date(Jahr, Monat - 1, 1);
  const Start = (Zeit.getDay() + 6) % 7;

  // die meisten Monate haben 31 Tage...
  let Stop = 31;

  // ...April (4), Juni (6), September (9) und November (11) haben nur 30 Tage...
  if (Monat == 4 || Monat == 6 || Monat == 9 || Monat == 11) --Stop;

  // ...und der Februar nur 28 Tage...
  if (Monat == 2) {
    Stop = Stop-3;
    // ...außer in Schaltjahren
    if (Jahr %   4 == 0) Stop++;
    if (Jahr % 100 == 0) Stop--;
    if (Jahr % 400 == 0) Stop++;
  }

  const tabelle = document.getElementById(KalenderId);
  if (!tabelle)
    return false;
  // schreibe Tabellenüberschrift
  let Monatskopf = Monatsname[Monat - 1] + " " + Jahr,
  caption = tabelle.createCaption();
  caption.innerHTML = Monatskopf;

  // schreibe Tabellenkopf
  let row = tabelle.insertRow(0);
  for (let i = 0; i < 7; i++) {
    let cell = row.insertCell(i);
    cell.innerHTML = Tag[i];
  }

  // ermittle Tag und schreibe Zeile
  let Tageszahl = 1;

  // Monate können 4 bis 6 Wochen berühren. Darum laufen, bis die Tageszahl hinter dem Monatsletzen liegt.
  for (let i = 0; Tageszahl <= Stop; i++) {
    let row = tabelle.insertRow(1 +i);
    for (let j = 0; j < 7; j++) {
      let cell = row.insertCell(j);
     	  
      // Zellen vor dem Start-Tag in der ersten Zeile und Zeilen nach dem Stop-Tag werden leer aufgefüllt
      if ( ((i == 0) && (j < Start)) || (Tageszahl > Stop) ) {
        cell.innerHTML = ' ';
      }
      else {
        // normale Zellen werden mit der Tageszahl befüllt und mit der Klasse Kalendertag markiert
        cell.innerHTML = Tageszahl;
        cell.className = 'kalendertag'
			  
        // und der aktuelle Tag (heute) wird noch einmal speziell mit der Klasse "heute" markiert
        if ( Tageszahl == DieserTag ) {
          cell.className = cell.className+' heute';  
        }
              
        Tageszahl++;	
      }
    }
  }
  return true;
}

Aktuelles Datum ermitteln:

Im Script-Bereich wird zunächst mit d = new Date() ein neues Datumsobjekt mit dem aktuellen Zeitpunkt erzeugt. In den Variablen dm und dj werden anschließend aus dem neuen Datumsobjekt d der Monat und das Jahr ermittelt. Mit diesen beiden Variablen, sowie der ID des table-Elements, in dem der Kalender erzeugt werden soll, wird die Funktion Kalender() aufgerufen.


Funktion "Kalender()":

Die Funktion Kalender() ist als in sich abgeschlossenes Unterprogramm realisiert, das einen Monat und ein Jahr als Parameter erwartet, für die ein Monatskalender angezeigt werden soll. Die id des table-Elements, in dem der Kalender darzustellen ist, wird ebenfalls übergeben. Auf diese Weise lässt sich die Funktion auch noch anderweitig als zur einmaligen Ausgabe des aktuellen Kalendermonats nutzen. Falls die übergebene ID nicht gefunden wird, bricht die Funktion ab und gibt false zurück.

Zu Beginn der Funktion Kalender() werden erst einmal verschiedene Variablen definiert. Dazu gehören die gewünschten Monatsnamen und die Wochentage, die jeweils als Array-Objekte angelegt werden. Wenn Sie andere, zum Beispiel landesspezifische Namen wie "Jänner" wünschen, ändern Sie den entsprechenden Namen einfach.


Ermitteln, ob der aktive Tag im anzuzeigenden Monat liegt:

Da die Funktion Kalender() ja als Parameter übergeben bekommt, welchen Monat in welchem Jahr sie ausgeben soll, kann es sich durchaus um einen anderen als den aktuellen Monat handeln (nur im obigen Beispiel wird die Funktion mit dem aktuellen Monat/Jahr aufgerufen). Die Funktion prüft daher, ob das aktuelle Jahr und der aktuelle Monat übergeben wurden. Wenn ja, wird der aktuelle Tag in DieserTag vermerkt, um ihn im Kalender hervorheben zu können. Wird ein anderer Monat als der aktuelle angezeigt, wird DieserTag auf -1 gesetzt, was keinem Tag im Monat entspricht, sodass es zu keiner Hervorhebung kommt.


Anzeige in Tabelle vorbereiten:

Der Monatskalender soll mit Hilfe der oben besprochenen Methoden in eine HTML-Tabelle geschrieben werden. Zunächst muss jedoch ermittelt werden, wie viele Tage der auszugebende Monat hat, und an welchem Wochentag er beginnt. Davon hängt ab, wie die Tage in die Tabelle geschrieben werden. In der Variablen Start wird der Wochentag gespeichert, auf den der erste Tag des auszugebenden Monats fällt. Dazu wird in einer Variablen Zeit ein Datumsobjekt erzeugt, das sich mit Date(Jahr,Monat-1,1) auf den ersten Tag des auszugebenden Monats bezieht. Mit Zeit.getDay() wird der Wochentag dieses Tages ermittelt. getDay liefert 0 für Sonntag bis 6 für Samstag. Unsere Darstellung wird aber mit dem Montag beginnen, darum erfolgt eine Umrechnung auf 0 für Montag bis 6 für Sonntag.

In der Variablen Stop wird die Anzahl der Tage ermittelt, die der Monat hat. Wenn es einer der Monate 4, 6, 9 oder 11 ist, hat der Monat 30 Tage. Wenn es der Monat 2 ist, ist etwas Kalenderakrobatik erforderlich. Denn dieser Monat kann 28 oder 29 Tage haben, abhängig einmal davon, ob es ein Schaltjahr ist (durch 4 teilbar), ob es trotzdem kein Schaltjahr ist (durch 100 teilbar), oder ob es doch wieder ein Schaltjahr ist (durch 400 teilbar).


Tabelle erzeugen:

Nachdem alle Vorbereitungen getroffen sind, kann die Tabelle mit dem Kalendermonat geschrieben werden. Dies geschieht mit Hilfe der insertRow()- und insertCell()-Methoden, die dynamisch die entsprechenden HTML-Konstrukte in die Datei schreiben. Um den Tabellenkopf mit Monats- und Jahresangabe zu schreiben, erzeugt sie mit createCaption() eine caption. Als nächstes wird eine Row mit den Wochentagnamen erzeugt, und danach die Rows mit den Tageszahlen.

Dafür werden zwei Schleifen ineinander geschachtelt. Die äußere ist für die Erzeugung der Rows zuständig, und läuft so lange, wie die erreichte Tageszahl den Stop-Tag noch nicht überschritten hat. Die innere Schleife ist für die Tageszellen innerhalb der Row verantwortlich und wird pro Row sieben Mal durchlaufen.

Innerhalb der Tagesschleife wird zunächst geprüft, ob eine leere Zelle benötigt wird. Das ist der Fall, wenn man in der ersten Zeile ist und die Spaltennummer noch kleiner ist als der Starttag, und es ist der Fall, wenn die Tageszahl den Stop-Tag übersteigt. Andernfalls wird die Zelle mit der Tageszahl gefüllt und bekommt die kalendertag-Klasse, um sich von den leeren Zellen abzuheben. Falls die Tageszahl dem aktuellen Kalendertag entspricht, wird zusätzlich die heute-Klasse gesetzt. Eine Abfrage auf Jahr und Monat ist nicht nötig, wenn die nicht passen, wurde DieserTag vorab auf -1 gesetzt.

Quellen

  1. MSDN: Table Object