skip to Main Content

I have a simple table, and this table contains thead, tbody and tfoot sections. In JavaScript, I want to be able to access each of these parts to set some attributes.

I try to get the the parts with table.tHead, table.tBody and table.tFoot respectively.

This works for tHead and tFoot just fine, but tBody always returns undefined.

Looking inside the table object with the browser debugger, I can see that table.childNoes and table.children shows all the table parts, including tbody.

Strangely, if I access the tbody section using its ID with document.getElementById("TB") it works just fine.

Can anyone explain this to me? Here’s the source HTML with JavaScript:

let table1 = document.getElementById("TBL1");

if (typeof(table1) != "undefined") {
  console.log(" - table element 'TBL1' acquired");

  let thead = table1.tHead;
  if (typeof(thead) != "undefined") {
    console.log(" - table element table1.tHead acquired,");
    thead.style.color = "#ffff50";
    console.log("   thead color changed to " + thead.style.color);
  } else
    console.log(" OOPS - could not access table table1.tHead");


  let tbody = table1.tBody;
  if (typeof(tbody) != "undefined") {
    console.log(" - table element table1.tBody acquired,");
    tbody.style.color = "#504020";
    console.log("   tbody color changed to " + tbody.style.color);
  } else
    console.log(" OOPS - could not access table table1.tBody");

  let tfoot = table1.tFoot;
  if (typeof(tfoot) != "undefined") {
    console.log(" - table element table1.tFoot acquired,");
    tfoot.style.color = "#ffff50";
    console.log("   tfoot color changed to " + tfoot.style.color);
  } else
    console.log(" OOPS - could not access table table1.tFoot");
} else
  console.log("OOP - Couldn't acquire TBL1 table");

if (typeof(tbody) == "undefined") {
  tbody = document.getElementById("TB");
  if (typeof(tbody) != "undefined")
    console.log(" - table element table1.tBody acquired using getElementById('TB'),");
  tbody.style.color = "#504020";
  console.log("   tbody color changed to " + tbody.style.color);
}

console.log(" - Done with table element access test");
thead,
tfoot {
  background-color: #3f87a6;
  color: #ffff;
}

tbody {
  background-color: #64d0c0;
  color: #ffff;
}

caption {
  padding: 10px;
  caption-side: bottom;
}

table {
  border-collapse: collapse;
  border: 2px solid rgb(120, 120, 120);
  letter-spacing: 1px;
  font-family: sans-serif;
  font-size: 0.8rem;
}

td,
th {
  border: 1px solid rgb(120, 120, 120);
  padding: 5px 10px;
}

td {
  text-align: center;
}
<body>
  <script>
    document.body.style.backgroundColor = "#A0C0C0";
    console.log("Testing table element access -");
  </script>

  <div ID="DIV1">
    <table ID="TBL1" style="margin-left: 100px; margin-top: 100px;">
      <caption>
        Council budget (in £) 2018
      </caption>

      <thead ID="TH">
        <tr ID="HROW">
          <td>Items</td>
          <td scope="col">Expenditure</td>
        </tr>
      </thead>

      <tbody ID="TB">
        <tr ID="BROW1">
          <td scope="row">Donuts</td>
          <td>3,000</td>
        </tr>
        <tr ID="BROW2">
          <td scope="row">Stationery</td>
          <td>18,000</td>
        </tr>
      </tbody>

      <tfoot ID="TF">
        <tr ID="FROW">
          <td scope="row">Totals</td>
          <td>21,000</td>
        </tr>
      </tfoot>
    </table>
</body>

3

