Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are TH elements missing from the DOM table API?

I'm building HTML tables with the DOM table API, but I'm not sure how to create th elements using said API, and the more I dig the more it seems like I can't.

For example, given a table > thead > tr that has been set up like this:

let table = ...;                 // some HTMLTableElement
let thead = table.createTHead(); // a new HTMLTableSectionElement
let row = thead.insertRow();     // a new HTMLTableRowElement

If I do this, it inserts a td, not a th:

row.insertCell().textContent = 'something';

So, I have to do this instead:

let th = document.createElement('th');
th.textContent = 'something';
row.appendChild(th);

... which works fine (and is what I'm doing now), but doesn't use the table API, which seems weird.

So, I looked through the MDN docs as hard as I could but the th elements seem to be missing from the API entirely, and I'm not sure if that's on purpose, or if it's an oversight, or if th's just aren't cool any more, or if they're there but I'm missing something:

  • HTMLTableRowElement.insertCell specifically notes that it can't be used to insert a th.
  • HTMLTableRowElement doesn't seem to have any other method for it (and also there's some broken links on that MDN page).
  • HTMLTableSectionElement doesn't have any special stuff for rows in a header.
  • HTMLTableElement.createTHead() just returns an HTMLTableSectionElement, not some thead-specific object with specialized methods for headers or whatever.
  • Looking through the index, there doesn't appear to be anything that could be specific to a th, at least not in the vicinity of the other "HTMLTable..." things.

Even without th-specific API, I would have expected e.g. some behind-the-scenes magic that made the element returned by createTHead().insertRow().insertCell() be a th instead of a td or something.

So, the fact that the DOM table API seems to cover every single aspect of dealing with tables except for th makes me feel like I am missing something, and my questions are:

  • Assuming I'm not missing anything, what happened... ? Why is TH (apparently) omitted from the API?
  • But, if I am misinterpreting, then, is there a way to create th elements with the table-specific API?

Here is an example snippet. The createOneTable function is some boilerplate table creation stuff, and its parameter is a function used to create header cells. It is set up like this to (hopefully) make the interesting parts clear. The stylesheet will set th backgrounds to yellow.

// in the callbacks below:
//   header: an HTMLRowElement of a table>thead>tr
//   str: text to insert
//   postcondition: cell containing str appended to header

createOneTable((header, str) => {
  // this inserts a td
  header.insertCell().textContent = str;
});

createOneTable((header, str) => {
  // this just doesn't use the table api
  let cell = document.createElement('th');
  cell.textContent = str;
  header.appendChild(cell);
});

//---------------------------------------------

function createOneTable (addth) {

  const DATA = [
    [ 'First Name', 'Last Name', 'Favorite Food' ],
    [ 'Jason', 'C', 'Rocks' ],
    [ 'Sam', 'Hamwich', 'Spiderwebs' ],
    [ 'Debbie', 'Downer', 'Pine cones' ]
  ];

  let table = document.createElement('table');

  // thead: create header row then populate
  let thead = table.createTHead();
  let header = thead.insertRow();
  for (let str of DATA[0])
    addth(header, str);

  // tbody: create content rows then populate
  let tbody = table.createTBody();
  for (let strs of DATA.slice(1)) {
    let row = tbody.insertRow();
    for (let str of strs)
      row.insertCell().textContent = str;
  }

  document.body.appendChild(table);

}

if (typeof(jQuery) !== 'undefined')
  throw Error("Weird, because I don't *see* a jquery tag on the question...");
table { border-collapse: collapse; margin: 1em; }
th,td { border: 1px solid black; }
th { background: yellow; }
like image 857
Jason C Avatar asked Dec 03 '25 04:12

Jason C


1 Answers

there is no "legal" way.

but You can do

row.insertCell().outerHTML = `<th> ${'something'} </th>` ; 
like image 144
Mister Jojo Avatar answered Dec 05 '25 19:12

Mister Jojo