Menü

 

 

 

de-de

Tabellenfunktionen

Dieses Kapitel beschreibt nicht, wie man mit Tabellen Webseitenlayouts erzeugt. Dafür gibt es CSS. Es geht vielmehr um echte Tabellen, Gestaltungsmöglichkeiten dazu, sortieren, selektieren und auch editieren.

Streifentabelle

Oft möchte man die Lesbarkeit einer Tabelle verbessern, indem man die Zeilen in unterschiedlichen Hintergrundfarben darstellt. Mit PHP geht das recht einfach:

downloadrunCodebeispiel 014:

<?php
// Tabelleninhalte
$tab[0]['nr'] = '001';
$tab[0]['thema'] = 'Styledefinition mit php verändern';
$tab[0]['demo'] = 'x';
$tab[0]['download'] = 'x';
$tab[0]['kapitel'] = '2';

$tab[1]['nr'] = '002';
$tab[1]['thema'] = 'Email-Test mit regulärem Ausdruck in Javasctipt und php';
$tab[1]['demo'] = 'x';
$tab[1]['download'] = 'x';
$tab[1]['kapitel'] = '2';

$tab[2]['nr'] = '003';
$tab[2]['thema'] = 'Formular';
$tab[2]['demo'] = 'x';
$tab[2]['download'] = 'x';
$tab[2]['kapitel'] = '2';

$tab[3]['nr'] = '004';
$tab[3]['thema'] = 'Passwortgenerator';
$tab[3]['demo'] = 'x';
$tab[3]['download'] = 'x';
$tab[3]['kapitel'] = '3';

$tab[4]['nr'] = '008';
$tab[4]['thema'] = 'Registrierungsseite';
$tab[4]['demo'] = '&nbsp;';
$tab[4]['download'] = 'x';
$tab[4]['kapitel'] = '3';

$tab[5]['nr'] = '010';
$tab[5]['thema'] = 'Login-Script';
$tab[5]['demo'] = '&nbsp;';
$tab[5]['download'] = 'x';
$tab[5]['kapitel'] = '3';

$tab[6]['nr'] = '011';
$tab[6]['thema'] = 'Logout-Script';
$tab[6]['demo'] = '&nbsp;';
$tab[6]['download'] = 'x';
$tab[6]['kapitel'] = '3';

$tab[7]['nr'] = '013';
$tab[7]['thema'] = 'Web mit geschützten Seiten';
$tab[7]['demo'] = 'x';
$tab[7]['download'] = 'x';
$tab[7]['kapitel'] = '3';

?>
<!DOCTYPE HTML>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Codebsp_014</title>
<style type="text/css">
<!--
.bg_yellow {
    background-color:#FFFFCC;
}

.bg_green {
    background-color:#CCFFFF;
}
-->
</style>
</head>

<body>
<table width="98%">
  <tr>
    <th scope="col">Nr.</th>
    <th scope="col">Thema</th>
    <th scope="col">Demo</th>
    <th scope="col">Download</th>
    <th scope="col">Kapitel</th>
  </tr>
<?php
//$bgcolor = 'bg_green'; // wird nur bei der auskommentierten Methode gebraucht
for ($i=0;$i<count($tab);$i++) {
/*
    if ($bgcolor=='bg_green') {
        $bgcolor = 'bg_yellow';
    } else {
        $bgcolor = 'bg_green';
    }
*/
    
$bgcolor $i 0x1 'bg_yellow' 'bg_green';
    echo 
'<tr class="'.$bgcolor.'">';
    echo 
'<td class="center">'.$tab[$i]['nr'].'</a></td>';
    echo 
'<td>'.$tab[$i]['thema'].'</td>';
    echo 
'<td class="center">'.$tab[$i]['demo'].'</td>';
    echo 
'<td class="center">'.$tab[$i]['download'].'</td>';
    echo 
'<td class="center">'.$tab[$i]['kapitel'].'</td>';
}
?>
</table>
</body>
</html>

Die Array-Vereinbarungen ($tab[0][...] bis $tab[7][...]) dienen nur einfach dazu, die daten für eine Tabelle zu liefern. Es können natürlich beliebige Daten genutzt werden. Der wichtige Code beginnt mit der Definition der Styles für die 2 Hintergrundfarben. Durch Anwahl der verschiedenen Klassen bg_green und bg_yellow derden Die Farben je <tr> gesetzt. Der Trick dabei ist, dass man die Variable mittels eines Bit-Operators besetzt:

