Table.js 0.2

A small JavaScript library without dependencies to manipulate HTML tables
Download on Github

Documentation

Note : a HTMLTableCellElement is any <TD> or <TH> element.

Matrix

A matrix is the Array representation of a table (vs the DOM representation of a table). It is the core of this library. TableObject.matrix() returns an Array of Arrays of Objects. Each subarray represents a row and each object a cell. Cells that span more than a row or more than a col are represented as "Ghost object" that references the original cell. A normal Cell Object look like this :

{
    cell : a <TD> or <TH> element,
    x : column number,
    y: row number
}
A Ghost Cell Object look like this :

{
    refCell : a Cell Object,
    x : column number,
    y: row number
}
A
BCDEF
HIJK
LMNO
PQRS
Log matrix to console
Syntax: Matrix TableObject.matrix(Optional Boolean alwaysInterpretZeroRowSpan)
Returns the matrix representation of the table. If alwaysInterpretZeroRowSpan is set to true, the matrix will interpret rowspan="0" (which is part of the HTML5 standard) even if the browser doesn't support it. By default, this argument is set to false (rowspan="0" will only be interpreted if it is supported by the browser).

Accessing cells

Syntax: HTMLTableCellElement TableObject.cell(Number x, Number y, Optional Matrix matrix)
Returns the cell at absolute position [x,y]. Negative numbers start at the end (i.e. [-1,-1] is the last cell from the last row).
Syntax: HTMLTableCellElement TableObject.first()
Returns the first cell of the table.
Syntax: HTMLTableCellElement TableObject.last()
Returns the last cell of the table.
Syntax: HTMLTableCellElement TableObject.rel(Number x, Number y)
Returns the cell at relative position [x,y].
You can also access to the HTMLTableElement with the TableObject.element property.
Syntax: Boolean TableObject.isAChildCell(Misc cell)
Returns true if cell is a HTMLTableCellElement and a cell of the table.

Cell's position

A
BCDEF
HIJK
LMNO
PQRS
Position : (1,1)

var table = new Table(document.getElementById('table-position'));
function position(){
	var cell = table.element.querySelector(".selected");
	if(cell){
		var position = table.position(cell);
		document.getElementById('position-x').innerHTML = position.x;
		document.getElementById('position-y').innerHTML = position.y;
	}
}
Syntax: Object TableObject.position(HTMLTableCellElement cell, Optional Matrix matrix)
Returns the cell real position inside the table as an {x:x, y:y} Object. If matrix is not specified, a matrix of the table will be calculated via TableObject.matrix() which uses a lot of ressources. If you have a lot of cells' positions to calculate, you should cache the matrix.

Inserting and removing rows and columns

A
BCDEF
HIJK
LMNO
PQRS
Insert row before Insert row after Remove row
Insert column before Insert column after Remove column

var table = new Table(document.getElementById('table-row-col'));
function rowBefore(){
	var cell = table.element.querySelector(".selected");
	if(cell){
		var position = table.position(cell);
		table.insertRow(position.y, function(cell){
			cell.innerHTML = "0";
		})
	}
}
function rowAfter(){
	var cell = table.element.querySelector(".selected");
	if(cell){
		var position = table.position(cell);
		table.insertRow(position.y+cell.rowSpan, function(cell){
			cell.innerHTML = "0";
		})
	}
}
function removeRow(){
	var cell = table.element.querySelector(".selected");
	if(cell){
		var position = table.position(cell);
		table.removeRow(position.y)
	}
}
function colBefore(){
	var cell = table.element.querySelector(".selected");
	if(cell){
		var position = table.position(cell);
		table.insertCol(position.x, function(cell){
			cell.innerHTML = "0";
		})
	}
}
function colAfter(){
	var cell = table.element.querySelector(".selected");
	if(cell){
		var position = table.position(cell);
		table.insertCol(position.x+cell.colSpan, function(cell){
			cell.innerHTML = "0";
		})
	}
}
function removeCol(){
	var cell = table.element.querySelector(".selected");
	if(cell){
		var position = table.position(cell);
		table.removeCol(position.x)
	}
}
Syntax: TableObject.insertRow(Optional Number position, Optional function callback)
Insert a row at the position position (or at the end of the table, if not specified) and insert cells inside it like the row before it (or after it if it's the first row). If specified, the function callback is called for each cell inserted with the cell as the first argument.
Syntax: TableObject.insertCol(Optional Number position, Optional function callback)
Insert a column at the position position (or at the end of the table, if not specified) and insert cells inside it like the column before it (or after it if it's the first column). If specified, the function callback is called for each cell inserted with the cell as the first argument.
Syntax: TableObject.removeRow(Optional Number position)
Remove the row located at position position and move each cell with a rowspan attribute other than 1 to the next row if possible. Negative position start at the end (i.e. -1 is the last row). Default value for position is -1.
Syntax: TableObject.removeCol(Optional Number position)
Remove each cell located at position position for each row. Negative position start at the end (i.e. -1 is the last cell from each row). Default value for position is -1.

Merging and splitting cells

12345
12345
12345
12345
12345
Merge Split Group

var table = new Table(document.getElementById('table-merge-split'));
function merge(){
	var cells = table.element.querySelectorAll(".selected");
	table.merge(cells, function(colspan, rowspan, kept, removed){
		var content = kept.innerHTML;
		for(var i=0;i<removed.length;i++){
			content += " " + removed[i].innerHTML;
		}
		kept.innerHTML = content;
	})
}

var table = new Table(document.getElementById('table-merge-split'));
function split(){
	var cells = table.element.querySelectorAll(".selected");
	table.split(cells, function(newcell){
		newcell.innerHTML = "New";
		newcell.classList.add("selected");
	})
}
Syntax: TableObject.merge(NodeList||Array cells, Optional Function callback)
Merge all HTMLTableCellElement in cells. Whenever cells are about to be merged, callback is called with four arguments : the first is the future value of the colspan attribute, the second is the future value of the rowspan attribute, the third is the cell that will be kept and the fourth is an Array of cells that will be removed.
Syntax: TableObject.mergeHorizontal(NodeList||Array cells, Optional Function callback)
Merge horizontally all HTMLTableCellElement in cells. Whenever cells are about to be merged, callback is called with four arguments : the first is the future value of the colspan attribute, the second is the future value of the rowspan attribute, the third is the cell that will be kept and the fourth is an Array of cells that will be removed.
Syntax: TableObject.mergeVertical(NodeList||Array cells, Optional Function callback)
Merge vertically all HTMLTableCellElement in cells. Whenever cells are about to be merged, callback is called with four arguments : the first is the future value of the colspan attribute, the second is the future value of the rowspan attribute, the third is the cell that will be kept and the fourth is an Array of cells that will be removed.
Syntax: TableObject.split(HTMLTableCellElement||Array||NodeList cells, Optional Function callback)
Split each cell specified in the first argument and call callback, if specified, for each cell created with the cell as the first argument.

You should normalize your table after merging cells.

Normalizing a table

Normalizing a table means four things :
  1. Adjusting the rowspan value of each cell to its minimal value;
  2. Adjusting the colspan value of each cell to its minimal value;
  3. Removing empty <TR> elements;
  4. If there are missing cells in a row, expanding the colspan value of the last cell of this row.
Syntax: Boolean TableObject.normalize()
The function returns true if the table was modified.
1234
123
12345
1234
12345
Normalize

var table = new Table(document.getElementById('table-normalize'));
function normalizeTable(){
	table.normalize();
}