Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterate over table cells, re-using rowspan values

I have a simple HTML table, which uses rowspans in some random columns. An example might look like

 A | B |
---|---| C
 D |   |
---| E |---
 F |   | G

I'd like to iterate over the rows such that I see rows as A,B,C, D,E,C, then F,E,G.

I think I can probably cobble together something very convoluted using cell.index() to check for "missed" columns in later rows, but I'd like something a little more elegant...

like image 857
Coderer Avatar asked Feb 15 '23 18:02

Coderer


1 Answers

without jquery:

function tableToMatrix(table) {
  var M = [];
  for (var i = 0; i < table.rows.length; i++) {
    var tr = table.rows[i];
    M[i] = [];
    for (var j = 0, k = 0; j < M[0].length || k < tr.cells.length;) {
      var c = (M[i-1]||[])[j];
      // first check if there's a continuing cell above with rowSpan
      if (c && c.parentNode.rowIndex + c.rowSpan > i) {
        M[i].push(...Array.from({length: c.colSpan}, () => c))
        j += c.colSpan;
      } else if (tr.cells[k]) {
        var td = tr.cells[k++];
        M[i].push(...Array.from({length: td.colSpan}, () => td));
        j += td.colSpan;
      }
    }
  }
  return M;
}

var M = tableToMatrix(document.querySelector('table'));

console.table(M.map(r => r.map(c => c.innerText)));

var pre = document.createElement('pre');
pre.innerText = M.map(row => row.map(c => c.innerText).join('\t')).join('\n');
document.body.append(pre);
td {
  border: 1px solid rgba(0,0,0,.3);
}
<table>
  <tr>
    <td colspan=2>A</td>

    <td rowspan=2>B</td>
  </tr>
  <tr>
    <td>C</td>
    <td rowspan=3>D</td>
  </tr>
  <tr>
    <td rowspan=2>E</td>
    <td rowspan=4>F</td>
  </tr>
  <tr></tr>
  <tr>
    <td rowspan=2 colspan=2>G</td>
  </tr>
  <tr></tr>
  <tr>
    <td rowspan=3 colspan=3>H</td>
  </tr>
  <tr></tr>
  <tr></tr>
  <tr>
    <td colspan=3>I</td>
  </tr>
</table>
like image 160
caub Avatar answered Feb 27 '23 04:02

caub