$i zählt normal durch. ox1 ist hexadezimal 1. Der & Operator schaltet als Ergebnis zwischen der laufenden Zahl und der 1 um zwischen 1 und 0, also zwischen wahr und falsch. Wenn der Ausdruck wahr ist, wird das, was hinter dem Fragezeichen steht, gewählt, ansonsten das, was hinter dem Doppelpunkt steht.

Wenn Ihnen das zu "um die Ecke gedacht" ist, können Sie die andere Methode wählen: $bgcolor wird vor der Laufschleife mit bg_green vorbelegt. In der Laufschleife wird dann abgefragt, ob der Wert bg_green ist. Wenn ja, wird auf bg_yellow umgeschaltet; wenn bereits bg_yellow gesetzt ist, wird wieder zurückgeschaltet.

Streifentabelle mit Zellencursor

Gerade bei großen Tabellen mit kleinen Zellen verliert man manchmal den Überblick: zu welcher Spalte gehört nun gerade diese Zelle? Abhilfe schafft ein Zellencursor, der die betreffende Zelle, die dazu gehörende Spalte und auch die dazu gehörende Zeile farblich markiert, also eine Art Fadenkreuz.

Das folgende Codebeispiel funktioniert ausschließlich mit HTML, CSS und Javascript. PHP ist also nicht zwingend notwendig.

downloadrunCodebeispiel 015:

<!DOCTYPE HTML>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Streifentabelle mit Zellencursor</title>
<style type="text/css">
<!--
table {
  width:700px;
}

tr {
  background-color: #CCFF99;
}

td {
  border:1px solid #D9D9D9;
  border-collapse:collapse;
  text-align:center;
}

#playlist {
  border: 1px solid #666666;
}

#playlist tr td {
  padding: 3px 8px;
  border-left: 1px solid #D9D9D9;
}
 
#playlist tr.even td {
  background-color: #edf3fe;
}  
 
#playlist tr td.high {
  background-color: #FFFF00;
}

#playlist tr td.medium {
  background-color: #FFFF99;
}

-->
</style>
<script language="JavaScript" type="text/JavaScript">
<!--

var oldClass = null; // zum speichern der CSS-Klasse der Zelle, in der sich der Cursor aktuell befindet
oldClassTD = new Array(); // zum speichern der CSS-Klasse der Zellenzeile, in der sich der Cursor aktuell befindet
oldClassTR = new Array(); // zum speichern der CSS-Klasse der Zellenspalte, in der sich der Cursor aktuell befindet

onload = function() { stripe ('playlist') }; // Lade die Streifen

// Erzeuge die Streifen mit Javascript
function stripe(id) {
  var table = document.getElementById(id);
  if (!table) { return; }
  var trs = table.getElementsByTagName("tr");
  for (var i=0;i<trs.length;i+=2) { trs[i].className += " even"; }
}

// Farbänderung an den Zellen, die in der Reihe und der Spalte des Cursors sind
function high(tdNumber, id) {
  var table = document.getElementById(id);
  var trs = table.getElementsByTagName("tr");
  var rowNumber = tdNumber.parentNode.rowIndex;
  var tds = trs[rowNumber].getElementsByTagName("td");
  var cellNumber = tdNumber.cellIndex;
  oldClass = tds[cellNumber].className; // Farbe der Zelle
  for (i=0;i<tds.length;i++) {
    oldClassTD[i] = tds[i].className; // Farbe der Spalte
    tds[i].className = "medium";
  }
  for (i=0;i<trs.length;i++) {
    var tdx = trs[i].getElementsByTagName("td");
    oldClassTR[i] = tdx[cellNumber].className; // Farbe der Zeile
    tdx[cellNumber].className = "medium";
  }
  tds[cellNumber].className = "high";
}

// Farbänderung rückgängig in den Zellen, die in der Reihe und der Spalte des Cursors sind
function norm(tdNumber, id) {
  var table = document.getElementById(id);
  var trs = table.getElementsByTagName("tr");
  var rowNumber = tdNumber.parentNode.rowIndex;
  var tds = trs[rowNumber].getElementsByTagName("td");
  var cellNumber = tdNumber.cellIndex;
  for (i=0;i<tds.length;i++) {
    tds[i].className = oldClassTD[i]; // Farbe der Zelle
  }
  for (i=0;i<trs.length;i++) {
    var tdx = trs[i].getElementsByTagName("td");
    tdx[cellNumber].className = oldClassTR[i];
  }
  tds[cellNumber].className = oldClass;
}
-->
</script>
</head>

