Kalender

Dynamische Elemente mit DOM-Methoden

Die vorgestellten Mini-Monats-Kalender sind in Javascript programmiert und werden vorwiegend mit Document-Object-Model (DOM)-Methoden gesteuert.
Die Beispiele demonstrieren einige Möglichkeiten der dynamischen Programmierung von Webseiten.
Leider beherrscht der Browser des Marktführers DOM-Methoden nur unvollständig, daher ist die Programmierung noch recht aufwändig.
Mit modernen Browsern kann das Beispiel komplett mit DOM-Methoden arbeiten.
Javascript ECMAScript für HTML und XML
DOM Zugriff auf alle Elemente einer Webseite
Kalender 1 Aufwändige Kompromisse für Browser-Probleme
Programmierung Vereinfachter und erklärter HTML und Javacript-Code
Kalender 2 Reiner DOM-Code
Programmierung Vereinfachter und erklärter HTML und Javacript-Code
Kalender 3 Pseudo-Tabelle, Reiner DOM-Code
Programmierung Vereinfachter und erklärter HTML und Javacript-Code
Popup Mini-Kalender in einem eigenen Fenster
Verwandte Themen Tabellen, CSS-Formatierung (mit Javascript)

Mini-Monats-Kalender   (Kompromisse für den Marktführer..)
Klick ! auf einen Kalender-Tag:
Struktur/Array:
 
ISO-String:  
DIN-String:  
SQL:
 
Der M$IE Browser des Marktführer hat viele Schwächen. Diese Kalender-Version kompensiert einige davon mit erheblichem Aufwand. Die Datum-Eingabe mit Klick auf einen Kalender-Tag hat viele Vorteile:
Für AnwenderInnen bequemer, schneller und übersichtlicher, für die Verarbeitung frei von Eingabe-Fehlern !
Prozessor-Zeit (ihres PC)
Lade-Zeit   
Änderungs-Zeit   
Die Lade-Zeit (Erzeugung einer leeren Kalender-Tabelle) fällt einmalig beim Laden der Webseite an.
Die Änderungs-Zeit fällt bei jedem Monats-Wechsel an, erstmalig (automatisch) beim Laden der Webseite. Sie variiert etwas, je nach Auslastung des Prozessors.
Details zur Programmierung (teilweise mit DOM-Methoden).

Mini-Monats-Kalender   (DOM-Methoden)

Wenn das Kalender-Feld leer bleibt, dann beherrscht ihr Browser nicht alle Standard DOM-Methoden oder macht dabei Fehler. Probieren sie in diesem Fall moderne Browser wie Firefox, Opera etc.
 
Klick ! auf einen Kalender-Tag:
Struktur/Array:
 
ISO-String:  
DIN-String:  
SQL:
 
Prozessor-Zeit (ihres PC)
Lade-Zeit    
Die Lade-Zeit (Erzeugung einer kompletten Kalender-Tabelle mit Daten) fällt bei jedem Monats-Wechsel an, erstmalig (automatisch) beim Laden der Webseite. Sie variiert etwas, je nach Auslastung des Prozessors.
Details zur Programmierung (komplett mit DOM-Methoden).

Mikro-Monats-Kalender   (Pseudo-Tabelle, DOM-Methoden)

Winzige Kalender lassen sich mit Pseudo-Tabellen herstellen: Hier werden einfache Text-Zeilen an Stelle einer Tabelle verwendet. Die 'Formatierung' erfolgt mit Leerzeichen. Der Trick funktioniert nur mit monospace-Schriften (alle Zeichen gleich breit). Durch den Verzicht auf die Tabelle funktioniert der reine DOM-Code auch mit M$IE.
calendar3 Klick ! auf einen Kalender-Tag:
Struktur/Array:
 
ISO-String:  
DIN-String:  
SQL:
 
Prozessor-Zeit (ihres PC)
Lade-Zeit    
Die Lade-Zeit (Erzeugung eines kompletten Kalenders mit Daten) fällt bei jedem Monats-Wechsel an, erstmalig (automatisch) beim Laden der Webseite. Sie variiert etwas, je nach Auslastung des Prozessors.
Details zur Programmierung (komplett mit DOM-Methoden).

Popup-Kalender

