[/] [plugins/] [jquery.tableHelper.js] - Rev 2
Compare with Previous |
Blame |
View Log
/****************************************************************
* jquery.tableHelper.js *
* *
* by: Dan VerWeire *
* email: [email protected] *
* *
* sponsored by: Pavilion Gift Company *
* www.paviliongift.com *
* *
* This library is free software; you can redistribute *
* it and/or modify it under the terms of the GNU *
* Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the *
* License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will *
* be useful, but WITHOUT ANY WARRANTY; without even the *
* implied warranty of MERCHANTABILITY or FITNESS FOR A *
* PARTICULAR PURPOSE. See the GNU Lesser General Public *
* License for more details. *
* *
* You should have received a copy of the GNU Lesser *
* General Public License along with this library; *
* Inc., 59 Temple Place, Suite 330, Boston, *
* MA 02111-1307 USA *
****************************************************************/
(function () {
var alphaColLookup
= {}
var colIndex
= 0;
for (var x
= 97; x
<= 122; x
++) {
alphaColLookup
[String.
fromCharCode(x
)] = colIndex
++;
}
for (var x
= 97; x
<= 122; x
++) {
for (var y
= 97; y
<= 122; y
++) {
alphaColLookup
[String.
fromCharCode(x
) + String.
fromCharCode(y
)] = colIndex
++;
}
}
//helper function to quickly determine if an element is a table
isTable
= function (el
) {
return (el.
nodeName == 'TABLE') ? true : false;
}
//helper function to quickly determine if an element is a tbody
isTbody
= function (el
) {
return (el.
nodeName == 'TBODY') ? true : false;
}
//helper function to quickly determine if an element is a tfoot
isTfoot
= function (el
) {
return (el.
nodeName == 'TFOOT') ? true : false;
}
//helper function to quickly determine if an element is a thead
isThead
= function (el
) {
return (el.
nodeName == 'THEAD') ? true : false;
}
//helper function to quickly determine if an element is a table cell
isCell
= function (el
) {
return (el.
nodeName == 'TD') ? true : false;
}
//helper function to quickly determine if an element is a table row
isRow
= function (el
) {
return (el.
nodeName == 'TR') ? true : false;
}
getTable
= function (el
,jq
) {
var tbl
;
if (isTable
(el
) || isThead
(el
) || isTbody
(el
) || isTfoot
(el
)) {
jq
= jq.
not(el
);
tbl
= el
;
}
else if (isCell
(el
)) {
tbl
= el.
parentNode.
parentNode;
}
else if (isRow
(el
)) {
tbl
= el.
parentNode;
}
return { table
: tbl
, jq
: jq
}
}
getVirtTable
= function (tbl
) {
//tables which contain cells that have a rowSpan or cellSpan make the indices not friendly for
//any type of coordinate system. What this section does is loop through the actual table, building
//a map of that table where a 'merged cell' has a reference at every coordinate which it takes up.
//i tried other methods, but this is the one that ended up working. not sure if this is the most efficient.
//
//this method helps with including merged cells in an overlapping range
var virtTable
= {};
if (tbl.
rowLength) {
rowLength
= tbl.
rowLength+1;
}
else {
rowLength
= tbl.
rows.
length
}
if (tbl.
cellLength) {
colLength
= tbl.
cellLength+1;
}
else {
colLength
= tbl.
rows[0].
cells.
length;
}
for (var y
= 0; y
< rowLength
; y
++) {
var row
= tbl.
rows[y
];
for (var x
= 0; x
< colLength
; x
++) {
var cell
= row.
cells[x
];
if (cell
) {
//this loop is for setting the references of a cell that might have a rowSpan or cellSpan
for (var a
= 0; a
< cell.
rowSpan; a
++) {
for (var b
= 0; b
< cell.
colSpan; b
++) {
if (!virtTable
[y
+ a
]) virtTable
[y
+ a
] = {};
if (!virtTable
[y
+ a
][x
+ b
]) {
virtTable
[y
+ a
][x
+ b
] = cell
;
cell.
x = x
+ b
;
cell.
y = y
+ a
;
}
else {
var c
= 0;
while (virtTable
[y
+ a
][x
+ b
+ c
]) {
c
++;
}
virtTable
[y
+ a
][x
+ b
+ c
] = cell
;
cell.
x = x
+ b
+ c
;
cell.
y = y
+ a
;
}
}
}
}
}
}
return virtTable
;
}
//add the cell method to the jQuery object
//this method adds the cell at row,col in any tables in the current
//selection to the selection
//
//it will remove the table from the selection
jQuery.
fn.
cell = function (col
,row
) {
var jq
= this;
this.
each(function(i
,el
) {
var obj
= getTable
(this,jq
);
jq
= obj.
jq;
tbl
= obj.
table;
var virtTable
= getVirtTable
(tbl
);
if (virtTable
&& virtTable
[row
] && virtTable
[row
][col
]) {
var cell
= virtTable
[row
][col
];
jq
= jq.
add(cell
);
}
});
return jq
;
};
jQuery.
fn.
row = function (row
) {
var jq
= this;
jq.
each(function (i
,el
) {
var obj
= getTable
(this,jq
);
jq
= obj.
jq;
tbl
= obj.
table;
var tmp
= Array
();
var rw
= tbl.
rows.
item(row
);
if (rw
) {
for (var x
= 0; x
< rw.
cells.
length; x
++) {
var cell
= rw.
cells.
item(x
);
tmp.
push(cell
);
}
jq
= jq.
add(tmp
);
}
});
return jq
;
}
jQuery.
fn.
alternate = function(start
, interval
) {
var jq
= this;
jq.
each(function (i
,el
) {
var obj
= getTable
(this,jq
);
jq
= obj.
jq;
tbl
= obj.
table;
var tmp
= Array
();
for (var x
= start
; x
< tbl.
rows.
length; x
+= interval
) {
var rw
= tbl.
rows.
item(x
);
for (var y
= 0; y
< rw.
cells.
length; y
++) {
var cell
= rw.
cells.
item(y
);
tmp.
push(cell
);
}
}
jq
= jq.
add(tmp
);
});
return jq
;
}
jQuery.
fn.
even = function () {
return this.
alternate(0,2);
}
jQuery.
fn.
odd = function () {
return this.
alternate(1,2);
}
jQuery.
fn.
all = function () {
return this.
alternate(0,1);
}
jQuery.
fn.
col = function (col
) {
var jq
= this;
jq.
each(function (i
,el
) {
var obj
= getTable
(this,jq
);
jq
= obj.
jq;
tbl
= obj.
table;
var tmp
= Array
();
for (var y
= 0; y
< tbl.
rows.
length; y
++) {
var cell
= tbl.
rows.
item(y
).
cells.
item(col
)
tmp.
push(cell
);
}
jq
= jq.
add(tmp
);
});
return jq
;
}
jQuery.
fn.
tableEnd = function () {
var jq
= this;
while (jq.
length > 0 ) {
// jq.each(function (i, el) {
jq
= jq.
end();
// });
}
jq
= jq.
end();
return jq
;
}
//resize the table, only grows the table at the moment
jQuery.
fn.
resize = function (cols
,rows
) {
var jq
= this;
//fix off by one issue
cols
--;
rows
--;
result
= this.
each(function(i
,el
) {
this.
cellLength = cols
;
this.
rowLength = rows
;
for (var y
= this.
rows.
length; y
< rows
+ 1; y
++) {
var rw
= this.
insertRow(-1);
}
//now for each row, check all the cells
for (var y
= 0; y
< this.
rows.
length; y
++) {
var rw
= this.
rows.
item(y
);
for (var x
= rw.
cells.
length; x
< cols
+ 1; x
++) {
var td
= rw.
insertCell(-1);
}
}
});
return jq
;
}
jQuery.
fn.
range = function (stRange
) { //yes i called this stRange for fun reasons.
var jq
= this;
if (stRange.
indexOf(':') >= 0) {
var tokens
= stRange.
split(':');
var range
= []
for (var x
= 0; x
< tokens.
length; x
++) {
var token
= tokens
[x
];
var col
= alphaColLookup
[/[a
-zA
-Z
]{1,2}/.
exec(token
)];
var row
= (/[0-9]{1,}/.
exec(token
)) - 1;
range.
push({row
: row
, col
: col
});
}
if (range.
length == 2) {
//we have a start coord and a stop coord
jq.
each(function(i
,el
) {
var cells
= [];
var obj
= getTable
(this,jq
);
jq
= obj.
jq;
tbl
= obj.
table;
var virtTable
= getVirtTable
(tbl
);
//now grab the cells in the range from the virtual table.
for (var y
= range
[0].
row ; y
<= range
[1].
row ; y
++) {
for (var x
= range
[0].
col; x
<= range
[1].
col; x
++) {
try {
if (virtTable
[y
][x
]) {
cells.
push(virtTable
[y
][x
]);
}
}
catch (e
) { alert('.range error: ' + e
+ ': ' + y
+ ', ' + x
) };
}
}
//add the cells we collected to the jquery object
jq
= jq.
add(cells
);
});
}
}
return jq
;
}
jQuery.
fn.
merge = function (copyContents
) {
var jq
= this;
var contents
= '';
var tl
= {}, br
= {};
var cells
= [];
jq.
each(function (i
, el
) {
if (isCell
(this)) cells.
push(this);
})
//find the top left most cell
if (cells.
length > 0) {
var tl
= {row
: cells
[0].
y, col
: cells
[0].
x, cell
: cells
[0]};
var br
= {row
: cells
[0].
y, col
: cells
[0].
x, cell
: cells
[0]};
for (var x
= 0; x
< cells.
length; x
++){
var cell
= cells
[x
];
var row
= cell.
y;
var col
= cell.
x;
if (row
< tl.
row || col
< tl.
col ) tl
= {row
: row
, col
: col
, cell
: cell
};
if (row
> br.
row || col
> br.
col ) br
= {row
: row
, col
: col
, cell
: cell
};
}
for (var x
= 0; x
< cells.
length; x
++){
var cell
= cells
[x
];
if (cell
!= tl.
cell) {
if (copyContents
) contents
+= cell.
innerHTML;
cell.
parentNode.
removeChild(cell
);
}
}
tl.
cell.
colSpan = br.
col - tl.
col + 1;
tl.
cell.
rowSpan = br.
row - tl.
row + 1;
if (copyContents
) tl.
cell.
innerHTML += contents
;
}
//remove all the td's and then just add back in the topleft cell
jq
= jq.
not('td').
add(tl.
cell);
return jq
;
}
jQuery.
fn.
unMerge = function () {
var jq
= this;
var contents
= '';
var cells
= [];
jq.
each(function (i
, el
) {
var done
= false;
if (isCell
(this)) {
var tbl
= getTable
(this).
table;
var virtTable
= getVirtTable
(tbl
);
//loop through the virtual table to find the top leftest reference to this merged cell.
for ( var y
in virtTable
) {
var row
= virtTable
[y
];
for (var x
in row
) {
var cell
= row
[x
];
if (cell
== this) {
rowSpan
= this.
rowSpan;
colSpan
= this.
colSpan;
//
//loop through the size of this cell and insert new cells
for ( var a
= 0; a
< rowSpan
; a
++ ) {
for ( var b
= 0 ; b
< colSpan
; b
++ ) {
//alert(parseInt(x) + colSpan);
//alert((parseInt(y) + a) + ' ' + y + ' ' + a)// + virtTable[String(y + a)][x])
var cell
= jQuery
('<td />').
insertBefore(virtTable
[(parseInt
(y
) + a
)][parseInt
(x
) + colSpan
]).
get(0)
cells.
push(cell
);
}
}
$
(this).
remove();
done
= true;
break;
}
}
if (done
) break;
}
}
})
return jq.
add(cells
);
}
})();
Compare with Previous |
Blame |
View Log