<body>
<table id="playlist">
  <tr>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">&nbsp;</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">Spalte a</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">Spalte b</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">Spalte c</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">Spalte d</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">Spalte e</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">Spalte f</td>
  </tr>
  <tr>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">Zeile 1</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">a1</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">b1</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">c1</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">d1</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">e1</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">f1</td>
  </tr>
  <tr>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">Zeile 2</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">a2</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">b2</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">c2</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">d2</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">e2</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">f2</td>
  </tr>
  <tr>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">Zeile 3</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">a3</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">b3</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">c3</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">d3</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">e3</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">f3</td>
  </tr>
  <tr>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">Zeile 4</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">a4</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">b4</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">c4</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">d4</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">e4</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">f4</td>
  </tr>
  <tr>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">Zeile 5</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">a5</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">b5</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">c5</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">d5</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">e5</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">f5</td>
  </tr>
  <tr>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">Zeile 6</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">a6</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">b6</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">c6</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">d6</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">e6</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">f6</td>
  </tr>
  <tr>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">Zeile 7</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">a7</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">b7</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">c7</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">d7</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">e7</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">f7</td>
  </tr>
  <tr>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">Zeile 8</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">a8</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">b8</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">c8</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">d8</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">e8</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">f8</td>
  </tr>
  <tr>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">Zeile 9</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">a9</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">b9</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">c9</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">d9</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">e9</td>
    <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">f9</td>
  </tr>
</table>
<p>&nbsp;</p>
<table>
  <tr>
    <td>&nbsp;</td>
    <td>Spalte a</td>
    <td>Spalte b</td>
    <td>Spalte c</td>
    <td>Spalte d</td>
    <td>Spalte e</td>
    <td>Spalte f</td>
  </tr>
  <tr>
    <td>Zeile 1</td>
    <td>a1</td>
    <td>b1</td>
    <td>c1</td>
    <td>d1</td>
    <td>e1</td>
    <td>f1</td>
  </tr>
  <tr>
    <td>Zeile 2</td>
    <td>a2</td>
    <td>b2</td>
    <td>c2</td>
    <td>d2</td>
    <td>e2</td>
    <td>f2</td>
  </tr>
  <tr>
    <td>Zeile 3</td>
    <td>a3</td>
    <td>b3</td>
    <td>c3</td>
    <td>d3</td>
    <td>e3</td>
    <td>f3</td>
  </tr>
  <tr>
    <td>Zeile 4</td>
    <td>a4</td>
    <td>b4</td>
    <td>c4</td>
    <td>d4</td>
    <td>e4</td>
    <td>f4</td>
  </tr>
  <tr>
    <td>Zeile 5</td>
    <td>a5</td>
    <td>b5</td>
    <td>c5</td>
    <td>d5</td>
    <td>e5</td>
    <td>f5</td>
  </tr>
  <tr>
    <td>Zeile 6</td>
    <td>a6</td>
    <td>b6</td>
    <td>c6</td>
    <td>d6</td>
    <td>e6</td>
    <td>f6</td>
  </tr>
  <tr>
    <td>Zeile 7</td>
    <td>a7</td>
    <td>b7</td>
    <td>c7</td>
    <td>d7</td>
    <td>e7</td>
    <td>f7</td>
  </tr>
  <tr>
    <td>Zeile 8</td>
    <td>a8</td>
    <td>b8</td>
    <td>c8</td>
    <td>d8</td>
    <td>e8</td>
    <td>f8</td>
  </tr>
  <tr>
    <td>Zeile 9</td>
    <td>a9</td>
    <td>b9</td>
    <td>c9</td>
    <td>d9</td>
    <td>e9</td>
    <td>f9</td>
  </tr>
</table>
</body>
</html>
 

Wirkung des Scripts nur auf eine Tabelle

Da man ja beliebig viele Tabellen in einer Seite haben kann, muss es einen Mechanismus geben, der dafür sorgt, dass nur die Tabelle Streifen und auch den Cursor enthält, bei der das gewünscht ist. Dazu wird der Tabelle eine id (hier id = playlist) gegeben. Alle Referenzen des CSS beziehen sich ausschließlich auf diese id. Um zu beweisen, dass das funktioniert, habe ich eine zweite Tabelle angegeben, in der der Zellencursor nicht funktioniert.