Mit Klick auf das Kalender-Icon öffnen sie ein kleines Kalender-Fenster. Es ist von dieser Webseite unabhängig und kann daher zusammen mit jedem anderen Programm verwendet werden. Der Kalender wird mit dem gleichen Programm erzeugt wie im Beispiel ganz oben.
Leider kann der M$IE Browser je nach Version und Einstellung evtl. kein Mini-Fenster für den Kalender öffnen. Überlegen sie die Verwendung eines wirklich modernen Browsers, z.B. Firefox, Opera, ..
Das Kalender-Icon ist übrigens kein Bild ! Es ist ganz normaler Text, der mit DOM-Methoden erzeugt und mit CSS formatiert ist.
Die Apache-Feder im Navigations-Rahmen (links) führt zu einem etwas versteckten Teil der Startseite, auf dem sie u.a. diesen Kalender und eine Uhr finden.
Das Popup ist eine 'abgemagerte' Mini-Webseite, die fast nichts anderes enthält als den Kalender.

M$IE-kompatible Programmierung

Strategie

Ein Kalender wird ganz offensichtlich am besten mit einer Tabelle dargestellt.

Der meist-verwendete Browser kann zwar mit DOM-Methoden Tabellen herstellen, verlangt dazu jedoch die Berücksichtigung einiger Sonder-Regeln.
Daher wird folgender Umweg gewählt:

Zunächst wird eine leere Tabelle erzeugt. Das ist in HTML kein Problem. Allerdings ist der Kalender dann nicht mehr portabel, denn es ist unerfahrenen EntwicklerInnen nicht zumutbar, eine HTML-Tabelle mit genauen (!) Vorgaben zu erstellen.

Daher wird die Tabelle mit den Inline-Methoden von Javascript erstellt. Das ist wesentlich stabiler, weil die Verwendung auf eigenen Webseiten nur wenig Aufwand erfordert. Allerdings sind diese Methoden veraltet und nicht XML-kompatibel.

Jede Zelle der Tabelle erhält ein eindeutiges id-Attribut. Damit ist sie für die nachfolgende Bearbeitung mit DOM-Methoden geeignet.

Die Zellen der fertigen Tabelle können mit DOM-Methoden beliebig verändert werden:
Man kann die Daten des aktuellen Monats eintragen, oder zu einem beliebigen anderen Monat wechseln.

Das Beispiel bietet darüber hinaus die Möglichkeit, bei Klick auf einen Tag die Daten an eine private Javascript-Funktion weiterzugeben. Dafür wäre das onclick-Attribut besonders geeignet.

Leider zeigt sich hier ein weiteres, jahrelang nicht behobenes Problem von M$IE: Der Wert des Attributs kann zwar (je nach Monat) geändert werden, der onclick-Handler spricht dann aber nicht mehr an.
Daher wird jede einzelne Zelle mit einem Hyperlink ausgestattet - Das funktioniert sogar mit M$IE . .
Aufbau einer Tabelle mit Inline-Javascript:
Dieser Code muss im <body> einer Webseite enthalten sein, und zwar genau an jener Stelle, wo die Kalender-Tabelle entstehen soll.
Das Beispiel erzeugt 'an Ort und Stelle' eine einfache Tabelle mit 6 Zeilen zu je 7 Spalten.
Die Methode document.write erhält als Argument den zu schreibenden HTML-Code als String. Im Quelltext der angezeigten Seite ist der Javascript-Code sichtbar, nicht jedoch der damit erzeugte HTML-Code.
Hinweis: Zum Tabellen-Aufbau werden wegen notorischer M$IE-Probleme keine DOM-Methoden verwendet. Die gezeigte Methode ist außerdem nicht XHTML kompatibel.
Javascript (vereinfacht):
<script type="text/javascript">
document.write("<table>");
for(var i=0;i<6;i++) { // Zeilen
document.write("<tr>");
for(var j=0;j<7;j++) { // Spalten
document.write("<td>");
document.write("&nbsp;</td>");
}
document.write("</tr>");
}
document.write("</table>");
</script>

id-Attribute

