Newer
Older

Tim Repke
committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
(function( $ ) {
'use strict';
$.fn.tableToJSON = function(opts) {
// Set options
var defaults = {
ignoreColumns: [],
onlyColumns: null,
ignoreHiddenRows: true,
headings: null,
allowHTML: false
};
opts = $.extend(defaults, opts);
var notNull = function(value) {
return value !== undefined && value !== null;
};
var ignoredColumn = function(index) {
if( notNull(opts.onlyColumns) ) {
return $.inArray(index, opts.onlyColumns) === -1;
}
return $.inArray(index, opts.ignoreColumns) !== -1;
};
var arraysToHash = function(keys, values) {
var result = {}, index = 0;
$.each(values, function(i, value) {
// when ignoring columns, the header option still starts
// with the first defined column
if ( index < keys.length && notNull(value) ) {
result[ keys[index] ] = value;
index++;
}
});
return result;
};
var cellValues = function(cellIndex, cell) {
var value, result;
var override = $(cell).data('override');
if ( opts.allowHTML ) {
value = $.trim($(cell).html());
} else {
value = $.trim($(cell).text());
}
result = notNull(override) ? override : value;
return result;
};
var rowValues = function(row) {
var result = [];
$(row).children('td,th').each(function(cellIndex, cell) {
result.push( cellValues(cellIndex, cell) );
});
return result;
};
var getHeadings = function(table) {
var firstRow = table.find('tr:first').first();
return notNull(opts.headings) ? opts.headings : rowValues(firstRow);
};
var construct = function(table, headings) {
var i, j, len, len2, txt, $row, $cell,
tmpArray = [], cellIndex = 0, result = [];
table.children('tbody,*').children('tr').each(function(rowIndex, row) {
if( rowIndex > 0 || notNull(opts.headings) ) {
$row = $(row);
if( $row.is(':visible') || !opts.ignoreHiddenRows ) {
if (!tmpArray[rowIndex]) {
tmpArray[rowIndex] = [];
}
cellIndex = 0;
$row.children().each(function(){
$cell = $(this);
// process rowspans
if ($cell.filter('[rowspan]').length) {
len = parseInt( $cell.attr('rowspan'), 10) - 1;
txt = cellValues(cellIndex, $cell, []);
for (i = 1; i <= len; i++) {
if (!tmpArray[rowIndex + i]) { tmpArray[rowIndex + i] = []; }
tmpArray[rowIndex + i][cellIndex] = txt;
}
}
// process colspans
if ($cell.filter('[colspan]').length) {
len = parseInt( $cell.attr('colspan'), 10) - 1;
txt = cellValues(cellIndex, $cell, []);
for (i = 1; i <= len; i++) {
// cell has both col and row spans
if ($cell.filter('[rowspan]').length) {
len2 = parseInt( $cell.attr('rowspan'), 10);
for (j = 0; j < len2; j++) {
tmpArray[rowIndex + j][cellIndex + i] = txt;
}
} else {
tmpArray[rowIndex][cellIndex + i] = txt;
}
}
}
// skip column if already defined
while (tmpArray[rowIndex][cellIndex]) { cellIndex++; }
txt = tmpArray[rowIndex][cellIndex] || cellValues(cellIndex, $cell, []);
if (notNull(txt)) {
tmpArray[rowIndex][cellIndex] = txt;
}
cellIndex++;
});
}
}
});
$.each(tmpArray, function( i, row ){
if (notNull(row)) {
// remove ignoredColumns / add onlyColumns
var newRow = notNull(opts.onlyColumns) || opts.ignoreColumns.length ?
$.grep(row, function(v, index){ return !ignoredColumn(index); }) : row,
// remove ignoredColumns / add onlyColumns if headings is not defined
newHeadings = notNull(opts.headings) ? headings :
$.grep(headings, function(v, index){ return !ignoredColumn(index); });
txt = arraysToHash(newHeadings, newRow);
result[result.length] = txt;
}
});
return result;
};
// Run
var headings = getHeadings(this);
return construct(this, headings);
};
})( jQuery );