ShihiZu: Tabelle aufklappen

Hi

Unterdessen weiss ich nicht mehr weiter. Ich kriegs nicht gebacken, eine Tabelle zu machen, bei der man auf der Header klickt, sich der Rest der Tabelle zeigt. Momentan bin ich bei dem hier:

  
<script type="text/javascript">  
 function toggle(item) {  
  if (item.nextSibling.firstChild.firstChild.style.display = "none") {  
   item.nextSibling.firstChild.firstChild.style.display = "block";  
  }  
  else {  
   item.nextSibling.firstChild.firstChild.style.display = "none";  
  }  
 }  
</script>  
  
<table>  
 <tr onClick='toggle(this)'>  
  <td><b>Header</b></td>  
 </tr>  
 <tr>  
  <td><div style="display:none;">Text.</div></td>  
 </tr>  
</table>  

Im Prinzip sollte das reichen, bei Opera öffnet sich auf der untere Teil. Geht aber bei zweitem Klicken nicht mehr weg. Firefox macht gar nichts.
Kann mir jemand weiterhelfen?

Grüsse, Shi

  1. hallo,

    Ich kriegs nicht gebacken, eine Tabelle zu machen, bei der man auf der Header klickt, sich der Rest der Tabelle zeigt.

    Hm. Wenn ich "Tabelle" lese, werde ich immer mißtrauisch. Was soll denn deine Tabelle enthalten? Wirklich nur tabellarische Daten?

    function toggle(item) {
      if (item.nextSibling.firstChild.firstChild.style.display = "none") {
       item.nextSibling.firstChild.firstChild.style.display = "block";
      }
      else {
       item.nextSibling.firstChild.firstChild.style.display = "none";
      }
    }

    Das ist zwar ein möglicher Denkansatz, aber ich halte ihn nicht für effizient.

    <table>
    <tr onClick='toggle(this)'>

    Upsa. "onclick" solltest du besser nur für <td> verwenden.

    <td><div style="display:none;">Text.</div></td>

    Und das ist ganz schlecht. Es gibt _absolut keinen_ Grund, in dein <td> noch ein <div> einzusperren. Noch dazu, wenn es "unsichtbar" sein soll.

    Kann mir jemand weiterhelfen?

    Falls ich deine Fragestellung richtig verstanden habe, geht das nach dem Schema:
       <table><tr>
       <td id="z1">Zeile 1</td>
       </tr><tr>
       <td id="z2" onclick="document.getElementById('z3').style.display='block'; this.style.display='none'" style="display:none;">Zeile 2</td>
       <td id="z3" onclick="document.getElementById('z2').style.display='block'; this.style.display='none'">Zeile 3</td>
       </tr></table>
    Wohlgemerkt: das ist das "Schema", und ob das auf deine Bedürfnisse zutrifft, ist fraglich.

    Grüße aus Berlin

    Christoph S.

    --
    Visitenkarte
    ss:| zu:) ls:& fo:) va:) sh:| rl:|
    1. <table>
      <tr onClick='toggle(this)'>

      Upsa. "onclick" solltest du besser nur für <td> verwenden.

      Stimmt, danke!

      <td><div style="display:none;">Text.</div></td>
      Und das ist ganz schlecht. Es gibt _absolut keinen_ Grund, in dein <td> noch ein <div> einzusperren. Noch dazu, wenn es "unsichtbar" sein soll.

      Das weiss ich selber auch. Das Problem an "display: block" ist leider, dass er die Ansicht der Zelle verändert. Ich muss das noch genauer ansehen.

      Falls ich deine Fragestellung richtig verstanden habe, geht das nach dem Schema:
         <table><tr>
         <td id="z1">Zeile 1</td>
         </tr><tr>
         <td id="z2" onclick="document.getElementById('z3').style.display='block'; this.style.display='none'" style="display:none;">Zeile 2</td>
         <td id="z3" onclick="document.getElementById('z2').style.display='block'; this.style.display='none'">Zeile 3</td>
         </tr></table>
      Wohlgemerkt: das ist das "Schema", und ob das auf deine Bedürfnisse zutrifft, ist fraglich.

      Nunja, das wichtigste am Ganzen ist es, dass es relativ funktioniert. Die Funktion muss für mehrere solche Tabellen (unbestimmt viele) immer funktionieren, egal wo jene im Text vorkommen. Deswegen kann ich nicht mit IDs arbeiten (höchstens Arrays). Es geht um eine Forenfunktion.

  2. Hi,

    if (item.nextSibling.firstChild.firstChild.style.display = "none") {
       item.nextSibling.firstChild.firstChild.style.display = "block";
      }
      else {
       item.nextSibling.firstChild.firstChild.style.display = "none";

    Im Prinzip sollte das reichen, bei Opera öffnet sich auf der untere Teil. Geht aber bei zweitem Klicken nicht mehr weg.

    Klar, weil du ja *immer* zuerst den Wert "none" zuweist(!). Das ergibt true, also wird anschliessend "block" zugewiesen.

    Firefox macht gar nichts.

    "block" ist kein geeigneter display-Wert fuer Tabellen-Elemente.

    MfG ChrisB

    --
    "The Internet: Technological marvel of marvels - but if you don't know *what* you're lookin' for on the Internet, it is nothing but a time-sucking vortex from hell."
  3. Mahlzeit ShihiZu,

    Unterdessen weiss ich nicht mehr weiter. Ich kriegs nicht gebacken, eine Tabelle zu machen, bei der man auf der Header klickt, sich der Rest der Tabelle zeigt.

    Ich sehe keinen Tabellen-"Header", sondern nur eine Zeile, die eine Zelle enthält, in der - eingeschlossen in absolut überflüssige <b>-Tags - zufällig dieses Wort steht. Du solltest Deine Tabellen besser strukturieren ... insbesondere, wenn Du unterschiedliche Elemente unterschiedlich behandeln bzw. ihnen unterschiedliche Eigenschaften zuweisen willst:

    <table>  
      <thead>  
        <tr>  
          <th onclick="toggle(this);">Header</th>  
        </tr>  
      </thead>  
      <tbody style="display: none;">  
        <tr>  
          <td>Text</td>  
        </tr>  
      </tbody>  
    </table>  
    <script type="text/javascript">  
      
    [code lang=javascript]function toggle(cell) {  
      var table = cell.parentNode;  
      
      while (table && (table.nodeName != 'TABLE')) {  
        table = table.parentNode;  
      }  
      
      if (table) {  
        var tbody = table.getElementsByTagName('tbody')[0];  
      
        if (tbody) {  
          tbody.style.display = (tbody.style.display == 'none') ? 'table-row-group' : 'none';  
        }  
      }  
    }
    

    </script>[/code]

    MfG,
    EKKi

    --
    sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
    1. Nunja, dein Script funktioniert einwandfrei, sobald ich aber etwas ändern will - z.B. statt auf den Header klicken einen Link einfügen, dann ändere ich auch entsprechend die Variable table, aber dann klappts bei mir wieder nicht. Irgendwie komm ich überhaupt nicht klar damit.

      <table>  
        <thead>  
          <tr>  
            <th><a href="javascript:toggle(this)">Header</a></th>  
          </tr>  
        </thead>  
        <tbody style="display: none;">  
          <tr>  
            <td>Text</td>  
          </tr>  
        </tbody>  
      </table>  
      <script type="text/javascript">
      
        
        
      function toggle(cell) {  
        var table = cell.parentNode.parentNode; //Ein zweites Mal, weil ja der a-Tag ein Child von th ist...  
        
        while (table && (table.nodeName != 'TABLE')) {  
          table = table.parentNode;  
        }  
        
        if (table) {  
          var tbody = table.getElementsByTagName('tbody')[0];  
        
          if (tbody) {  
            tbody.style.display = (tbody.style.display == 'none') ? 'table-row-group' : 'none';  
          }  
        }  
      }  
      </script>
      

      Wahrscheindlich mache ich irgendeinen Denkfehler. Herzlichen Dank trotzdem!

      1. Mahlzeit ShihiZu,

        Nunja, dein Script funktioniert einwandfrei, sobald ich aber etwas ändern will - z.B. statt auf den Header klicken einen Link einfügen,

        Wenn Du einen Link einfügst, dann füg doch auch bitte einen Link ein - und das entscheidende Merkmal für einen Link ist, dass er irgendwo hinlinkt. Ein <a>-Element mit nur Javascript als Ressourcenangabe ist kein Link. Also lass es bleiben und gib lieber dem Element, das angeklickt werden soll, einen entsprechenden http://de.selfhtml.org/html/attribute/eventhandler.htm#uebersicht@title=Eventhandler. Darüber hinaus ist das Pseudoprotokoll "javascript:" überflüssig und falsch:

        <th><span onclick="toggle(this);">Header</span></th>

        dann ändere ich auch entsprechend die Variable table, aber dann klappts bei mir wieder nicht.

        "Klappt nicht" klappt nicht. Was genau funktioniert nicht? Welche Fehlermeldungen treten auf?

        Darüber hinaus brauchst Du die Variable "table" nicht ändern. Das Skript sucht nämlich einfach ausgehend von dem angeklickten Element solange das jeweils übergeordnete Element, bis es bei einem vom Typ <table> angekommen ist.

        Also lass es bei

        var table = cell.parentNode;

        Wahrscheindlich mache ich irgendeinen Denkfehler. Herzlichen Dank trotzdem!

        Wahrscheinlich. :-)

        Wenn es nicht geht und Du aussagekräftige Fehlermeldungen lieferst, könnte man Dir auch helfen ...

        MfG,
        EKKi

        --
        sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
        1. Mahlzeit ShihiZu,

          Nunja, dein Script funktioniert einwandfrei, sobald ich aber etwas ändern will - z.B. statt auf den Header klicken einen Link einfügen,

          Wenn Du einen Link einfügst, dann füg doch auch bitte einen Link ein - und das entscheidende Merkmal für einen Link ist, dass er irgendwo hinlinkt. Ein <a>-Element mit nur Javascript als Ressourcenangabe ist kein Link. Also lass es bleiben und gib lieber dem Element, das angeklickt werden soll, einen entsprechenden http://de.selfhtml.org/html/attribute/eventhandler.htm#uebersicht@title=Eventhandler. Darüber hinaus ist das Pseudoprotokoll "javascript:" überflüssig und falsch:

          <th><span onclick="toggle(this);">Header</span></th>

          Okay, wusste ich nicht. Werde ich beherzigen. Es funktioniert nun einwandfrei mit:

          <th><img src="http://srczupic" style="cursor:pointer;" onclick="toggle(this);" />Header</th>

          Danke!

  4. Hi,

    ergänzend zu den Anmerkungen der anderen (block, = statt == ...)

    if (item.nextSibling.firstChild.firstChild.style.display = "none") {

    <tr onClick='toggle(this)'>
      <td><b>Header</b></td>
    </tr>
    <tr>

    item ist das tr, item.nextSibling ist der textnode, der den Whitespace (Zeilenumbruch, Einrückung) zwischen </tr> und <tr> enthält.
    item.nextSibling.firstChild ist undefiniert, da textnodes keine Kinder haben.

    Firefox macht gar nichts.

    Wirklich gar nichts? Ich würde erwarten, daß er etwas in die Fehlerkonsole schreibt.

    cu,
    Andreas

    --
    Warum nennt sich Andreas hier MudGuard?
    O o ostern ...
    Fachfragen unaufgefordert per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
    1. Hi

      if (item.nextSibling.firstChild.firstChild.style.display = "none") {

      <tr onClick='toggle(this)'>
        <td><b>Header</b></td>
      </tr>
      <tr>

      item ist das tr, item.nextSibling ist der textnode, der den Whitespace (Zeilenumbruch, Einrückung) zwischen </tr> und <tr> enthält.
      item.nextSibling.firstChild ist undefiniert, da textnodes keine Kinder haben.

      Dankeschön, das erklärt einiges. Wenn ich alle Absätze entferne, funktioniert alles so wie es sollte. :)