Für den Zugriff mit DOM-Methoden sind mehrere Varianten möglich. Die beste Voraussetzung sind eindeutige id-Attribute für jede einzelne Zelle der Tabelle.
Das Beispiel zeigt, wie man solche Attribute mit Javascript erzeugen kann:
An Stelle des einfachen <td>-Elements im ersten Beispiel wird ein Element mit id-Attribut erzeugt.
Die Attribute werden in einer Schleife systematisch erstellt, z.B. lautet das id-Attribut der Zelle in Zeile i=3, Spalte j=4 auf "z3s4"
Einfacher HTML-Code (Ausschnitt aus dem Beispiel oben):
document.write("<td>");
Erweiterung mit id-Attributen für jede Zelle:
t = "<td";
id = "z"+i.toString();
id += "s"+j.toString();
t += id + ">";
document.write(t);   // <td id="z1s1">

DOM-Zugriff

Mit DOM-Methoden kann man prinzipiell erst nach dem Aufbau einer Webseite auf deren Elemente zugreifen - Vorher existieren diese Elemente noch nicht.
Das Ereignis (event) onLoad wird nach dem Abschluss des Lade-Vorgangs ausgelöst und wird oft zur Initialisierung mit DOM-Methoden verwendet.
Dazu wird das <body>-Element mit dem Attribut onLoad versehen. Dort wird die Javascript-Funktion angegeben, welche bei onLoad auszuführen ist.
In der bezeichneten Funktion (hier my_onload) werden alle auszuführenden Arbeiten organisiert.
Details zu Ereignissen (events)
<html>
<head>
...
<script type="text/javascript">
function my_onload() {
alert("onLoad !");
}
</script>
</head>
<body onload="my_onload()">
...
</body>

DOM-Elemente und Tochter-(Child)-Elemente

Die Daten befinden sich nicht in den adressierbaren Elementen (nodes), sondern in einem oder mehreren Tochter-Knoten.
Das ist notwendig, wenn man die Daten z.B. mit <span style="...">-Elementen formatieren will, oder wenn die Daten von einem <a href="..."> Hyperlink umschlossen werden sollen.
Details zu DOM-Methoden, Text-Knoten
HTML-Beispiele für Daten in einer Tabellen-Zelle (vereinfacht):
<td id="z1s1">123</td>
<td id="z1s2"><span>234</span></td>
<td id="z2s3"><a><span>345</span></a></td>
Das <td>-Element mit dem Attribut id="z1s1" enthält nur einen childNode, die Daten "123" als String (Text-Knoten).
Element id="z1s2" enthält einen childNode (span-Element), dieser jedoch einen weiteren childNode mit den Daten.
Element id="z2s3" enthält insgesamt 3 verschachtelte childNodes

Alte Daten entfernen

Das Beispiel rechts zeigt, wie man aus einem DOM-Element (z.B. aus einer Tabellen-Zelle) alle vorhandenen Daten entfernt.
Es funktioniert unabhängig davon, welche und wie viele Tochter-Elemente im Element enthalten sind.
Javascript: Alle Tochter-Elemente entfernen.
var n = document.getElementById("z2s4");
while(n.childNodes.length>0) {
n.removeChild(n.firstChild);
}

Neue Daten eintragen

Nach der Entferung aller alten Daten werden neue eingetragen:
Dazu wird ein neues Text-Element (TextNode) mit den gewünschten Daten erzeugt, und an das bereits vorher adressierte Element (Tabellen-Zelle) angehängt (append).
Nach Ausführung dieses Codes zeigt die Zelle in der Webseite die Daten "987" an.
Javascript: Daten eintragen
var nt = document.createTextNode("987");
n.appendChild(nt);
Das Beispiel wirkt genauso wie dieser HTML-Code
<td id="z2s4">987</td>
Der kleine Unterschied: HTML kann nur einmalig geladen werden, Javascript DOM-Code kann beliebig oft und mit programmierbaren Daten ausgeführt werden - In einem Kalender z.B. bei Monats-Wechsel.

Komplexe Daten eintragen

Für höhere Ansprüche müssen meist mehrere Elemente eingetragen werden. Das geschieht schrittweise und erscheint für AnfängerInnen meist etwas komplex:
Im Beispiel wird zuerst das Ziel-Element (Tabellen-Zelle) mit dem gesuchten id-Attribut adressiert.
Aus den Daten (hier die Zahl 876) wird ein Text-Element nt erzeugt.
Danach wird ein <a> Hyperlink-Element na erzeugt.
Das Link-Ziel wird als Attribut href erzeugt und an das Element na angehängt.
Das Text-Element nt wird an das Hyperlink-Element na angehängt.
Das fertige Hyperlink-Element na wird an die Tabellen-Zelle n angehängt.
Nach Ausführung des Codes enthält die Zelle die Daten "876". Beim Anklicken wird die Funktion test mit dem Argument 876 aufgerufen.
Mehrere Elemente erzeugen und anhängen:
var n = document.getElementById("z1s3");
var na = document.createElement("a");
var nah = document.createAttribute("href");
nah.nodeValue = "javascript:test(876)";
na.setAttributeNode(nah);
var nt = document.createTextNode("876");
na.appendChild(nt);
n.appendChild(na);

