![]() |
Dynamisches HTML:
|
|
| |
| E-Mail: | |
|---|---|
| Homepage-URL: |
Bei Fragen zu diesem Beitrag bitte den Autor des Beitrags kontaktieren!
Oft kommt es vor, dass man Datensätze aus einer Datenbank (oder aus einer sonstigen Datenquelle) als tabellarische Liste anzeigen will, um dem Besucher die Möglichkeit zu geben, einen oder mehrere Datensätze auswählen.
Üblicherweise wird hierzu ein
select-Element
verwendet, dieses bereitet aber einige Schwierigkeiten - so ist eine spaltenweise Darstellung nur möglich, wenn man dem select-Element eine monospace-Schriftart zuweist und die Texte der einzelnen Spalten mit non-breaking-spaces ( ) auffüllt.
Schöner wäre es aber eigentlich, wenn man eine echte HTML-Tabelle benutzen könnte.
Das ist an sich auch kein Problem, wenn man in die erste Spalte einen
Radiobutton
(wenn nur ein Datensatz ausgewählt werden darf) oder aber eine
Checkbox
(wenn mehrere Datensätze ausgewählt werden dürfen) setzt. Dabei geht aber leider die Möglichkeit verloren, an eine beliebige Stelle der Tabellenzeile zu klicken, um den Datensatz auszuwählen.
Durch eine geschickte Kombination von Radiobuttons oder Checkboxen, des
Label-Elements, etwas CSS und Javascript kann man dies aber doch erreichen. Zumindest in DOM-fähigen Browsern.
Bei älteren Browsern (und modernen Browser, die das Label-Element nicht unterstützen) ist die Funktion der Checkboxen/Radiobuttons immer noch vorhanden, lediglich der Fullrow-Select geht verloren.
Anzeigebeispiel: So sieht's aus
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Datensatzauswahl mit Fullrowselect</title>
<style type="text/css">
<!--
body { background-color:white; }
table.selectrows { border:1px solid black; }
table.selectrows td { padding:1px; margin:0; }
table.selectrows tr.checked { background-color:#00c; color:white; }
table.selectrows tr.unchecked { background-color:white; color:black; }
table.selectrows label { display:block; width:100%; height:100%; margin:0; padding:0; border:none; }
-->
</style>
<script type="text/javascript"><!--
function rowclickedcheck(checkid, rowid)
{
window.setTimeout("colorizeRow('"+checkid+"','"+rowid+"')",300); //delay ist notwendig, weil der Eventhandler ausgelöst wird, bevor die Checkbox umgeschaltet wird...
return true;
}
function colorizeRow(idcheck, idrow)
{
document.getElementById(idrow).className = ((document.getElementById(idcheck).checked) ? "checked" : "unchecked");
}
function rowclickedradio(checkid, rowid,count)
{
window.setTimeout("colorizeRowRadio('"+checkid+"','"+rowid+"','" + count + "')",300); //delay ist notwendig, weil der Eventhandler ausgelöst wird, bevor die Checkbox umgeschaltet wird...
return true;
}
function colorizeRowRadio(idcheckcommon, idrowcommon, count)
{
for (i = 1; i <= count; i++)
{
idrow = "" + idrowcommon + i;;
idcheck = "" + idcheckcommon + i;
document.getElementById(idrow).className = ((document.getElementById(idcheck).checked) ? "checked" : "unchecked");
}
}
//--></script>
</head>
<body>
<h1>Auswahltabelle - Radiobuttons</h1>
<form name="theform" action="" method="GET">
<table class="selectrows">
<tr class="unchecked" id="rownr1"><td><input type="checkbox" id="checknr1" name="checknr1" onclick="return rowclickedcheck('checknr1','rownr1');" onkeyup="return rowclickedcheck('checknr1','rownr1');"></td><td><label for="checknr1">Vereinigtes Königreich von Großbritannien und Nordirland</label></td><td><label for="checknr1">London</label></td></tr>
<tr class="unchecked" id="rownr2"><td><input type="checkbox" id="checknr2" name="checknr2" onclick="return rowclickedcheck('checknr2','rownr2');" onkeyup="return rowclickedcheck('checknr2','rownr2');"></td><td><label for="checknr2">Deutschland</label></td><td><label for="checknr2">Berlin</label></td></tr>
<tr class="unchecked" id="rownr3"><td><input type="checkbox" id="checknr3" name="checknr3" onclick="return rowclickedcheck('checknr3','rownr3');" onkeyup="return rowclickedcheck('checknr3','rownr3');"></td><td><label for="checknr3">Frankreich</label></td><td><label for="checknr3">Paris</label></td></tr>
</table>
<hr>
<table class="selectrows">
<tr class="unchecked" id="row1"><td><input type="radio" id="radio1" value="radio01" name="radio" onclick="return rowclickedradio('radio','row',3);" onkeyup="return rowclickedradio('radio','row',3);"></td><td><label for="radio1">Vereinigtes Königreich von Großbritannien und Nordirland</label></td><td><label for="radio1">London</label></td></tr>
<tr class="unchecked" id="row2"><td><input type="radio" id="radio2" value="radio02" name="radio" onclick="return rowclickedradio('radio','row',3);" onkeyup="return rowclickedradio('radio','row',3);"></td><td><label for="radio2">Deutschland</label></td><td><label for="radio2">Berlin</label></td></tr>
<tr class="unchecked" id="row3"><td><input type="radio" id="radio3" value="radio03" name="radio" onclick="return rowclickedradio('radio','row',3);" onkeyup="return rowclickedradio('radio','row',3);"></td><td><label for="radio3">Italien</label></td><td><label for="radio3">Rom</label></td></tr>
</table>
</div>
</form>
</body>
</html>
<tr class="unchecked" id="rownr1">
class und id werden nur im Zusammenhang mit der Umfärbung per Javascript benötigt.
<td><input type="checkbox" id="checknr1" name="checknr1" onclick="return rowclickedcheck('checknr1','rownr1');" onkeyup="return rowclickedcheck('checknr1','rownr1');"></td>
Eine ganz normale Checkbox in einer Tabellenzelle, mit zwei
Event-Handlern,
näheres dazu weiter unten bei Javascript.
<td><label for="checknr1">Vereinigtes Königreich ...</label></td>
Eine von (beliebig vielen) Daten-Tabellenzellen. Entscheidend ist das label-Element, das bewirkt, dass ein Klick auf seinen Inhalt wie ein Klick auf die dazugehörige Checkbox (bzw. Radiobutton) wirkt. Die Verbindung zwischen Checkbox/Radiobutton und dem Label wird durch den Wert im for-Attribut erreicht, der mit dem id-Wert des input-Elements übereinstimmen muss.
<td><label for="checknr1">London</label></td>
Eine weitere Daten-Tabellenzelle. Hier gilt das selbe wie bei der vorherigen. Der Anzahl der Tabellenzellen ist theoretisch keine Grenze gesetzt.
Hier ist vor allem die Zeile
table.selectrows label { display:block; width:100%; height:100%; margin:0; padding:0; border:none; }
entscheidend.
Sie legt fest, dass die label-Elemente (die innerhalb der relevanten Tabellen mit dem
class-Attribut
"selectrows" liegen) als
Block-Elemente
behandelt werden. Dies ist notwendig, damit
width und
height
interpretiert werden. Normalerweise ist label ein
Inline-Element
und für inline-Elemente gelten width und height nicht. Durch das Umschalten auf
block
gelten width und height und damit füllt das label-Element die jeweilige Tabellenzelle
komplett aus, so dass auch zwischen den Texten der einzelnen Spalten geklickt werden kann.
Margin,
padding und
border
werden auch noch auf 0 gesetzt, damit der anklickbare Bereich möglichst groß wird.
table.selectrows tr.checked { background-color:#00c; color:white; }
table.selectrows tr.unchecked { background-color:white; color:black; }
Diese beiden Zeilen werden nur benötigt, um die komplette Zeile umzufärben, je nach Status des Radiobuttons oder der Checkbox.
Javascript wird hier ausschließlich dazu benutzt, die ausgewählten Tabellenzeilen hervorzuheben. Zur normalen Auswahl der Punkte ist Javascript nicht erforderlich!
Zunächst werden Eventhandler definiert:
onclick="return rowclickedcheck('checknr1','rownr1');" onkeyup="return rowclickedcheck('checknr1','rownr1');"
onclick="return rowclickedradio('check','row',3);" onkeyup="return rowclickedradio('check','row',3);"
Sowohl beim Klick auf die Checkbox, auf den Radiobutton als auch beim Betätigen einer Taste wird jeweils eine Funktion aufgerufen. Sie ist unterschiedlich für Checkboxen und Radiobuttons (da bei einer Checkbox nur eine Zeile umgefärbt werden muss, bei Radiobuttons aber mehrere). Für Taste und Mausklick wird die gleiche Funktion aufgerufen.
onchange klingt zwar zunächst nach dem richtigen Eventhandler, aber dieser wird erst ausgelöst, wenn
das input-Element den Fokus verliert.
function rowclickedcheck(checkid, rowid)
{
window.setTimeout("colorizeRow('"+checkid+"','"+rowid+"')",300);
// delay ist notwendig, weil der Eventhandler ausgelöst
// wird, bevor die Checkbox umgeschaltet wird...
return true;
}
Diese Funktion wird bei einem Tastendruck oder einem Klick auf einee Checkbox aufgerufen. Sie macht nichts weiter, als mit etwas Verzögerung eine weitere Funktion aufzurufen, wobei sie die Parameter einfach weiterreicht. Dies ist nötig, da die Events ausgelöst werden, bevor sich der Status der Checkbox geändert hat.
function rowclickedradio(checkid, rowid,count)
{
window.setTimeout("colorizeRowRadio('"+checkid+"','"+rowid+"','" + count + "')",300);
// delay ist notwendig, weil der Eventhandler ausgelöst
// wird, bevor die Checkbox umgeschaltet wird...
return true;
}
Die entsprechende Funktion für Radiobuttons:
function colorizeRow(idcheck, idrow)
{
document.getElementById(idrow).className = ((document.getElementById(idcheck).checked) ? "checked" : "unchecked");
}
Durch Änderung des class-Attributs für die Tabellenzeile wird die Zeile umgefärbt. Als Parameter
werden die id der Checkbox und die id der Tabellenzeile übergeben.
function colorizeRowRadio(idcheckcommon, idrowcommon, count)
{
for (i = 1; i <= count; i++)
{
idrow = "" + idrowcommon + i;;
idcheck = "" + idcheckcommon + i;
document.getElementById(idrow).className = ((document.getElementById(idcheck).checked) ? "checked" : "unchecked");
}
}
Bei Radiobuttons ist etwas mehr Aufwand nötig. Es ändern sich bis zu zwei Buttons: der aktuell angeklickte sowie
derjenige, der zuvor selektiert war. Ich habe es hier so gelöst, dass ich einfach in einer Schleife über alle
Radiobuttons laufe und jeweils die Klasse zuweise, die dem Zustand des Buttons entspricht. Als Parameter erhält die Funktion
den konstanten Namensteil der id der Tabellenzelle und des Radiobuttons sowie die Anzahl der Radiobuttons. So
wie die Funktion implementiert ist, müssen die Zeilen und Radiobuttons IDs der Form
konstant<nummer> haben, ich habe row1, row2, row3 und radio1, radio2, radio3 benutzt.
Opera bis Version 6
kennt das Label-Element nicht und kann Elementen per DOM keine neuen Klassen zuweisen. Der Versuch, das Layout
zu ändern scheitert damit ebenso wie in Netscape 4, Radiobuttons und Checkboxen bleiben jedoch voll funktionsfähig.
Die folgenden Stellen werden empfohlen, um das obige Beispiel besser zu verstehen, oder um weitere Möglichkeiten und Details zu erfahren.
deutsche Seite, SELFHTML HTML, Label-Element
Englische Seite, HTML Standard: Label-Element
deutsche Seite, SELFHTML CSS, Display-Eigenschaft
Englische Seite, CSS Standard: Display-Property