Die Erzeugung der Streifen

In diesem Beispiel wurden die Streifen mit Javascript erzeugt (statt mit PHP; siehe Codebeispiel 014). Die Funktion stripe prüft zuerst einmal, ob die Tabelle eine id besitzt. Falls ja, wird jede 2. Zeile mit einer anderen Farbe belegt. Die Funktion wird beim Laden der Seite aufgerufen.

Die Erzeugung des Zellencursors

Dazu benötigt man 2 Funktionen (high (= Farbe setzen) und norm (= Farbe in den ursprünglichen Zustand zurücksetzen)), die beim Überfahren der Zelle und beim Verlassen der Zelle aufgerufen werden. Der Aufruf erfolgt per Eventhandler <td onMouseOver="high(this,'playlist')" onMouseOut="norm(this,'playlist')">. Zuerst beschreibe ich die Funktion high:

Am Anfang wird die Zelle mit getElementById identifiziert. Dann werden die Zeilen der Tabelle in trs gespeichert. Danach merkt sich die Funktion die aktuelle Spaltennummer. Alle Zellen der Cursorspalte werden in tds gespeichert. Jetzt muss sich die Funktion die Farben der Zelle merken (in oldClass), damit die Funktion norm diese später wieder herstellen kann. Gleiches passiert mit allen Zellen der betroffenen Zeile und Spalte. Nachdem die Farben gespeichert sind (in oldClassTD und oldClassTR), werden die neuen Farben gesetzt (hier auf medium). Schließlich wird die Zelle, in der der Cursor steht, noch mit der Farbe high belegt. Damit ist der Zellencursor dargestellt.

Die Funktion norm stellt den alten Zustand wieder her, indem die Farben aus den Arrays oldClassTR und oldClassTD wieder eingesetzt werden. Auch die Farbe der Zelle wird wieder hergestellt (oldClass).

Tabelle scrollen mit festem Tabellenkopf

Ich habe schon öfter das Problem gehabt, dass ich eine große Tabelle hatte, bei der bein Scrollen der Tabellenkopf aus dem Fenster verschwand und ich nicht mehr wusste, was nun zu wem gehörte. Eine Lösung ist, den Tabellenkopf als eigene Tabelle in eine div zu setzen und den Tabellenrumpf in eine zweite div darunter, die mit overflow:auto gescrollt werden kann. Dabei ergibt sich allerdings das Problem, dass die Spaltenbreiten von Tabellenkopf und Tabellenrumpf unterschiedlich breit sind, wenn sich Tabellenkopf und Tabellenrumpf automatisch der Breite der Inhalte anpassen.

Feste Spaltenbreite

Es gibt dazu zwei prinzipielle Möglichkeiten: man kann die Spaltenbreiten von Tabellenkopf und Tabellenrumpf per Style-Definition festsetzen. Dies ist in Codebeispiel 016 dargestellt.

downloadrunCodebeispiel 016:

<!DOCTYPE HTML>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Tabelle scrollen mit fester Kopfzeile und fester Spaltenbreite</title>
<style type="text/css">
<!--
table, tr, td {
  margin:0px;
  padding:0px;
  border:solid 1px #000000;
  border-collapse:collapse;
}

#tableheader {
  position:absolute;
  left:10px;
  top:50px;
  width:900px;
  height:22px;
  overflow:hidden;
  background-color:#CCCC66;
}

#tablebody {
  position:absolute;
  left:10px;
  top:72px;
  width:900px;
  height:200px;
  overflow:auto;
  background-color:#FFFFCC;
}

.breite_1 {
  width:85px;
}

.breite_2 {
  width:130px;
}

.breite_3 {
  width:210px;
}

.breite_4 {
  width:300px;
}

.breite_5 {
  width:80px;
}

.tabellenbreite {
  width:805px;
}
-->
</style>
</head>

<body>
<div id="tableheader">
<table class="tabellenbreite">
  <tr>
    <td class="breite_1">Spalte 1</td>
    <td class="breite_2">Spalte 2</td>
    <td class="breite_3">Spalte 3</td>
    <td class="breite_4">Spalte 4</td>
    <td class="breite_5">Spalte 5</td>
  </tr>