Das Beispiel erzeugt in einer bestehenden Zelle folgende Struktur:
<td id="z1s3">
<a href="javascript:test(876)">876</a>
</td>
Die gewünschte Zelle ist mit Hilfe des systematischen id-Attributs (hier z1s3) programmierbar, der Daten-Inhalt (hier 876) ebenfalls.
Details zur Anwendung von DOM-Methoden mit Javascript Details zum Kalender-Beispiel können sie dem Quellcode dieser Webseite entnehmen. HTML und Javascript Code ist frei zugänglich !

DOM Programmierung

Strategie:

Einfach und übersichtlich:
Eine allenfalls bestehende Kalender-Tabelle wird gelöscht.
Danach wird eine neue Tabelle mit den Daten des gewünschten Monats erzeugt.

Diese Methode ist wird ungefähr gleich schnell ausgeführt wie die oben vorgestellte, ist aber wesentlich flexibler und übersichtlicher zu programmieren.

Einsatz von DOM-Methoden

DOM-Methoden kann man prinzipiell erst nach dem Aufbau einer Webseite anwenden.
Für den Einbau des DOM-Kalenders wird an der gewünschten Stellen ein leeres Element (hier mit id="calendar2" ) in die Webseite eingebaut: Dieses Element gibt es erst nach Aufbau der Webseite.
Nach Aufbau der Webseite wird das Ereignis (event) onLoad ausgelöst. Es wird hier verwendet, um die Funktion my_onload zu starten.
Diese oder eine ähnliche Funktion kann man verwenden, um DOM-Zugriffe (Lesen / Schreiben) an der Webseite automatisch auszuführen - Hier: Kalender des aktuellen Monats erstellen.
Darüber hinaus stehen DOM-Methoden zu jedem späteren Zeitpunkt für interaktive Zugriffe (User-Steuerung) zur Verfügung (Kalender anderer Monate).
<html>
<head>
...
<script type="text/javascript">
function my_onload() {
alert("onLoad !");
}
</script>
</head>
<body onload="my_onload()">
 ...
<div id="calendar2"></div>
 ...
</body>

Alte Daten entfernen

Das Beispiel zeigt, wie man aus einem DOM-Element alle vorhandenen Daten entfernt. Es funktioniert unabhängig davon, welche und wie viele Tochter-Elemente im Element enthalten sind.
Javascript: Alle Tochter-Elemente entfernen.
var n = document.getElementById("calendar2");
while(n.childNodes.length>0) {
n.removeChild(n.firstChild);
}
Aufbau einer Tabelle mit DOM-Methoden:
Die Tabelle wird schrittweise aufgebaut:
Jedes Element wird einzeln erzeugt, am besten in genau der gleichen Reihenfolge wie im äquivalenten HTML-Code (darunter).
Wenn ein Element fertig ist, wird es an sein übergeordnetes Element (parent) angehängt. So erhält z.B. jedes <td>-Element einen TextNode als childNode, jedes <tr>-Element erhält 6 fertige <td>-Elemente usw.
Das <tbody>-Element ist (nur) für M$IE-Browser notwendig.
Zuletzt wird die fertige Tabelle an das gewünschte Element (hier <div> ) angehängt. Gleichzeitig wird die Tabelle in der Webseite angezeigt.
var n = document.getElementById("calendar2");
ntab = document.createElement("table");
ntby = document.createElement("tbody");
for(var i=0;i<6;i++) {
ntr = document.createElement("tr");
for(var j=0;j<7;j++) {
ntd=document.createElement("td");
txt = "z"+i+"s"+j;
ntxt = document.createTextNode(txt);
ntd.appendChild(ntxt);
ntr.appendChild(ntd);
}
ntby.appendChild(ntr);
}
ntab.appendChild(ntby);
n.appendChild(ntab);
Der gezeigte Javascript-DOM-Code erzeugt eine Tabelle, die äquivalent zum rechts gezeigten HTML-Code ist.
Die Tabelle funktioniert genauso wie eine mit HTML-Quellcode erzeugte Tabelle. Im Quelltext der angezeigten Webseite finden sie jedoch nur das (beim Laden noch leere) Element <div id="calendar2"></div>
Der kleine Unterschied: HTML-Code wird nur einmalig beim Laden ausgeführt, Javascript kann beliebig oft mit programmierten Daten ausgeführt werden.
<div id="calendar2">
<table>
<tbody>
<tr><td>z0s0</td> . . . </tr>
...
<tr> . . . <td>z5s6</td></tr>
</tbody>
</table>
</div>

