Museum/Datensatzauswahl aus Tabelle

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Achtung!

Dieser Artikel ist eine Textübertragung aus dem aktuell.de.selfHTML-Bereich.
  • zuerst erschienen: 30.10.2002

Seine Inhalte entsprechen nicht mehr der best practice und sollten nicht für die Umsetzung aktueller Projekte eingesetzt werden.
Eine neue und aktuelle Version dieses Artikels finden sie unter: JavaScript/Tutorials/Datensatzauswahl aus Tabelle--Matthias Scharwies (Diskussion) 08:46, 2. Dez. 2015 (CET)


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 Radio-Button (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.

Das Beispiel

Beispiel ansehen …
<h1>Auswahltabelle</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>

<h1>Radiobuttons</h1>
<table class="selectrows">
  <tr class="unradioed" 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="unradioed" 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="unradioed" 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>
</form>

Der HTML-Teil

Beispiel
<tr class="unchecked" id="rownr1">

Die Attribute class und id von <tr class="unchecked" id="rownr1"> werden nur im Zusammenhang mit der Umfärbung per Javascript benötigt.

Beispiel
<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.

Beispiel
<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.

Beispiel
<td><label for="checknr1">London</label></td>

Eine weitere Daten-Tabellenzelle. Hier gilt dasselbe wie bei der vorherigen. Der Anzahl der Tabellenzellen ist theoretisch keine Grenze gesetzt.


Der CSS-Teil

Beispiel
table.selectrows label { 
  display: block; 
  width: 100%; 
  height: 100%; 
  margin: 0; 
  padding:0; 
  border: none; 
}

Hier ist vor allem diese Festlegung 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 display: block gelten width und height und damit füllt das label-Element die jeweilige Tabellenzelle komplett aus, sodass 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.

Beispiel
table.selectrows tr.checked { background-color:#00c; color:white; }
table.selectrows tr.unchecked { background-color:white; color:black; }</pre>

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:

Beispiel
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.

Beispiel
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.

Beispiel
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:

Beispiel
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.

Beispiel
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.