Answers


  1. There is no tBody property on a HTMLTableElement. There can be multiple tbody elements within a single table, so there’s a tBodies collection which returns a NodeList of them all.

    In your example, as you know there is only a single tbody instance, you can access the 0th element by index:

    let table1 = document.getElementById("TBL1");
    
    if (table1) {
      let thead = table1.tHead;
      if (thead) {
        thead.style.color = "#ffff50";
      }
    
      let tbody = table1.tBodies[0]; // Note the property name and index accessor here
      if (tbody) {
        tbody.style.color = "#504020";
      }
    
      let tfoot = table1.tFoot;
      if (tfoot) {
        tfoot.style.color = "#ffff50";
      }
    }
    thead,
    tfoot {
      background-color: #3f87a6;
      color: #ffff;
    }
    
    tbody {
      background-color: #64d0c0;
      color: #ffff;
    }
    
    caption {
      padding: 10px;
      caption-side: bottom;
    }
    
    table {
      border-collapse: collapse;
      border: 2px solid rgb(120, 120, 120);
      letter-spacing: 1px;
      font-family: sans-serif;
      font-size: 0.8rem;
    }
    
    td,
    th {
      border: 1px solid rgb(120, 120, 120);
      padding: 5px 10px;
    }
    
    td {
      text-align: center;
    }
    <div id="DIV1">
      <table id="TBL1" style="margin-left: 100px; margin-top: 100px;">
        <caption>
          Council budget (in £) 2018
        </caption>
        <thead id="TH">
          <tr ID="HROW">
            <td>Items</td>
            <td scope="col">Expenditure</td>
          </tr>
        </thead>
        <tbody id="TB">
          <tr id="BROW1">
            <td scope="row">Donuts</td>
            <td>3,000</td>
          </tr>
          <tr id="BROW2">
            <td scope="row">Stationery</td>
            <td>18,000</td>
          </tr>
        </tbody>
        <tfoot id="TF">
          <tr id="FROW">
            <td scope="row">Totals</td>
            <td>21,000</td>
          </tr>
        </tfoot>
      </table>
    </div>

    If there will ever be multiple tbody elements within your table, then you could implement a loop to iterate through them all.

    Also, as an aside, note that it’s generally good practice to keep attributes in your HTML in lowercase, and to avoid using inline style attributes. Use external stylesheets for all styling.

    Login or Signup to reply.
  2. A table can have more than one body, and hence there is no single tBody property on an HTMLTableElement but instead a tBodies array1.

    Therefore, you can access your table body using table1.tBodies[0] (returning the first and only body your table has).

    It’s always good to verify in the docs first whether some property you are trying to use even exists, and if it doesn’t, what other properties there are which may do what you want!


    1: Technically, it’s a NodeList and not an array.

    Login or Signup to reply.
  3. For completeness sake, here is the same using querySelector

    document.body.style.backgroundColor = "#A0C0C0";
    console.log("Testing table element access -");
    
    
    let table1 = document.getElementById("TBL1");
    
    if (typeof(table1) != "undefined") {
      console.log(" - table element 'TBL1' acquired");
    
      let thead = table1.querySelector('thead');
      if (typeof(thead) != "undefined") {
        console.log(" - table element table1 thead acquired,");
        thead.style.color = "#ffff50";
        console.log("   thead color changed to " + thead.style.color);
      } else
        console.log(" OOPS - could not access table table1.tHead");
    
    
      let tbody = table1.querySelector('thead'); // first thead. Use querySelectorAll to get more
      if (typeof(tbody) != "undefined") {
        console.log(" - table element table1 tbody #1 acquired,");
        tbody.style.color = "#504020";
        console.log("   tbody color changed to " + tbody.style.color);
      } else
        console.log(" OOPS - could not access table table1.tBody");
    
      let tfoot = table1.querySelector('tfoot');
      if (typeof(tfoot) != "undefined") {
        console.log(" - table element table1 tFoot acquired,");
        tfoot.style.color = "#ffff50";
        console.log("   tfoot color changed to " + tfoot.style.color);
      } else
        console.log(" OOPS - could not access table table1.tFoot");
    } else
      console.log("OOP - Couldn't acquire TBL1 table");
    
    tbody = document.getElementById("TB");
    if (typeof(tbody) != "undefined")
      console.log(" - table element table1 tbody acquired using getElementById('TB'),");
    tbody.style.color = "#504020";
    console.log("   tbody color changed to " + tbody.style.color);
    
    
    console.log(" - Done with table element access test");
    #TBL1 {margin-left: 100px; margin-top: 100px;}
    
    thead,
    tfoot {
      background-color: #3f87a6;
      color: #ffff;
    }
    
    tbody {
      background-color: #64d0c0;
      color: #ffff;
    }
    
    caption {
      padding: 10px;
      caption-side: bottom;
    }
    
    table {
      border-collapse: collapse;
      border: 2px solid rgb(120, 120, 120);
      letter-spacing: 1px;
      font-family: sans-serif;
      font-size: 0.8rem;
    }
    
    td,
    th {
      border: 1px solid rgb(120, 120, 120);
      padding: 5px 10px;
    }
    
    td {
      text-align: center;
    }
    <div id="DIV1">
      <table id="TBL1">
        <caption>
          Council budget (in £) 2018
        </caption>
    
        <thead id="TH">
          <tr id="HROW">
            <td>Items</td>
            <td scope="col">Expenditure</td>
          </tr>
        </thead>
    
        <tbody id="TB">
          <tr id="BROW1">
            <td scope="row">Donuts</td>
            <td>3,000</td>
          </tr>
          <tr id="BROW2">
            <td scope="row">Stationery</td>
            <td>18,000</td>
          </tr>
        </tbody>
    
        <tfoot id="TF">
          <tr id="FROW">
            <td scope="row">Totals</td>
            <td>21,000</td>
          </tr>
        </tfoot>
      </table>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search