![]() |
DHTML:
|
|
| |
| E-Mail: | |
|---|---|
| Homepage-URL: |
Bei Fragen zu diesem Beitrag bitte den Autor des Beitrags kontaktieren!
Wenn Sie eine typische Datentabelle anbieten, müssen Sie bei statischem HTML entscheiden, nach welchem Spalten-Sortierkriterium die Tabellenzeilen angezeigt werden. Mit Hilfe von DHTML können Sie eine solche Entscheidung dem Anwender überlassen. Er kann die Tabelle selber nach den einzelnen Spalten sortieren und sich damit verschiedene Präsentationen des gleichen Datenbestandes ansehen. In unserem folgenden Beispiel nehmen wir folgende Datentabelle an (Quelle: Statistisches Bundesamt, Jahr: 2000):

Die Tabelle ist in dieser Form unsortiert und intern in drei Gruppen (zuerste alte Bundesländer, dann neue Bundesländer, dann Städte) aufgeteilt. Um in einer solchen Tabelle nach aussagekräftigen Informationen der Sorte "welche Länder haben das höchste Pro-Kopf-Einkommen" zu suchen, muss der Betrachter sich mühsam durch Spalten und Zeilen wühlen und einiges im Kopf behalten. Eine dynamische Anwendung, die ihm die Tabelle nach beliebigen Spalten wahlweise aufsteigend oder absteigend sortiert, würde ihm diese Arbeit abnehmen. Genau das soll in der nachfolgenden Beispielanwendung mit DHTML realisiert werden.
Das Beispiel funktioniert in der vorliegenden Form sowohl mit modernen, DOM-fähigen Browsern, als auch mit älteren, problematischen Browsern wie Netscape 4.x. Da wir die Tabellensortierung nur auf einer Seite benötigen, notieren wir den JavaScript-Code der Einfachheit halber in die entsprechende HTML-Datei. Der Code ist jedoch allgemein geschrieben, so dass es auch möglich ist, ihn in eine separate JavaScript-Datei auszulagern und auf benötigten Seiten einzubinden.
Anzeigebeispiel:
So sieht's aus
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<style type="text/css">
#Kopfbereich { position:absolute; top:20px; left:30px; }
#Tabelle { position:absolute; top:100px; left:30px; }
body { background-color:#FFFFFF; }
h1,h2,h3,p,ul,ol,li,td,th { font-family:Arial,sans-serif; color:black; }
h1 { font-size:24px; margin-top:4px; margin-bottom:4px; margin-left:6px; }
p,ul,ol,li,td,th { font-size:13px; color:#000000; }
th,td { padding:1px; }
</style>
<script type="text/javascript">
<!--
var Tabellendaten = new Array(
"Baden-Württemberg","28305","6793","32312",
"Bayern","28746","4863","31285",
"Hessen","29998","9466","30070",
"Niedersachsen","22259","10416","29686",
"Nordrhein-Westfalen","25166","11022","31960",
"Rheinland-Pfalz","22400","10958","29353",
"Saarland","22413","13087","29295",
"Schleswig-Holstein","22304","12486","30119",
"Brandenburg","16084","10978","25855",
"Mecklbg.-Vorp","16037","10497","24682",
"Sachsen","16266","6871","25883",
"Sachsen-Anhalt","15783","12471","25149",
"Thüringen","16082","11130","25709",
"Berlin","22143","27757","27757",
"Bremen","33062","33978","33978",
"Hamburg","42097","32121","32131",
"Deutschland gesamt","24658","10053","30078"
);
var sortierte_Tabellendaten = new Array(Tabellendaten.length);
var Spaltenueberschriften = new Array(
"Land",
"Brutto-Inlands-produkt pro Einwohner (in Euro)",
"Öffentliche Schulden pro Einwohner (in DM)",
"Einkommen pro Einwohner 1999 (DM)"
);
var Spalten = Spaltenueberschriften.length;
var Zeilen = Tabellendaten.length / Spalten;
var Spaltenueberschriftformatierungen = new Array(
"width=\"250\" valign=\"top\" style=\"text-align:left; border:solid 1px #808080\"",
"width=\"100\" valign=\"top\" style=\"text-align:right; border:solid 1px #808080\"",
"width=\"100\" valign=\"top\" style=\"text-align:right; border:solid 1px #808080\"",
"width=\"100\" valign=\"top\" style=\"text-align:right; border:solid 1px #808080\""
);
var Spaltenformatierungen = new Array(
"width=\"250\" style=\"text-align:left; border:solid 1px #808080\"",
"width=\"100\" style=\"font-family:Courier New,courier; text-align:right; border:solid 1px #808080\"",
"width=\"100\" style=\"font-family:Courier New,courier; text-align:right; border:solid 1px #808080\"",
"width=\"100\" style=\"font-family:Courier New,courier; text-align:right; border:solid 1px #808080\""
);
var Spaltensortierungen = new Array(
"alphabetisch","numerisch","numerisch","numerisch"
);
var Tabellenformatierung = "border=\"1\" style=\"border:solid 1px #808080\" cellspacing=\"0\"";
var Ordinalzahlenspalte = 1;
var Ordinalzahlenspaltenformatierung = "width=\"20\" style=\"border:solid 1px #808080\"";
var IconNormalAuf = "<img src=\"normal_auf.gif\" width=\"14\" height=\"12\" border=\"0\" alt=\"\">";
var IconNormalAb = "<img src=\"normal_ab.gif\" width=\"14\" height=\"12\" border=\"0\" alt=\"\">";
var IconSortiertAuf = "<img src=\"sortiert_auf.gif\" width=\"14\" height=\"12\" border=\"0\" alt=\"\">";
var IconSortiertAb = "<img src=\"sortiert_ab.gif\" width=\"14\" height=\"12\" border=\"0\" alt=\"\">";
var Sortierzeile = "";
function Erzeuge_Sortierzeile(Nummer,Richtung) {
Sortierzeile = "<tr>";
if(Ordinalzahlenspalte)
Sortierzeile += "<th " + Ordinalzahlenspaltenformatierung + "> <\/th>";
for(var j = 0; j < Spalten; ++j) {
Sortierzeile += "<th " + Spaltenformatierungen[j] + ">";
if(Richtung == "aufsteigend" && j == Nummer) {
Sortierzeile += IconSortiertAuf + " ";
Sortierzeile += "<a href=\"javascript:Sortiere_nach_Spalte(" + j + ",'" + Spaltensortierungen[j] + "','absteigend')\">" + IconNormalAb + "</a>";
}
else if(Richtung == "absteigend" && j == Nummer) {
Sortierzeile += "<a href=\"javascript:Sortiere_nach_Spalte(" + j + ",'" + Spaltensortierungen[j] + "','aufsteigend')\">" + IconNormalAuf + "</a>";
Sortierzeile += " " + IconSortiertAb;
}
else {
Sortierzeile += "<a href=\"javascript:Sortiere_nach_Spalte(" + j + ",'" + Spaltensortierungen[j] + "','aufsteigend')\">" + IconNormalAuf + "</a> ";
Sortierzeile += "<a href=\"javascript:Sortiere_nach_Spalte(" + j + ",'" + Spaltensortierungen[j] + "','absteigend')\">" + IconNormalAb + "</a><\/td>";
}
Sortierzeile += "<\/th>";
}
Sortierzeile += "<tr>";
}
function Sortiere_nach_Spalte(Nummer,Art,Richtung) {
var Spaltendaten = new Array();
var Vergleichsdaten = new Array();
var SortierIndex = new Array();
for(var i = 0; i < Zeilen; ++i)
Spaltendaten[i] = Vergleichsdaten[i] = Tabellendaten[i * Spalten + Nummer];
if(Art == "alphabetisch") Spaltendaten.sort();
if(Art == "numerisch") Spaltendaten.sort(Numsort);
if(Richtung == "absteigend") Spaltendaten.reverse();
for(i = 0; i < Zeilen; ++i)
for(var j = 0; j < Zeilen; ++j)
if(Spaltendaten[i] == Vergleichsdaten[j])
SortierIndex[i] = j;
var Speicher;
for(i = 0; i < Zeilen; ++i)
for(j = 0; j < Spalten; ++j)
sortierte_Tabellendaten[i * Spalten + j] = Tabellendaten[SortierIndex[i] * Spalten + j];
Erzeuge_Sortierzeile(Nummer,Richtung);
Schreibe_Tabelle(sortierte_Tabellendaten);
}
function Schreibe_Tabelle(Array) {
var Tabelleninhalt = "";
Tabelleninhalt += "<table " + Tabellenformatierung + ">";
Tabelleninhalt += "<thead><tr>";
if(Ordinalzahlenspalte)
Tabelleninhalt += "<th " + Ordinalzahlenspaltenformatierung + "> <\/th>";
for(var j = 0; j < Spalten; ++j)
Tabelleninhalt += "<th " + Spaltenueberschriftformatierungen[j] + ">" + Spaltenueberschriften[j] + "<\/th>";
Tabelleninhalt += "<\/tr>";
Tabelleninhalt += Sortierzeile;
Tabelleninhalt += "<\/thead>";
Tabelleninhalt += "<tfoot><\/tfoot>";
Tabelleninhalt += "<tbody>";
for(var i = 0; i < Zeilen; ++i) {
Tabelleninhalt += "<tr>";
if(Ordinalzahlenspalte)
Tabelleninhalt += "<td " + Ordinalzahlenspaltenformatierung + ">" + (i+1) + ".<\/td>";
for(var j = 0; j < Spalten; ++j)
Tabelleninhalt += "<td " + Spaltenformatierungen[j] + ">" + Array[i * Spalten + j] + "<\/td>";
Tabelleninhalt += "<\/tr>";
}
Tabelleninhalt += "<\/tbody>";
Tabelleninhalt += "<\/table>";
if(document.getElementById)
document.getElementById("Tabelle").innerHTML = Tabelleninhalt;
else if(document.all)
document.all.Tabelle.innerHTML = Tabelleninhalt;
else if(document.layers) {
document.Tabelle.document.open();
document.Tabelle.document.write(Tabelleninhalt);
document.Tabelle.document.close();
}
}
function Numsort(a,b)
{ return a-b; }
</script>
<title>Tabelle</title>
</head>
<body onLoad="Erzeuge_Sortierzeile(-1,''); Schreibe_Tabelle(Tabellendaten);">
<div id="Kopfbereich">
<h1>Bundesländer im Vergleich</h1>
<noscript>
<p>Die Daten auf dieser Seite lassen sich nur mit JavaScript-fähigen Browsern und mit eingeschaltetem JavaScript anzeigen!</p>
</noscript>
</div>
<div id="Tabelle"></div>
</body>
</html>
Der HTML-Code der Beispieldatei enthält im body-Bereich zwei Bereiche mit den id-Namen Kopfbereich und Tabelle, die im Dateikopf im style-Bereich mit Hilfe von entsprechenden Individualformaten absolut positioniert werden. Zumindest für die Rückwärtskompatibilität zu Netscape 4.x gibt es zu einer solchen absoluten Positionierung keine Alternative.
Die Tabellendaten selbst sind nicht im HTML-Code notiert. Stattdessen sind sie als "Rohdaten" im script-Bereich der Datei notiert, und zwar zu Beginn des im Array Tabellendaten. Dies ist ein einfacher Array, der jedoch intern wie eine Datensatzsammlung behandelt wird. Jeder Datensatz stellt eine Tabellenzeile dar. Im Beispiel bilden jeweils vier Array-Elemente eine Tabellenzeile. Dass dem so ist, wird jedoch nicht beim Array festgelegt, sondern erst später. Bei der Initialisierung des Arrays mit den Tabellendaten formatieren wir die Daten im Beispiel allerdings gleich so, dass alles, was in eine Tabellenzeile gehört, in einer Zeile steht. Wichtig: alle Array-Elemente werden bei der Initialisierung als Zeichenketten notiert, auch dann, wenn der Inhalt eine reine Zahl darstellt.
Unterhalb des Arrays Tabellendaten wird ein weiteres Array namens
sortierte_Tabellendaten deklariert. Dieser wird jedoch noch nicht
mit Daten initialisiert. Lediglich die Anzahl seiner Elemente wird vorgegeben,
und zwar mit Tabellendaten.length, also der Anzahl der Elemente
des zuvor initialisierten Arrays. In sortierte_Tabellendaten wird
später ein Abbild von Tabellendaten erzeugt, jedoch unter
Berücksichtigung der aktuell ausgewählten Sortierung. So bleibt das
Array mit den Originaldaten unberührt und kann jederzeit wieder als zum
Erzeugen der Tabelle in ihrer Originalform verwendet werden.
Im globalen Teil des script-Bereichs, also außerhalb aller
Funktionen, folgen nun diverse weitere Deklarationen und Initialisierungen von
Arrays und Einzelvariablen. In diesen Daten merkt sich das Script wichtige Details,
die später für die gewünschten Darstellung der Tabelle von Bedeutung
sind.
Im Array Spaltenueberschriften werden die Inhalte der Kopfzeile gesammelt. Für jede Datenspalte sollte eine sinnvolle Überschrift gewählt werden.
Anschließend werden zwei ganz wichtige globale Variablen deklariert und
initialisiert, nämlich Spalten und Zeilen. Spalten
ist dabei die entscheidende Variable, die später an mehreren Stellen zur
Strukturierung der Tabelle verwendet wird. Erst durch den bei Spalten
angegebenen Initialisierungswert weiß das Script, wie es das Array Tabellendaten
zu gliedern hat. In unserem Beispiel hat die Tabelle 4 Datenspalten, also wird
die Variable mit 4 initialisiert. Der korrekte Initialisierungswert für
Zeilen lässt sich dann bereits vom Script selber errechnen.
Die Anzahl der Elemente des Arrays Tabellendaten, geteilt durch
die Anzahl der Spalten, ergibt die Anzahl der Datenzeilen der Tabelle.
Im Array Spaltenueberschriftformatierungen können Sie für jede einzelne Spaltenüberschrift die gewünschten Formatierungen bestimmen. Es handelt sich einfach um einen Attribut-String, der beim Erzeugen der Tabelle ins einleitende <th>-Tag einer Kopfzelle eingefügt wird. Der Attributstring kann erlaubte HTML-Attribute für th-Elemente enthalten, aber natürlich auch ein style-Attribut mit gewünschten CSS-Formaten.
Das Gleiche gilt für das Array Spaltenformatierungen. Hier
wird festgelegt, wie die Zellen der einzelnen Spalten formatiert werden sollen.
Das Array erlaubt es also, jede Spalte individuell zu formatieren. Das erste
Element ist der HTML-Attribut-String für die erste Datenspalte, das zweite
für die zweite Datenspalte usw.
Im Array Spaltensortierungen legen Sie fest, nach welchem Algorithmus sortiert werden soll, falls nach der betreffenden Spalte sortiert wird. Zur Auswahl stehen die beiden möglichen Werte "alphabetisch" oder "numerisch". Bei Spalten, die Namen oder dergleichen als Daten enthalten, sollten Sie "alphabetisch" wählen, und bei Spalten mit reinen Zahlendaten "numerisch". Jeder Array-Eintrag steht für den Sortier-Algorithmus einer Spalte. Der erste Eintrag also für die erste Datenspalte, der zweite für die zweite Datenspalte usw.
Die Variable Tabellenformatierung legt den HTML-Attribut-String für das einleitende <table>-Tag der Tabelle fest. Auch hier sind alle üblichen HTML- und CSS-Angaben möglich.
Mit der Variablen Ordinalzahlenspalte bestimmen Sie, ob die Tabelle vor den Datenspalten eine Spalte mit durchnummerierten Zeilen enthalten soll. Dies kann bei sortierten Daten interessant sein, um die Rangfolge der Daten besser zu sehen. In unserem Beispiel wird die Variable mit 1 initialisiert. Das bedeutet, eine Ordinalzahlenspalte wird vor den Datenspalten eingefügt, wie ja auch auf der Abbildung weiter oben sichtbar ist. Wenn Sie keine solche Spalte wollen, initialisieren Sie die Variable mit 0. In der zusätzlichen Variable Ordinalzahlenspaltenformatierung können Sie den HTML-Attribut-String angeben, um die Ordinalzahlenspalte nach Wunsch zu formatieren.
Als nächstes werden vier Variablen deklariert, deren Initialisierungswert der HTML-Code zum Referenzieren einer Grafik ist. Es handelt sich um die anklickbaren Grafiken, die das Sortieren der Tabelle auslösen. Insgesamt brauchen Sie zwei Grafiken für die Sortierrichtungen "aufsteigend" und "absteigend" sowie zwei davon abgeleitete, z.B. andersfarbige Grafiken für "aktive Sortierung". In unserem Beispiel haben wir folgende Grafiken gebastelt:

Wird die Tabelle unsortiert angezeigt, erhält jede Spalte unterhalb der Spaltenüberschriften und oberhalb der Spaltendaten jeweils die beiden ersten dieser Grafiken, nämlich die Symbole für aufsteigende und absteigende Sortierung. Alle Grafiken sind in Links eingebettet, so dass sie anklickbar sind. Beim Anklicken wird die Script-Funktion zum Sortieren der Tabelle nach der Spalte dieser Grafik und der Sortierrichtung dieser Grafik aufgerufen. Wird die Tabelle dann sortiert dargestellt, erhält die Spalte, nach der sortiert wird, beim Symbol der Sortierrichtung, nach der sortiert wird, eine der beiden Highlight-Grafiken zugewiesen. Diese ist im Gegensatz zu allen anderen auch nicht in einen Verweis eingebettet und nicht anklickbar. So kann der Betrachter jederzeit optisch erkennen, nach welcher Spalte aktuell sortiert wird, und in welcher Sortierreihenfolge. Er kann eine andere Spalte und eine andere Sortierrichtung auswählen, aber nicht nochmals auf die bereits aktive Sortierung und Sortierreihenfolge klicken.
Um diese gewünschte Funktionalität zu erreichen, wird im Script anschließend eine Variable namens Sortierzeile deklariert. Ihre Wertzuweisung ist nicht trivial, so dass sie erst einmal nicht initialisiert wird. Stattdessen ist die unterhalb davon notierte Funktion Erzeuge_Sortierzeile() dafür zuständig, diese Variable mit Inhalt zu versorgen.
Zwei weitere Funktionen, Sortiere_nach_Spalte() und Schreibe_Tabelle(), enthalten den restlichen JavaScript-Code des Beispiels. Bevor wir uns dem Inhalt dieser Funktionen widmen, ist es wichtig zu verstehen, wann und wie sie aufgerufen werden. Im einleitenden <body>-Tag der Beispieldatei steht folgender Aufruf:
<body onLoad="Erzeuge_Sortierzeile(-1,''); Schreibe_Tabelle(Tabellendaten);">
Nach dem Laden der Seitendaten wird also zunächst die Funktion Erzeuge_Sortierzeile() aufgerufen, und anschließend die Funktion Schreibe_Tabelle(). Diese Reihenfolge ist wichtig, da beim Schreiben der Tabelle bereits der HTML-Code der Zeile mit den anklickbaren Sortiergrafiken vorausgesetzt wird. Dieser aber wird von Erzeuge_Sortierzeile() erst erzeugt. Der Funktion Erzeuge_Sortierzeile() werden bei dem Erstaufruf zwei etwas seltsam anmutende Parameter übergeben, nämlich der Wert -1 und eine leere Zeichenkette. Dies ist ein kleiner Trick. Als Parameter erwartet die Funktion nämlich, welche Grafik in welcher Spalte als aktive Sortierung gekennzeichnet werden soll. Da wir in unserem Beispiel aber zunächst die Tabelle ohne Sortierung ausgeben wollen, mit den Daten, wie sie in den Rohdaten notiert sind, übergeben wir als Spaltennummer den unerreichbaren Wert -1, und für die Sortierreihenfolge den ebenfalls zu nichts führenden Wert der leeren Zeichenkette.
Der Funktion Schreibe_Tabelle() wird beim Erstaufruf aus dem einleitenden <body>-Tag der Parameter Tabellendaten übergeben. Die Funktion erwartet als Parameter den Namen des Arrays, aus dem sie die zu schreibenden Daten holen soll. Da wir erst einmal die unsortierte Version unserer Tabellendaten ausgeben wollen, übergeben wir den Namen des Arrays, in dem die Tabellendaten als Rohdaten notiert sind.
Der JavaScript-Code der Funktion Schreibe_Tabelle() besteht im wesentlichen darin, die zu Beginn der Funktion deklarierte Variable Tabelleninhalt mit immer mehr Inhalt zu füllen. Mit Hilfe etlicher Zeichenkettenadditionen, beginnend jeweils mit Tabelleninhalt +=, wird der jeweils schon vorhandene Inhalt der Variablen um den dahinter notierten Zeichenkettenausdruck erweitert. Auf diese Weise entsteht der komplette HTML-Code der Tabelle, mitsamt allen gewünschten Formatierungen. Da Tabellen als Anzahl von Zeilen geschrieben werden, steckt das Erzeugen des Codes in einer for-Schleife, die zeilenweise arbeitet. Innerhalb dieser for-Schleife wiederholen sich Code-Fragmente für jede einzelne Spalte. Deshalb kommt eine innere for-Schleife zum Einsatz, die spaltenweise HTML-Code erzeugt.
In der kurzen Anweisung Tabelleninhalt += Sortierzeile steckt ebenfalls eine Menge HTML-Code. Denn die Variable Sortierzeile wurde ja zuvor durch Aufruf der Funktion Erzeuge_Sortierzeile() mit ihrem Inhalt versorgt. Sie enthält den HTML-Code der Zeile mit den anklickbaren Sortiersymbolen.
Das Einfügen der Tabelle in das Dokument ist dagegen vergleichsweise einfach. Am Ende der Funktion Schreibe_Tabelle() wird nach den typischen DHTML-Modellen unterschieden. Abhängig davon wird der Inhalt der Variablen Tabelleninhalt nach entsprechender Syntax in den positionierten Bereich Tabelle eingefügt.
Versuchen wir nun noch zu verstehen, wie eigentlich die Sortierung funktioniert. Innerhalb der Funktion Erzeuge_Sortierzeile() wird ja der HTML-Code der Tabellenzeile mit den anklickbaren Sortiersymbolen erzeugt. Dort sind auch die einzelnen HTML-Links notiert, die das eigentliche Sortieren auslösen. In diesen Links wird jeweils die Funktion Sortiere_nach_Spalte() aufgerufen, die für die Datensortierung verantwortlich ist. Diese Funktion erwartet drei Parameter. Im ersten Parameter wird die Nummer der Spalte angegeben, nach der die Tabelle sortiert werden soll. Für die erste Datenspalte muss 0 übergeben werden, für die zweite Datenspalte 1 usw. In den Links der Funktion Erzeuge_Sortierzeile() wird an dieser Stelle jeweils der for-Schleifenzähler j übergeben, da dessen Wert für die aktuelle Spalte steht. Als zweiten Parameter erwartet die Funktion Sortiere_nach_Spalte(), in welcher Form sortiert werden soll. Als mögliche Werte werden "alphabetisch" oder "numerisch" erkannt. In den Links wird hierfür auf die im Array Spaltensortierungen gespeicherten Werte zurückgegriffen. Im dritten Parameter wird der Sortierfunktion schließlich mitgeteilt, ob die Sortierung auf- oder absteigend sein soll. Erkannt werden die Werte "aufsteigend" bzw. "absteigend".
Die Funktion Sortiere_nach_Spalte() deklariert zu Beginn drei leere Arrays, die sie als Hilfsmittel benötigt. Die beiden Arrays Spaltendaten und Vergleichsdaten werden zunächst mit den gleichen Inhalten versorgt, nämlich mit allen Daten der Spalte, nach der sortiert werden soll. Beide Arrays enthalten also anschließend so viele Elemente, wie die Tabelle Datenzeilen hat, wobei jedes Element den Inhalt der Zelle aus der zu sortierenden Spalte speichert.
Anschließend wird das Array Spaltendaten sortiert. Wenn
alphabetisch sortiert werden soll, genügt der einfache Aufruf der Methode
sort(), die zum Array-Objekt von JavaScript gehört. Soll numerisch
sortiert werden, muss beim Aufruf der sort()-Methode zusätzlich
der Name einer Funktion übergeben werden, die einen einfachen numerischen
Wertevergleich durchführt. Im Beispiel wird der Funktionsname Numsort
übergeben. Am Ende des script-Bereichs ist die kleine Funktion Numsort()
notiert, die genau die gewünschte Aufgabe leistet.
Normalerweise sortiert die sort()-Methode aufsteigend. Soll aber
absteigend sortiert werden, muss zusätzlich die reverse()-Methode
aufgerufen werden, die ebenfalls zum Array-Objekt von JavaScript gehört.
Nach diesen Manipulationen sind in den beiden Arrays Spaltendaten
und Vergleichsdaten immer noch die gleichen Daten gespeichert,
jedoch an unterschiedlichen Plätzen innerhalb des Arrays. Denn Spaltendaten
wurde ja sortiert, während Vergleichsdaten unverändert
blieb. Damit ist die Voraussetzung geschaffen, um das dritte zu Beginn deklarierte
Array, nämlich SortierIndex, zu füllen. In einer verschachtelten
for-Schleife wird überprüft, welcher Element-Inhalt von
Spaltendaten welchem Element-Inhalt von Vergleichsdaten
entspricht. Die Nummer des jeweiligen Array-Elements aus Vergleichsdaten wird
dem aktuellen Element von SortierIndex zugewiesen. In SortierIndex
stehen also am Ende eine Reihe von Zahlen, und zwar so viele, wie die Tabelle
Datenzeilen besitzt, z.B. 6, 9, 11, 2, 8, 1, 13 usw. Die erste Zahl bedeutet:
nach Sortierung dieser Spalte steht die Zeile aus den Originaldaten mit dieser
Indexnummer (z.B. 6) an erster Stelle, die Originalzeile mit der zweiten Indexnummer
(9) an zweiter Stelle usw.
Das Script weiß nun, in welcher Reihenfolge es auf die Originaldaten,
gespeichert im Array Tabellendaten, zugreifen muss, um aus dessen
Daten das Array sortierte_Tabellendaten mit Inhalt zu füllen.
In einer weiteren verschachtelten for-Schleife wird das Array sortierte_Tabellendaten
Element für Element gefüllt, wobei die Zahlen, die in SortierterIndex
gespeichert sind, als Schlüssel für den Zugriff auf das Rohdaten-Array
Tabellendaten dienen.
Solchen nicht ganz trivialen Speichermanipulationen werden Sie bei der fortgeschrittenen DHTML-Programmierung immer wieder begegnen. Denn DHTML besteht nicht immer nur darin, Daten dynamisch auszutauschen, sondern manchmal auch darin, viele Daten in kontrollierter Form zu manipulieren. In den meisten Fällen gibt es dabei mehr als einen Lösungsweg, und es gibt elegantere und weniger elegante Algorithmen, um die jeweilige Aufgabe zu lösen. In den meisten Fällen dieser Art benötigen Sie Hilfsvariablen, wie in unserem Fall die Arrays Spaltendaten, Vergleichsdaten und SortierIndex. Nur so kann sich Ihr Script Daten zwischenspeichern bzw. merken, ohne andere, vorhandene Daten, die nicht verändert werden sollten, zu zerstören. Da Sie bei JavaScript im Normalfall auch nicht mit uferlosen Datenmassen zu tun haben, ist der für solche Hilfsvariablen benötigte Arbeitsspeicher kein ernsthaftes Thema. Wichtiger ist, dass gefundene Lösungen möglichst allgemeingültig sind. So ist etwa unser Beispielscript so geschrieben, dass es völlig egal ist, wie viele Datenspalten und Datenzeilen Ihre zu sortierende Tabelle enthält, und was in welcher Spalte steht. Der Code ist also wiederverwendbar.
Die folgenden Stellen werden empfohlen, um das obige Beispiel besser zu verstehen, oder um weitere Möglichkeiten und Details zu erfahren.
SELFHTML: DHTML-Kapitel
SELFHTML: Objektreferenz des Array-Objekts
WebFX: DOM-basierte Tabellensortierung
Perlunity: Weiteres Script zur Tabellensortierung
irt.org: Weiteres Script zur Tabellensortierung
sortieralgorithmen.de (Domainname = Inhalt)