Skip to content

Instantly share code, notes, and snippets.

@JDMCreator
Created May 16, 2017 21:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JDMCreator/840c2ad3de2506522a8748a36979ecf8 to your computer and use it in GitHub Desktop.
Save JDMCreator/840c2ad3de2506522a8748a36979ecf8 to your computer and use it in GitHub Desktop.
Fixed javascript "Table.rows" (including rowSpan and colSpan)
/****
This function create a matrix of cells from a table. It take care of merged cells (cells with "rowspan>1" or "colspan>1" attributes).
====| Syntax |====
@Array getMatrixOfCells(@TableElement table, [Optional @Boolean alwaysInterpretZeroRowSpan])
table : A <TABLE> HTML Element
alwaysInterpretZeroRowSpan : Optional (default : false). If set to true, "rowspan=0" attributes are always interpreted as if it was implemented in the browser (even if it's not)
The function returns an ARRAY of ARRAYs of OBJECTs. First-level array is the table and second-levels arrays are rows. Objects are cell.
Those objects may be real cells like this one :
{
x:x,
y:y,
cell : a <TD> or <TH> element
}
or "ghost" cell (if there is visually a cell there, but it's a cell with a "rowspan>1" or "colspan>1" attribute.
{
x:x,
y:y,
refCell : {
x:x,
y:y,
cell : a <TD> or <TH> element
}
}
*****/
function getMatrixOfCells(table, alwaysInterpretZeroRowSpan) {
var rg = [],
expandCells = [],
rows = table.rows;
for (var i = 0; i < rows.length; i++) {
rg.push([]);
}
for (var i = 0; i < rows.length; i++) {
var row = rows[i],
realCol = 0;
for (var j = 0; j < row.cells.length; j++) {
var cell = row.cells[j];
if (typeof rg[i][realCol] != "object" && rg[i][realCol] !== false) {
var rowSpan = alwaysInterpretZeroRowSpan ? parseInt(cell.getAttribute("rowSpan"), 10) : cell.rowSpan;
rowSpan = Math.floor(Math.abs(isNaN(rowSpan) ? 1 : rowSpan));
if (rowSpan === 0 && !alwaysInterpretZeroRowSpan && cell.ownerDocument && cell.ownerDocument.compatMode == "BackCompat") {
rowSpan = 1;
}
if (rowSpan == 1) {
if (!cell.colSpan || cell.colSpan < 2) {
rg[i][realCol] = {
cell: cell,
x: realCol,
y: i
}
} else {
var o = rg[i][realCol] = {
cell: cell,
x: realCol,
y: i
};
for (var k = 1; k < cell.colSpan; k++) {
rg[i][realCol + k] = {
refCell: o,
x: realCol + k,
y: i
};
}
}
} else {
var o = rg[i][realCol] = {
cell: cell,
x: realCol,
y: i
};
if (rowSpan === 0) {
expandCells.push(o);
}
for (var k = 0, kl = Math.max(rowSpan, 1); k < kl; k++) {
for (var l = 0; l < cell.colSpan; l++) {
// I hate four-level loops
if (!(k === 0 && l === 0)) {
o = rg[i + k][realCol + l] = {
refCell: o,
x: realCol + l,
y: i + k
}
if (rowSpan === 0) {
expandCells.push(o);
}
}
}
}
}
} else {
j--;
}
realCol++;
}
}
if (expandCells.length) {
for (var i = 0; i < expandCells.length; i++) {
var expandCell = expandCells[i],
x = expandCell.x,
y = expandCell.y;
for (var j = y + 1; j < rg.length; j++) {
rg[j].splice(x, 0, {
x: x,
y: j,
refCell: (expandCell.refCell || expandCell)
});
for (var h = x + 1; h < rg[j].length; h++) {
rg[j][h].x += 1;
}
}
}
}
return rg;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment