Teil von SELFHTML aktuell Teil von Artikel Teil von Dynamisches HTML

Dynamisches HTML:
Datensatzauswahl aus Tabelle mit Fullrowselect

nach unten Andreas Waechter (MudGuard)
nach unten Hinweise zum Thema
nach unten Beispiel mit Erläuterungen
nach unten Weiterführende Links

Andreas Waechter (MudGuard)

E-Mail: E-Mail mail@andreas-waechter.de
Homepage-URL: deutschsprachige Seite http://andreas-waechter.de/

Bei Fragen zu diesem Beitrag bitte den Autor des Beitrags kontaktieren!

nach obennach unten

Hinweise zum Thema

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 bereichsübergreifende Seite 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 bereichsübergreifende Seite Radiobutton (wenn nur ein Datensatz ausgewählt werden darf) oder aber eine bereichsübergreifende Seite 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 bereichsübergreifende Seite 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.

nach obennach unten

Beispiel mit Erläuterungen

Beispiel

Popup-Seite 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>

Erläuterung:

Der HTML-Teil

<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 bereichsübergreifende Seite 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.

Der CSS-Teil

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 bereichsübergreifende Seite class-Attribut "selectrows" liegen) als bereichsübergreifende Seite Block-Elemente behandelt werden. Dies ist notwendig, damit bereichsübergreifende Seite width und bereichsübergreifende Seite height interpretiert werden. Normalerweise ist label ein bereichsübergreifende Seite Inline-Element und für inline-Elemente gelten width und height nicht. Durch das Umschalten auf bereichsübergreifende Seite 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. bereichsübergreifende Seite Margin, bereichsübergreifende Seite padding und bereichsübergreifende Seite 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.

Der Javascript-Teil

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.

Beachten Sie:

Opera bis Version 6 englischsprachige Seite 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.

nach obennach unten

Weiterführende Links

Die folgenden Stellen werden empfohlen, um das obige Beispiel besser zu verstehen, oder um weitere Möglichkeiten und Details zu erfahren.

deutschsprachige Seite deutsche Seite, SELFHTML HTML, Label-Element
englischsprachige Seite Englische Seite, HTML Standard: Label-Element
deutschsprachige Seite deutsche Seite, SELFHTML CSS, Display-Eigenschaft
englischsprachige Seite Englische Seite, CSS Standard: Display-Property

Teil von SELFHTML aktuell Teil von Artikel Teil von Dynamisches HTML

© 2007 bereichsübergreifende Seite Impressum