Subversion Repositories jquery

[/] [plugins/] [jquery.tableHelper.js] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 -
 /****************************************************************
2
  *  jquery.tableHelper.js                                       *
3
  *                                                              *
4
  *  by: Dan VerWeire                                            *
5
  *  email: [email protected]                                  *
6
  *                                                              *
7
  *  sponsored by: Pavilion Gift Company                         *
8
  *  www.paviliongift.com                                        *
9
  *                                                              *
10
  *  This library is free software; you can redistribute         *
11
  *  it and/or modify it under the terms of the GNU              *
12
  *  Lesser General Public License as published by the           *
13
  *  Free Software Foundation; either version 2.1 of the         *
14
  *  License, or (at your option) any later version.             *
15
  *                                                              *
16
  *  This library is distributed in the hope that it will        *
17
  *  be useful, but WITHOUT ANY WARRANTY; without even the       *
18
  *  implied warranty of MERCHANTABILITY or FITNESS FOR A        *
19
  *  PARTICULAR PURPOSE. See the GNU Lesser General Public       *
20
  *  License for more details.                                   *
21
  *                                                              *
22
  *  You should have received a copy of the GNU Lesser           *
23
  *  General Public License along with this library;             *
24
  *  Inc., 59 Temple Place, Suite 330, Boston,                   *
25
  *  MA 02111-1307 USA                                           *
26
  ****************************************************************/
27
 