</table>
</div>

<div id="tablebody">
<table class="tabellenbreite">
  <tr>
    <td class="breite_1">Hier steht der erste Text</td>
    <td class="breite_2">und</td>
    <td class="breite_3">hier</td>
    <td class="breite_4">sonst</td>
    <td class="breite_5">irgend etwas</td>
  </tr>
  <tr>
    <td>Abra</td>
    <td>kadabra</td>
    <td>Sim</td>
    <td>sala</td>
    <td>bim</td>
  </tr>
  <tr>
    <td>und</td>
    <td>jetzt</td>
    <td>leer</td>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
    <td>ha</td>
    <td>ha</td>
    <td>ha</td>
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
    <td>Noch ein längerer Text, der die Spalte vergrößert</td>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
  <tr>
    <td>Abra</td>
    <td>kadabra</td>
    <td>Sim</td>
    <td>sala</td>
    <td>bim</td>
  </tr>
  <tr>
    <td>und</td>
    <td>jetzt</td>
    <td>leer</td>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
    <td>ha</td>
    <td>ha</td>
    <td>ha</td>
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
    <td>Noch ein längerer Text, der die Spalte vergrößert</td>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
  <tr>
    <td>Abra</td>
    <td>kadabra</td>
    <td>Sim</td>
    <td>sala</td>
    <td>bim</td>
  </tr>
  <tr>
    <td>und</td>
    <td>jetzt</td>
    <td>leer</td>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
    <td>ha</td>
    <td>ha</td>
    <td>ha</td>
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
    <td>Noch ein längerer Text, der die Spalte vergrößert</td>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
</table>
</div>

</body>
</html>
 

Zuerst werden die div-Container für Tabellenkopf und Tabellenrumpf per Style festgelegt. Dann werden die Spaltenbreiten festgelegt. In dem Beispiel sind es die Klassen breite_1 bis breite_5. Es ist wichtig, die Gesamtbreite der Tabelle zusätzlich festzulegen, da sonst der Text die Spalten über die per Style definierte Größe hinaus ausdehnt. Machen Sie einmal die Probe und entfernen Sie die Styledefinition für die Tabellengesamtbreite!

Variable Spaltenbreite

Es wäre schön, wenn man die Spaltenbreiten des Tabellenkopfes so machen könnte, wie sie sich aus den Spaltenbreiten des Tabellenrumpfes ergeben. Das kann man mit Javascript realisieren. Ich habe unterschiedliche Möglichkeiten ausprobiert und bin zuerst einmal daran gescheitert, dass ich nicht wusste, wie ich die aktuellen Spaltenbreiten auslesen kann. Abhilfe schaffen da Scripte von Struppi, welche ich hier mit seiner freundlichen Erlaubnis benutze. Einzelheiten zu diesen Scripten ersehen Sie bitte bei Struppi in seinem Artikel Position eines Elementes ermitteln. Die nächste Schwierigkeit ergibt sich aus der Tatsache, dass die Browser das DOM-Modell unterschiedlich interpretieren. So gibt es bei dem einen Browser unter dem Knoten TR für jedes TD einen Textknoten und den TD-Knoten, bei einem anderen Browser gibt es nur den TD-Knoten. Nachdem ich diese Fakten berücksichtigt hatte, entstand das Codebeispiel 017, das mit IE6, Gecko (Mozilla, Firefox) und Opera funktioniert. Bei anderen Browsern mag es funktionieren; ich habe es aber dort nicht getestet.

downloadrunCodebeispiel 017:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Tabelle scrollen mit fester Kopfzeile und variabler Spaltenbreite</title>
<style type="text/css">
<!--
table, tr, td {
  margin:0px;
  padding:0px;
  border:solid 1px #000000;
  border-collapse:collapse;
}

#tableheader {
  position:absolute;
  left:10px;
  top:50px;
  width:900px;
  height:40px;
  overflow:hidden;
  background-color:#CCCC66;
}

#tablebody {
  position:absolute;
  left:10px;
  top:90px;
  width:900px;
  height:200px;
  overflow:auto;
  background-color:#FFFFCC;
}
-->
</style>

<!-- Scripte von Struppi -->
<script language="JavaScript" type="text/javascript" src="getelementbyid.js"></script>
<script language="JavaScript" type="text/javascript" src="include.js"></script>
<script language="JavaScript" type="text/javascript" src="getrect.js"></script>
<!-- Ende Scripte von Struppi -->

