PDA

View Full Version : how to merge table cells.


ivarbug
10-22-2007, 07:27 AM
hello all, i'm coding my own wysiwyg editor and i have same problem as this guy here (http://www.codingforums.com/showthread.php?t=70411). i don't think that the solutions is that easy. this can't work for an example like this, when there already are set some random row and colspans.
cellIndex is just an array offset and next/previousSibling returns next/prev object from cells array?

<table border="1">
<tr><td></td><td rowspan="2"></td><td></td></tr>
<tr><td>merge</td><td>with this</td></tr></table>

Is there an easy way finding true adjacent cells so i don't have to scan whole table from top to find out if it's possible to merge thos 2 cells.

Fang
10-22-2007, 12:33 PM
afaik the only option is to scan the table from the top.

ivarbug
10-23-2007, 01:28 AM
okay, here's some ugly code for table editing that i wrote today. maybe someone will find it useful. didn't have time to test all cases and optimize the code, but it should be working more or less.
var cell = selobj;
var cellIndex;var cellrow;var cellcol;
var row = cell.parentNode;
var table = row.parentNode;
var re = /[0-9]$/;
if(selobj.align)align.value = selobj.align;else align.value = "";
if(selobj.vAlign)valign.value = selobj.vAlign;else valign.value = "";
var truetable;
var numcols;
function setuptruetable()
{
truetable = new Array(table.rows.length);
numcols = 0;
for(var i = 0;i < table.rows[0].cells.length;i++)
{
numcols += table.rows[0].cells[i].colSpan;
}
for(var i = 0;i < table.rows.length;i++)
{
truetable[i] = new Array(numcols);
}
for(var i = 0;i < table.rows.length;i++)
{
curcol = 0;
for(var j = 0;j < table.rows[i].cells.length;j++)
{
for(;curcol < numcols;curcol++)
{
if(!truetable[i][curcol])
{
break;
}
}
if(table.rows[i].cells[j] == cell)
{
cellIndex = i * numcols + curcol;
cellrow = i;
cellcol = curcol;
}
for(var k = 0;k < table.rows[i].cells[j].rowSpan;k++)
{
for(var l = 0;l < table.rows[i].cells[j].colSpan;l++)
{
truetable[i + k][curcol + l] = table.rows[i].cells[j];
}
}
}
}
}
setuptruetable();
function updatetable()
{
window.close();
}
function deletetable()
{
table.parentNode.parentNode.removeChild(table.parentNode);
window.close();
}
function mergeright()
{
if(cell.nextSibling && cell.nextSibling.rowSpan == cell.rowSpan && truetable[cellrow][cellcol + cell.colSpan] == cell.nextSibling)
{
cell.innerHTML += cell.nextSibling.innerHTML;
cell.colSpan += cell.nextSibling.colSpan;
row.removeChild(cell.nextSibling);
cleantable();
window.close();
}
}
function mergedown()
{
if(truetable[cellrow + cell.rowSpan][cellcol] && truetable[cellrow + cell.rowSpan][cellcol].colSpan == cell.colSpan)
{
cell.innerHTML += truetable[cellrow + cell.rowSpan][cellcol].innerHTML;
var tmp = truetable[cellrow + cell.rowSpan][cellcol].rowSpan;
table.rows[row.rowIndex + cell.rowSpan].removeChild(truetable[cellrow + cell.rowSpan][cellcol]);
cell.rowSpan += tmp;
cleantable();
window.close();
}
}
function splithoriz()
{
if(cell.colSpan > 1)
{
cell.colSpan--;
newcol = row.insertCell(cell.cellIndex + 1);
newcol.rowSpan = cell.rowSpan;
}
else
{
for(var i = 0;i < table.rows.length;)
{
if(truetable[i][cellcol] == cell)
{
i += cell.rowSpan;
continue;
}
truetable[i][cellcol].colSpan++;
i += truetable[i][cellcol].rowSpan;
}
newcol = row.insertCell(cell.cellIndex + 1);
newcol.rowSpan = cell.rowSpan;
}
window.close();
}
function splitvert()
{
if(cell.rowSpan > 1)
{
cell.rowSpan--;
for(var i = cellcol - 1;i >= 0;i--)
{
if(truetable[row.rowIndex + cell.rowSpan][i].parentNode == table.rows[row.rowIndex + cell.rowSpan])
{
break;
}
}
newcol = table.rows[row.rowIndex + cell.rowSpan].insertCell(truetable[row.rowIndex + cell.rowSpan][i].cellIndex + 1);
newcol.colSpan = cell.colSpan;
}
else
{
for(var i = 0;i < numcols;)
{
if(truetable[cellrow][i] == cell)
{
i += cell.colSpan;
continue;
}
truetable[cellrow][i].rowSpan++;
i += truetable[cellrow][i].colSpan;
}
newrow = table.insertRow(row.rowIndex + 1);
newcol = newrow.insertCell(-1);
newcol.colSpan = cell.colSpan;
}
window.close();
}
function updatecell()
{
cell.align = align.value;
cell.vAlign = valign.value;
window.close();
}
function deletecell()
{
if(cell.previousSibling && cell.previousSibling.rowSpan == cell.rowSpan && truetable[cellrow][cellcol - 1] == cell.previousSibling)
{
cell.previousSibling.colSpan += cell.colSpan;
row.removeChild(cell);
cleantable();
window.close();
}
else if(cell.nextSibling && cell.nextSibling.rowSpan == cell.rowSpan && truetable[cellrow][cellcol + cell.colSpan] == cell.nextSibling)
{
cell.nextSibling.colSpan += cell.colSpan;
row.removeChild(cell);
cleantable();
window.close();
}
else if(truetable[cellrow - 1][cellcol] && truetable[cellrow - 1][cellcol].colSpan == cell.colSpan)
{
truetable[cellrow - 1][cellcol].rowSpan += cell.rowSpan;
row.removeChild(cell);
cleantable();
window.close();
}
else if(truetable[cellrow + cell.rowSpan][cellcol] && truetable[cellrow + cell.rowSpan][cellcol].colSpan == cell.colSpan)
{
var tmp = truetable[cellrow + cell.rowSpan][cellcol].rowSpan;
table.rows[row.rowIndex + cell.rowSpan].removeChild(truetable[cellrow + cell.rowSpan][cellcol]);
cell.rowSpan += tmp;
cleantable();
window.close();
}
}
function insertcolumnbefore()
{
for(var i = 0;i < table.rows.length;i++)
{
if(truetable[i][cellcol].parentNode == table.rows[i])
{
var newcell = table.rows[i].insertCell(truetable[i][cellcol].cellIndex);
newcell.rowSpan = truetable[i][cellcol].rowSpan;
}
}
window.close();
}
function insertcolumnafter()
{
for(var i = 0;i < table.rows.length;i++)
{
if(truetable[i][cellcol].parentNode == table.rows[i])
{
var newcell = table.rows[i].insertCell(truetable[i][cellcol].cellIndex + 1);
newcell.rowSpan = truetable[i][cellcol].rowSpan;
}
}
window.close();
}
function updatecolumn()
{
window.close();
}
function deletecolumn()
{
for(var i = 0;i < table.rows.length;i++)
{
if(truetable[i][cellcol].colSpan > 1)
{
truetable[i][cellcol].colSpan--;
}
else
{
table.rows[i].deleteCell(truetable[i][cellcol].cellIndex);
}
}
cleantable();
window.close();
}
function insertrowbefore()
{
var newrow = table.insertRow(row.rowIndex);
for(var i = 0;i < numcols;)
{
if(truetable[newrow.rowIndex][i].parentNode != row)
{
truetable[newrow.rowIndex][i].rowSpan++;
}
i += truetable[newrow.rowIndex][i].colSpan;
}
for(var i = 0;i < row.cells.length;i++)
{
var newcell = newrow.insertCell(-1);
newcell.colSpan = row.cells[i].colSpan;
}
window.close();
}
function insertrowafter()
{
var newrow = table.insertRow(row.rowIndex + 1);
for(var i = 0;i < numcols;)
{
if(truetable[row.rowIndex][i].parentNode != row)
{
truetable[row.rowIndex][i].rowSpan++;
}
i += truetable[row.rowIndex][i].colSpan;
}
for(var i = 0;i < row.cells.length;i++)
{
var newcell = newrow.insertCell(-1);
newcell.colSpan = row.cells[i].colSpan;
}
window.close();
}
function updaterow()
{
window.close();
}
function deleterow()
{
for(var i = 0;i < numcols;)
{
if(truetable[row.rowIndex][i].parentNode != row)
{
truetable[row.rowIndex][i].rowSpan--;
}
else if(truetable[row.rowIndex][i].rowSpan > 1)
{
for(var j = i;j >= 0;j--)
{
if(truetable[row.rowIndex + 1][j].parentNode == row.nextSibling)
{
break;
}
}
newcell = row.nextSibling.insertCell(truetable[row.rowIndex + 1][j].cellIndex + 1);
newcell.cellSpan = truetable[row.rowIndex][i].colSpan;
newcell.rowSpan = truetable[row.rowIndex][i].rowSpan - 1;
}
i += truetable[row.rowIndex][i].colSpan;
}
table.deleteRow(row.rowIndex);
cleantable();
window.close();
}
function cleantable()
{
setuptruetable();
for(var i = 0;i < table.rows.length;i++)
{
if(!table.rows[i].cells.length)
{
for(var j = 0;j < numcols;j++)
{
if(truetable[i - 1][j].rowSpan > 1)
{
truetable[i - 1][j].rowSpan--;
}
}
table.deleteRow(table.rows[i].rowIndex);
}
}
if(!table.rows.length)
{
table.parentNode.parentNode.removeChild(table.parentNode);
}
}