28
(function () {
29
        var alphaColLookup = {}
30
        var colIndex = 0;
31
 
32
        for (var x = 97; x <= 122; x++) {
33
            alphaColLookup[String.fromCharCode(x)] = colIndex++;         
34
        }
35
 
36
        for (var x = 97; x <= 122; x++) {
37
            for (var y = 97; y <= 122; y++) {
38
                alphaColLookup[String.fromCharCode(x) + String.fromCharCode(y)] = colIndex++;    
39
            }
40
        }
41
 
42
        //helper function to quickly determine if an element is a table
43
        isTable = function (el) {
44
                return (el.nodeName == 'TABLE') ? true : false;
45
        }
46
 
47
        //helper function to quickly determine if an element is a tbody
48
        isTbody = function (el) {
49
                return (el.nodeName == 'TBODY') ? true : false;
50
        }
51
 
52
        //helper function to quickly determine if an element is a tfoot
53
        isTfoot = function (el) {
54
                return (el.nodeName == 'TFOOT') ? true : false;
55
        }
56
 
57
        //helper function to quickly determine if an element is a thead
58
        isThead = function (el) {
59
                return (el.nodeName == 'THEAD') ? true : false;
60
        }
61
 
62
        //helper function to quickly determine if an element is a table cell
63
        isCell = function (el) {
64
                return (el.nodeName == 'TD') ? true : false;
65
        }
66
 
67
        //helper function to quickly determine if an element is a table row
68
        isRow = function (el) {
69
                return (el.nodeName == 'TR') ? true : false;
70
        }
71
 
72
        getTable = function (el,jq) {
73
                var tbl;
74
 
75
                if (isTable(el) || isThead(el) || isTbody(el) || isTfoot(el)) {
76
                        jq = jq.not(el);
77
                        tbl = el;
78
                }
79
                else if (isCell(el)) {
80
                        tbl = el.parentNode.parentNode;
81
                }
82
                else if (isRow(el)) {
83
                        tbl = el.parentNode;
84
                }
85
 
86
                return { table : tbl, jq : jq }
87
        }
88
 
89
        getVirtTable = function (tbl) {
90
                //tables which contain cells that have a rowSpan or cellSpan make the indices not friendly for
91
                //any type of coordinate system. What this section does is loop through the actual table, building
92
                //a map of that table where a 'merged cell' has a reference at every coordinate which it takes up.
93
                //i tried other methods, but this is the one that ended up working. not sure if this is the most efficient.
94
                //
95
                //this method helps with including merged cells in an overlapping range
96
 
97
                var virtTable  = {};
98
 
99
                if (tbl.rowLength) {
100
                        rowLength = tbl.rowLength+1;
101
                }
102
                else {
103
                        rowLength = tbl.rows.length
104
                }
105
 
106
                if (tbl.cellLength) {
107
                        colLength = tbl.cellLength+1;
108
                }
109
                else {
110
                        colLength = tbl.rows[0].cells.length;
111
                }
112
 
113
                for (var y = 0; y < rowLength; y++) {
114
                        var row = tbl.rows[y];
115
                        for (var x = 0; x < colLength; x++) {
116
                                var cell = row.cells[x];
117
 
118
                                if (cell) {
119
                                        //this loop is for setting the references of a cell that might have a rowSpan or cellSpan
120
                                        for (var a = 0; a < cell.rowSpan; a++) {
121
                                                for (var b = 0; b < cell.colSpan; b++) {
122
                                                        if (!virtTable[y + a]) virtTable[y + a] = {};
123
 
124
                                                        if (!virtTable[y + a][x + b]) {
125
                                                                virtTable[y + a][x + b] = cell;
126
                                                                cell.x = x + b;
127
                                                                cell.y = y + a;
128
                                                        }
129
                                                        else {
130
                                                                var c = 0;
131
                                                                while (virtTable[y + a][x + b + c]) {
132
                                                                        c++;
133
                                                                }
134
                                                                virtTable[y + a][x + b + c] = cell;
135
                                                                cell.x = x + b + c;
136
                                                                cell.y = y + a;
137
                                                        }
138
                                                }
139
                                        }
140
                                }
141
                        }
142
                }
143
 
144
                return virtTable;
145
        }
146
 
147
        //add the cell method to the jQuery object
148
        //this method adds the cell at row,col in any tables in the current
149
        //selection to the selection
150
        //
151
        //it will remove the table from the selection
152
        jQuery.fn.cell = function (col,row) {
153
                var jq = this;
154
 
155
                this.each(function(i,el) {
156
                        var obj = getTable(this,jq);
157
                        jq = obj.jq;
158
                        tbl = obj.table;
159
 
160
                        var virtTable = getVirtTable(tbl);
161
 
162
                        if (virtTable && virtTable[row] && virtTable[row][col]) {
163
                                var cell = virtTable[row][col];
164
                                jq = jq.add(cell);
165
                        }
166
                });
167
 
168
                return jq;
169
        };
170
 
171
        jQuery.fn.row = function (row) {
172
                var jq = this;
173
 
174
                jq.each(function (i,el) {
175
                        var obj = getTable(this,jq);
176
                        jq = obj.jq;
177
                        tbl = obj.table;
178
 
179
                        var tmp = Array();
180
                        var rw = tbl.rows.item(row);
181
 
182
                        if (rw) {
183
                                for (var x = 0; x < rw.cells.length; x++) {
184
                                        var cell = rw.cells.item(x);
185
                                        tmp.push(cell);
186
                                }
187
 
188
                                jq = jq.add(tmp);
189
                        }
190
                });
191
 
192
                return jq;
193
        }
194
 
195
        jQuery.fn.alternate = function(start, interval) {
196
                var jq = this;
197
 
198
                jq.each(function (i,el) {
199
                        var obj = getTable(this,jq);
200
                        jq = obj.jq;
201
                        tbl = obj.table;
202
 
203
                        var tmp = Array();
204
 
205
                        for (var x = start; x < tbl.rows.length; x += interval) {
206
                                var rw = tbl.rows.item(x);
207
 
208
                                for (var y = 0; y < rw.cells.length; y++) {
209
                                        var cell = rw.cells.item(y);
210
                                        tmp.push(cell);
211
                                }
212
                        }
213
 
214
                        jq = jq.add(tmp);
215
                });
216
 
217
                return jq;
218
        }
219
 
220
        jQuery.fn.even = function () {
221
                return this.alternate(0,2);
222
        }
223
 
224
        jQuery.fn.odd = function () {
225
                return this.alternate(1,2);
226
        }
227
 
228
        jQuery.fn.all = function () {
229
                return this.alternate(0,1);
230
        }
231
 
232
 
233
        jQuery.fn.col = function (col) {
234
                var jq = this;
235
 
236
                jq.each(function (i,el) {
237
                        var obj = getTable(this,jq);
238
                        jq = obj.jq;
239
                        tbl = obj.table;
240
 
241
                        var tmp = Array();
242
 
243
                        for (var y = 0; y < tbl.rows.length; y++) {
244
                                var cell = tbl.rows.item(y).cells.item(col)
245
                                tmp.push(cell);
246
                        }
247
 
248
                        jq = jq.add(tmp);
249
                });
250
 
251
                return jq;
252
        }
253
 
254
        jQuery.fn.tableEnd  = function () {
255
                var jq = this;
256
 
257
                while (jq.length > 0 ) {
258
                //      jq.each(function (i, el) {
259
                                jq = jq.end();
260
                //      });
261
                }
262
                jq = jq.end();
263
 
264
                return jq;
265
        }
266
 
267
        //resize the table, only grows the table at the moment
268
        jQuery.fn.resize = function (cols,rows) {
269
                var jq = this;
270
                //fix off by one issue
271
                cols--;
272
                rows--;
273
                result = this.each(function(i,el) {
274
                        this.cellLength = cols;
275
                        this.rowLength = rows;
276
 
277
                        for (var y = this.rows.length; y < rows + 1; y++) {
278
                                var rw = this.insertRow(-1);
279
                        }
280
 
281
                        //now for each row, check all the cells
282
                        for (var y = 0; y < this.rows.length; y++) {
283
                                var rw = this.rows.item(y);
284
 
285
                                for (var x = rw.cells.length; x < cols + 1; x ++) {
286
                                        var td = rw.insertCell(-1);
287
                                }
288
                        }
289
                });
290
 
291
                return jq;
292
        }
293
 
294
        jQuery.fn.range = function (stRange) { //yes i called this stRange for fun reasons.
295
                var jq = this;
296
 
297
                if (stRange.indexOf(':') >= 0) {
298
                        var tokens = stRange.split(':');
299
                        var range = []
300
 
301
                        for (var x = 0; x < tokens.length; x++) {
302
                                var token = tokens[x];
303
                                var col = alphaColLookup[/[a-zA-Z]{1,2}/.exec(token)];
304
                                var row = (/[0-9]{1,}/.exec(token)) - 1;
305
 
306
                                range.push({row : row, col : col});
307
                        }
308
 
309
                        if (range.length == 2) {
310
                                //we have a start coord and a stop coord
311
                                jq.each(function(i,el) {
312
                                        var cells = [];
313
                                        var obj = getTable(this,jq);
314
 
315
                                        jq = obj.jq;
316
                                        tbl = obj.table;
317
 
318
                                        var virtTable = getVirtTable(tbl);
319
 
320
                                        //now grab the cells in the range from the virtual table.
321
                                        for (var y = range[0].row ; y <= range[1].row ; y ++) {
322
                                                for (var x = range[0].col; x <= range[1].col; x++) {
323
                                                        try {
324
                                                                if (virtTable[y][x]) {
325
                                                                        cells.push(virtTable[y][x]);
326
                                                                }
327
                                                        }
328
                                                        catch (e) { alert('.range error: '  + e + ': ' + y + ', ' + x) };
329
                                                }
330
                                        }
331
 
332
                                        //add the cells we collected to the jquery object
333
                                        jq = jq.add(cells);
334
                                });
335
                        }
336
                }
337
                return jq;
338
        }
339
 
340
        jQuery.fn.merge = function (copyContents) {
341
                var jq = this;
342
                var contents = '';
343
                var tl = {}, br = {};
344
 
345
                var cells = [];
346
 
347
                jq.each(function (i, el) {
348
                        if (isCell(this)) cells.push(this);
349
                })
350
 
351
                //find the top left most cell
352
                if (cells.length > 0) {
353
 
354
                        var tl = {row : cells[0].y, col : cells[0].x, cell : cells[0]};
355
                        var br = {row : cells[0].y, col : cells[0].x, cell : cells[0]};
356
 
357
                        for (var x = 0; x < cells.length; x ++){
358
                                var cell = cells[x];
359
 
360
                                var row = cell.y;
361
                                var col = cell.x;
362
 
363
                                if (row < tl.row || col < tl.col ) tl = {row : row, col : col, cell : cell};
364
                                if (row > br.row || col > br.col ) br = {row : row, col : col, cell : cell};
365
                        }
366
 
367
                        for (var x = 0; x < cells.length; x ++){
368
                                var cell = cells[x];
369
 
370
                                if (cell != tl.cell) {
371
                                        if (copyContents) contents += cell.innerHTML;
372
                                        cell.parentNode.removeChild(cell);
373
                                }
374
                        }
375
 
376
                        tl.cell.colSpan = br.col - tl.col + 1;
377
                        tl.cell.rowSpan = br.row - tl.row + 1;
378
 
379
                        if (copyContents) tl.cell.innerHTML += contents;
380
                }
381
 
382
                //remove all the td's and then just add back in the topleft cell
383
                jq = jq.not('td').add(tl.cell);
384
 
385
                return jq;
386
        }
387
 
388
        jQuery.fn.unMerge = function () {
389
                var jq = this;
390
                var contents = '';
391
 
392
                var cells = [];
393
 
394
                jq.each(function (i, el) {
395
                        var done = false;
396
 
397
                        if (isCell(this)) {
398
                                var tbl = getTable(this).table;
399
                                var virtTable = getVirtTable(tbl);
400
 
401
                                //loop through the virtual table to find the top leftest reference to this merged cell.
402
                                for ( var y in virtTable ) {
403
                                        var row = virtTable[y];
404
 
405
                                        for (var x in row) {
406
                                                var cell = row[x];
407
 
408
                                                if (cell == this) {
409
                                                        rowSpan = this.rowSpan;
410
                                                        colSpan = this.colSpan;
411
                                                        //
412
                                                        //loop through the size of this cell and insert new cells
413
                                                        for ( var a = 0; a < rowSpan; a++ ) {
414
                                                                for ( var b = 0 ; b < colSpan; b++ ) {
415
                                                                        //alert(parseInt(x) + colSpan);
416
                                                                        //alert((parseInt(y) + a) + ' ' + y + ' ' + a)// + virtTable[String(y + a)][x])
417
                                                                        var cell = jQuery('<td />').insertBefore(virtTable[(parseInt(y) + a)][parseInt(x) + colSpan]).get(0)
418
                                                                        cells.push(cell);
419
                                                                }
420
                                                        }
421
                                                        $(this).remove();
422
                                                        done = true;
423
                                                        break;
424
                                                }
425
                                        }
426
                                        if (done) break;
427
                                }
428
                        }
429
                })
430
                return jq.add(cells);
431
        }
432
 
433
})();