<script language="JavaScript" type="text/javascript">
function breite() {
  var td_rumpf = document.getElementById("tabellenrumpf");
  var td_kopf = document.getElementById("tabellenkopf");
  var i;
  for (i=0;i<td_rumpf.parentNode.childNodes.length;i++) {
    if (td_rumpf.parentNode.childNodes[i].nodeName=='TD') {
      if (i==0) {
        td_kopf.parentNode.childNodes[i].style.width = String(getRect(td_rumpf.parentNode.childNodes[i]).width)+'px';
      } else {
        td_kopf.parentNode.childNodes[i].style.width = String(getRect(td_rumpf.parentNode.childNodes[i]).width-1)+'px';
      }
    }
  }
}
</script>
</head>

<body>

<div id="tableheader">
<table>
  <tr>
    <td id="tabellenkopf">Spalte 1</td>
    <td>Spalte 2</td>
    <td>Spalte 3</td>
    <td>Spalte 4</td>
    <td>Spalte 5</td>
  </tr>
</table>
</div>

<div id="tablebody">
<table width="98%">
  <tr>
    <td id="tabellenrumpf">Hier steht der erste Text</td>
    <td>und</td>
    <td>hier</td>
    <td>sonst</td>
    <td>irgend etwas</td>
  </tr>
  <tr>
    <td>Abra</td>
    <td>kadabra</td>
    <td>Sim</td>
    <td>sala</td>
    <td>bim</td>
  </tr>
  <tr>
    <td>und</td>
    <td>jetzt</td>
    <td>leer</td>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
    <td>ha</td>
    <td>ha</td>
    <td>ha</td>
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
    <td>Noch ein l&auml;ngerer Text, der die Splate vergr&ouml;&szlig;ert</td>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
  <tr>
    <td>Abra</td>
    <td>kadabra</td>
    <td>Sim</td>
    <td>sala</td>
    <td>bim</td>
  </tr>
  <tr>
    <td>und</td>
    <td>jetzt</td>
    <td>leer</td>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
    <td>ha</td>
    <td>ha</td>
    <td>ha</td>
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
    <td>Noch ein l&auml;ngerer Text, der die Splate vergr&ouml;&szlig;ert</td>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
  <tr>
    <td>Abra</td>
    <td>kadabra</td>
    <td>Sim</td>
    <td>sala</td>
    <td>bim</td>
  </tr>
  <tr>
    <td>und</td>
    <td>jetzt</td>
    <td>leer</td>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
    <td>ha</td>
    <td>ha</td>
    <td>ha</td>
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
    <td>Noch ein l&auml;ngerer Text, der die Splate vergr&ouml;&szlig;ert</td>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
</table>
</div>

<script language="JavaScript" type="text/javascript">
breite();
</script>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" name="form1">
<input name="submit" type="submit" value="Zellenbreite" />
<input name="versteckt" type="hidden" value="1" />
</form>
</body>
</html>
 

Zuerst werden wie im Codebeispiel 016 die div-Container für Tabellenkopf und Tabellenrumpf per Style festgelegt. Dann bekommt das erste TD jeder Tabelle eine ID, damit im Script darauf zugegriffen werden kann. Im Script rufe ich zuerst den Knoten mit getElementById auf. Dann erzeuge ich das Elternelement und bestimme davon die Anzahl der Kindknoten. Man hätte das vielleicht auch mit nextSibling machen können, aber damit gab es Probleme beim Abbruchkriterium der Schleife. In der Schleife frage ich ab, ob der Knoten auch TD heißt (Wie ich oben bereits bemerkte, gibt es auch noch Textknoten, die ich hier nicht brauchen kann). Dann schreibe ich in das Style-Attribut width des Tabellenkopf-TDs die Breite des entsprechenden Tabellenrumpf-TDs. Achtung: man muss hier die Breiten von padding und border berücksichtigen. Da ich im Style border-collapse auf collapse gesetzt habe, wird die Rahmenbreite im ersten TD auf 0 und in den folgenden TDs auf 1 gesetzt. Würde border-collapse nicht gesetzt, müssten in jedem TD 2px (rechte und linke Seite) berücksichtigt werden.

Kommentar eintragen

Kommentare zu dieser Seite