Ergänzungen

Die gezeigten Beispiele sind vereinfacht, damit das angewendete System erkennbar ist. Ein praktisch verwendbarer Kalender ist etwas komplizierter:
Unterhalb der <td>-Elemente werden in manchen Fällen weitere zusätzliche childNodes erzeugt. Sie werden mit der gleichen Methode (append) angehängt, ergeben jedoch eine komplexere Struktur.
Viele Elemente erhalten Attribute. Das wird rechts an einem Beispiel gezeigt.
Erzeugung von Attributen mit DOM-Methoden:
ntd = document.createElement("td");
att = document.createAttribute("class");
att.nodeValue = "csstest";
ntd.setAttributeNode(att);

Das Beispiel wirkt so wie dieser äquivalente HTML-Code
<td class="csstest">
Details der Programmierung können sie dem HTML und Javascript-Quellcode dieser Webseite entnehmen. Beides ist frei einzusehen. Die Verwendung erfolgt auf eigenes Risko.

DOM Programmierung einer Pseudo-Tabelle

Strategie:

Einfach und übersichtlich:
Ein allenfalls bestehender Kalender wird gelöscht.
Danach wird ein neuer Kalender mit den Daten des gewünschten Monats erzeugt.
Eine Pseudo-Tabelle besteht aus einfachen Text-Zeilen. Die 'Formatierung' erfolgt wie bei der guten alten Schreibmaschine mit Leerzeichen.

Vorteil: Sieht aus wie eine Tabelle, kommt jedoch ohne Tabellen-Elemente aus. Funktioniert daher auch mit M$IE. Kann durch Verzicht auf die Tabellen-Linien besonders klein gehalten werden.
Nachteil: Der Trick funktioniert nur mit monospace-Schriften. In diesen Schriften sind alle Zeichen gleich breit. Daher kann man durch geschickte Wahl der Zeichen den Eindruck einer Tabelle hervorrufen.

Pseudo-Tabelle

Das Beispiel zeigt, wie mit Hilfe von Leerzeichen eine Tabelle simuliert wird. Das sieht einfach aus, der Teufel steckt jedoch im Detail.
Zeile einer HTML-Tabelle (verkürzt)
<tr><td>Mo</td><td>Mi</td><td>So</td></tr>
Zeile einer Pseudo-Tabelle
<div>Mo Mi So</div>

Geschützte Leerzeichen

HTML formatiert beliebig viele aufeinander folgende Leerzeichen so wie ein einziges. Daher müssen sie geschützte Leerzeichen zur Formatierung einsetzen.
Geschützes Leerzeichen: Unicode +00A0,   HTML-Code &nbsp;

<span>a      b</span>
<span>c&nbsp;&nbsp;&nbsp;d</span>
Ein Browser zeigt dieses Beispiel so an:
a bc   d

Spezielle Formatierung

Wenn einige Zellen (z.B. Sonntage) der Pseudo-Tabelle individuell formatiert werden sollen, dann müssen sie dafür eigene Elemente erzeugen.
Das wird umso komplizierter, je mehr Spezialfälle sie dabei berücksichtigen wollen.
Alle 'Zellen' gleich formatiert:
<div>Mo Mi So</div>
Eine Zelle anders formatiert:
<div>Mo Mi <span class="sonntag">So<span></div>

Hyperlinks

komplizieren die Lösung weiter. Da der M$IE Browser mit DOM-Methoden leider keine onclick-Attribute verwalten kann, müssen zusätzlich Hyperlink-Elemente erzeugt werden.
Eine Zelle mit Hyperlink:
<a href="javascript:my_onclick()">
<span class="sonntag">So<span>
</a>