foo_table-rails 0.5.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/foo_table-rails/version.rb +1 -1
- data/vendor/assets/javascripts/footable.core.js +353 -159
- data/vendor/assets/javascripts/footable.core.min.js +14 -0
- data/vendor/assets/javascripts/footable.filter.js +145 -92
- data/vendor/assets/javascripts/footable.filter.min.js +14 -0
- data/vendor/assets/javascripts/footable.paginate.js +90 -35
- data/vendor/assets/javascripts/footable.paginate.min.js +1 -0
- data/vendor/assets/javascripts/footable.sort.js +171 -146
- data/vendor/assets/javascripts/footable.sort.min.js +1 -0
- data/vendor/assets/stylesheets/fonts/footable.eot +0 -0
- data/vendor/assets/stylesheets/fonts/footable.svg +78 -0
- data/vendor/assets/stylesheets/fonts/footable.ttf +0 -0
- data/vendor/assets/stylesheets/fonts/footable.woff +0 -0
- data/vendor/assets/stylesheets/footable.all.css +407 -0
- data/vendor/assets/stylesheets/footable.all.min.css +3 -0
- data/vendor/assets/stylesheets/footable.core.css +147 -96
- data/vendor/assets/stylesheets/footable.core.min.css +1 -0
- data/vendor/assets/stylesheets/footable.metro.css +132 -0
- data/vendor/assets/stylesheets/footable.metro.min.css +1 -0
- data/vendor/assets/stylesheets/footable.standalone.css +106 -0
- data/vendor/assets/stylesheets/footable.standalone.min.css +1 -0
- metadata +16 -7
- data/vendor/assets/javascripts/footable.template.js +0 -44
- data/vendor/assets/stylesheets/footable.paginate.css +0 -31
- data/vendor/assets/stylesheets/footable.sort.css +0 -24
- data/vendor/assets/stylesheets/footable.theme.bootstrap-responsive.css +0 -1109
- data/vendor/assets/stylesheets/footable.theme.bootstrap-tab.js +0 -144
- data/vendor/assets/stylesheets/footable.theme.bootstrap.css +0 -6158
@@ -1,7 +1,7 @@
|
|
1
1
|
/*!
|
2
2
|
* FooTable - Awesome Responsive Tables
|
3
|
-
* Version : 0
|
4
|
-
* http://
|
3
|
+
* Version : 2.0
|
4
|
+
* http://fooplugins.com/plugins/footable-jquery/
|
5
5
|
*
|
6
6
|
* Requires jQuery - http://jquery.com/
|
7
7
|
*
|
@@ -9,7 +9,7 @@
|
|
9
9
|
* Released under the MIT license
|
10
10
|
* You are free to use FooTable in commercial projects as long as this copyright header is left intact.
|
11
11
|
*
|
12
|
-
* Date:
|
12
|
+
* Date: 23 Aug 2013
|
13
13
|
*/
|
14
14
|
(function ($, w, undefined) {
|
15
15
|
w.footable = {
|
@@ -22,12 +22,35 @@
|
|
22
22
|
parsers: { // The default parser to parse the value out of a cell (values are used in building up row detail)
|
23
23
|
alpha: function (cell) {
|
24
24
|
return $(cell).data('value') || $.trim($(cell).text());
|
25
|
+
},
|
26
|
+
numeric: function (cell) {
|
27
|
+
var val = $(cell).data('value') || $(cell).text().replace(/[^0-9.\-]/g, '');
|
28
|
+
val = parseFloat(val);
|
29
|
+
if (isNaN(val)) val = 0;
|
30
|
+
return val;
|
25
31
|
}
|
26
32
|
},
|
33
|
+
addRowToggle: true,
|
27
34
|
calculateWidthAndHeightOverride: null,
|
28
35
|
toggleSelector: ' > tbody > tr:not(.footable-row-detail)', //the selector to show/hide the detail row
|
29
36
|
columnDataSelector: '> thead > tr:last-child > th, > thead > tr:last-child > td', //the selector used to find the column data in the thead
|
30
|
-
|
37
|
+
detailSeparator: ':', //the seperator character used when building up the detail row
|
38
|
+
createGroupedDetail: function (data) {
|
39
|
+
var groups = { '_none': { 'name': null, 'data': [] } };
|
40
|
+
for (var i = 0; i < data.length; i++) {
|
41
|
+
var groupid = data[i].group;
|
42
|
+
if (groupid !== null) {
|
43
|
+
if (!(groupid in groups))
|
44
|
+
groups[groupid] = { 'name': data[i].groupName || data[i].group, 'data': [] };
|
45
|
+
|
46
|
+
groups[groupid].data.push(data[i]);
|
47
|
+
} else {
|
48
|
+
groups._none.data.push(data[i]);
|
49
|
+
}
|
50
|
+
}
|
51
|
+
return groups;
|
52
|
+
},
|
53
|
+
createDetail: function (element, data, createGroupedDetail, separatorChar, classes) {
|
31
54
|
/// <summary>This function is used by FooTable to generate the detail view seen when expanding a collapsed row.</summary>
|
32
55
|
/// <param name="element">This is the div that contains all the detail row information, anything could be added to it.</param>
|
33
56
|
/// <param name="data">
|
@@ -41,37 +64,60 @@
|
|
41
64
|
/// 'groupName': String // This is the actual name of the group the column belongs to.
|
42
65
|
/// }
|
43
66
|
/// </param>
|
67
|
+
/// <param name="createGroupedDetail">The grouping function to group the data</param>
|
68
|
+
/// <param name="separatorChar">The separator charactor used</param>
|
69
|
+
/// <param name="classes">The array of class names used to build up the detail row</param>
|
44
70
|
|
45
|
-
var groups =
|
46
|
-
for (var i = 0; i < data.length; i++) {
|
47
|
-
var groupid = data[i].group;
|
48
|
-
if (groupid != null) {
|
49
|
-
if (!(groupid in groups))
|
50
|
-
groups[groupid] = { 'name': data[i].groupName, 'data': [] };
|
51
|
-
|
52
|
-
groups[groupid].data.push(data[i]);
|
53
|
-
} else {
|
54
|
-
groups._none.data.push(data[i]);
|
55
|
-
}
|
56
|
-
}
|
57
|
-
|
71
|
+
var groups = createGroupedDetail(data);
|
58
72
|
for (var group in groups) {
|
59
|
-
if (groups[group].data.length
|
60
|
-
if (group
|
73
|
+
if (groups[group].data.length === 0) continue;
|
74
|
+
if (group !== '_none') element.append('<div class="' + classes.detailInnerGroup + '">' + groups[group].name + '</div>');
|
61
75
|
|
62
76
|
for (var j = 0; j < groups[group].data.length; j++) {
|
63
|
-
|
77
|
+
var separator = (groups[group].data[j].name) ? separatorChar : '';
|
78
|
+
element.append('<div class="' + classes.detailInnerRow + '"><div class="' + classes.detailInnerName + '">' + groups[group].data[j].name + separator + '</div><div class="' + classes.detailInnerValue + '">' + groups[group].data[j].display + '</div></div>');
|
64
79
|
}
|
65
80
|
}
|
66
81
|
},
|
67
82
|
classes: {
|
83
|
+
main: 'footable',
|
68
84
|
loading: 'footable-loading',
|
69
85
|
loaded: 'footable-loaded',
|
70
|
-
|
71
|
-
|
72
|
-
|
86
|
+
toggle: 'footable-toggle',
|
87
|
+
disabled: 'footable-disabled',
|
88
|
+
detail: 'footable-row-detail',
|
89
|
+
detailCell: 'footable-row-detail-cell',
|
90
|
+
detailInner: 'footable-row-detail-inner',
|
91
|
+
detailInnerRow: 'footable-row-detail-row',
|
92
|
+
detailInnerGroup: 'footable-row-detail-group',
|
93
|
+
detailInnerName: 'footable-row-detail-name',
|
94
|
+
detailInnerValue: 'footable-row-detail-value',
|
95
|
+
detailShow: 'footable-detail-show'
|
96
|
+
},
|
97
|
+
triggers: {
|
98
|
+
initialize: 'footable_initialize', //trigger this event to force FooTable to reinitialize
|
99
|
+
resize: 'footable_resize', //trigger this event to force FooTable to resize
|
100
|
+
redraw: 'footable_redraw', //trigger this event to force FooTable to redraw
|
101
|
+
toggleRow: 'footable_toggle_row', //trigger this event to force FooTable to toggle a row
|
102
|
+
expandFirstRow: 'footable_expand_first_row' //trigger this event to force FooTable to expand the first row
|
73
103
|
},
|
74
|
-
|
104
|
+
events: {
|
105
|
+
alreadyInitialized: 'footable_already_initialized', //fires when the FooTable has already been initialized
|
106
|
+
initializing: 'footable_initializing', //fires before FooTable starts initializing
|
107
|
+
initialized: 'footable_initialized', //fires after FooTable has finished initializing
|
108
|
+
resizing: 'footable_resizing', //fires before FooTable resizes
|
109
|
+
resized: 'footable_resized', //fires after FooTable has resized
|
110
|
+
redrawn: 'footable_redrawn', //fires after FooTable has redrawn
|
111
|
+
breakpoint: 'footable_breakpoint', //fires inside the resize function, when a breakpoint is hit
|
112
|
+
columnData: 'footable_column_data', //fires when setting up column data. Plugins should use this event to capture their own info about a column
|
113
|
+
rowDetailUpdating: 'footable_row_detail_updating', //fires before a detail row is updated
|
114
|
+
rowDetailUpdated: 'footable_row_detail_updated', //fires when a detail row is being updated
|
115
|
+
rowCollapsed: 'footable_row_collapsed', //fires when a row is collapsed
|
116
|
+
rowExpanded: 'footable_row_expanded', //fires when a row is expanded
|
117
|
+
rowRemoved: 'footable_row_removed' //fires when a row is removed
|
118
|
+
},
|
119
|
+
debug: false, // Whether or not to log information to the console.
|
120
|
+
log: null
|
75
121
|
},
|
76
122
|
|
77
123
|
version: {
|
@@ -82,9 +128,9 @@
|
|
82
128
|
parse: function (str) {
|
83
129
|
version = /(\d+)\.?(\d+)?\.?(\d+)?/.exec(str);
|
84
130
|
return {
|
85
|
-
major: parseInt(version[1]) || 0,
|
86
|
-
minor: parseInt(version[2]) || 0,
|
87
|
-
patch: parseInt(version[3]) || 0
|
131
|
+
major: parseInt(version[1], 10) || 0,
|
132
|
+
minor: parseInt(version[2], 10) || 0,
|
133
|
+
patch: parseInt(version[3], 10) || 0
|
88
134
|
};
|
89
135
|
}
|
90
136
|
},
|
@@ -95,14 +141,14 @@
|
|
95
141
|
///<param name="plugin">The object defining the plugin, this should implement a string property called "name" and a function called "init".</param>
|
96
142
|
|
97
143
|
if (typeof plugin['name'] !== 'string') {
|
98
|
-
if (w.footable.options.debug
|
144
|
+
if (w.footable.options.debug === true) console.error('Validation failed, plugin does not implement a string property called "name".', plugin);
|
99
145
|
return false;
|
100
146
|
}
|
101
147
|
if (!$.isFunction(plugin['init'])) {
|
102
|
-
if (w.footable.options.debug
|
148
|
+
if (w.footable.options.debug === true) console.error('Validation failed, plugin "' + plugin['name'] + '" does not implement a function called "init".', plugin);
|
103
149
|
return false;
|
104
150
|
}
|
105
|
-
if (w.footable.options.debug
|
151
|
+
if (w.footable.options.debug === true) console.log('Validation succeeded for plugin "' + plugin['name'] + '".', plugin);
|
106
152
|
return true;
|
107
153
|
},
|
108
154
|
registered: [], // An array containing all registered plugins.
|
@@ -113,8 +159,8 @@
|
|
113
159
|
|
114
160
|
if (w.footable.plugins._validate(plugin)) {
|
115
161
|
w.footable.plugins.registered.push(plugin);
|
116
|
-
if (options
|
117
|
-
if (w.footable.options.debug
|
162
|
+
if (options !== undefined && typeof options === 'object') $.extend(true, w.footable.options, options);
|
163
|
+
if (w.footable.options.debug === true) console.log('Plugin "' + plugin['name'] + '" has been registered with the Foobox.', plugin);
|
118
164
|
}
|
119
165
|
},
|
120
166
|
init: function (instance) {
|
@@ -125,7 +171,7 @@
|
|
125
171
|
try {
|
126
172
|
w.footable.plugins.registered[i]['init'](instance);
|
127
173
|
} catch (err) {
|
128
|
-
if (w.footable.options.debug
|
174
|
+
if (w.footable.options.debug === true) console.error(err);
|
129
175
|
}
|
130
176
|
}
|
131
177
|
}
|
@@ -145,7 +191,8 @@
|
|
145
191
|
var o = $.extend(true, {}, w.footable.options, options); //merge user and default options
|
146
192
|
return this.each(function () {
|
147
193
|
instanceCount++;
|
148
|
-
|
194
|
+
var footable = new Footable(this, o, instanceCount);
|
195
|
+
$(this).data('footable', footable);
|
149
196
|
});
|
150
197
|
};
|
151
198
|
|
@@ -174,13 +221,13 @@
|
|
174
221
|
t.stop = function () {
|
175
222
|
///<summary>Stops the timer if its runnning and resets it back to its starting state.</summary>
|
176
223
|
|
177
|
-
if (t.id
|
224
|
+
if (t.id !== null) {
|
178
225
|
clearTimeout(t.id);
|
179
226
|
t.id = null;
|
180
227
|
t.busy = false;
|
181
228
|
}
|
182
229
|
};
|
183
|
-
}
|
230
|
+
}
|
184
231
|
|
185
232
|
function Footable(t, o, id) {
|
186
233
|
///<summary>Inits a new instance of the plugin.</summary>
|
@@ -196,11 +243,13 @@
|
|
196
243
|
ft.breakpointNames = '';
|
197
244
|
ft.columns = {};
|
198
245
|
|
199
|
-
var opt = ft.options
|
200
|
-
|
201
|
-
|
246
|
+
var opt = ft.options,
|
247
|
+
cls = opt.classes,
|
248
|
+
evt = opt.events,
|
249
|
+
trg = opt.triggers,
|
250
|
+
indexOffset = 0;
|
202
251
|
|
203
|
-
// This object simply houses all the timers used in the
|
252
|
+
// This object simply houses all the timers used in the FooTable.
|
204
253
|
ft.timers = {
|
205
254
|
resize: new Timer(),
|
206
255
|
register: function (name) {
|
@@ -216,29 +265,19 @@
|
|
216
265
|
|
217
266
|
if ($table.hasClass(cls.loaded)) {
|
218
267
|
//already loaded FooTable for the table, so don't init again
|
219
|
-
ft.raise(
|
268
|
+
ft.raise(evt.alreadyInitialized);
|
220
269
|
return;
|
221
270
|
}
|
222
271
|
|
272
|
+
//raise the initializing event
|
273
|
+
ft.raise(evt.initializing);
|
274
|
+
|
223
275
|
$table.addClass(cls.loading);
|
224
276
|
|
225
277
|
// Get the column data once for the life time of the plugin
|
226
278
|
$table.find(opt.columnDataSelector).each(function () {
|
227
279
|
var data = ft.getColumnData(this);
|
228
280
|
ft.columns[data.index] = data;
|
229
|
-
|
230
|
-
if (data.className != null) {
|
231
|
-
var selector = '', first = true;
|
232
|
-
$.each(data.matches, function (m, match) { //support for colspans
|
233
|
-
if (!first) {
|
234
|
-
selector += ', ';
|
235
|
-
}
|
236
|
-
selector += '> tbody > tr:not(.footable-row-detail) > td:nth-child(' + (parseInt(match) + 1) + ')';
|
237
|
-
first = false;
|
238
|
-
});
|
239
|
-
//add the className to the cells specified by data-class="blah"
|
240
|
-
$table.find(selector).not('.footable-cell-detail').addClass(data.className);
|
241
|
-
}
|
242
281
|
});
|
243
282
|
|
244
283
|
// Create a nice friendly array to work with out of the breakpoints object.
|
@@ -252,49 +291,110 @@
|
|
252
291
|
return a['width'] - b['width'];
|
253
292
|
});
|
254
293
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
294
|
+
$table
|
295
|
+
//bind to FooTable initialize trigger
|
296
|
+
.bind(trg.initialize, function () {
|
297
|
+
//remove previous "state" (to "force" a resize)
|
298
|
+
$table.removeData('footable_info');
|
299
|
+
$table.data('breakpoint', '');
|
300
|
+
|
301
|
+
//trigger the FooTable resize
|
302
|
+
$table.trigger(trg.resize);
|
303
|
+
|
304
|
+
//remove the loading class
|
305
|
+
$table.removeClass(cls.loading);
|
306
|
+
|
307
|
+
//add the FooTable and loaded class
|
308
|
+
$table.addClass(cls.loaded).addClass(cls.main);
|
309
|
+
|
310
|
+
//raise the initialized event
|
311
|
+
ft.raise(evt.initialized);
|
312
|
+
})
|
313
|
+
//bind to FooTable redraw trigger
|
314
|
+
.bind(trg.redraw, function () {
|
315
|
+
ft.redraw();
|
316
|
+
})
|
317
|
+
|
318
|
+
//bind to FooTable resize trigger
|
319
|
+
.bind(trg.resize, function () {
|
320
|
+
ft.resize();
|
321
|
+
})
|
322
|
+
//bind to FooTable expandFirstRow trigger
|
323
|
+
.bind(trg.expandFirstRow, function () {
|
324
|
+
$table.find(opt.toggleSelector).first().not('.' + cls.detailShow).trigger(trg.toggleRow);
|
325
|
+
});
|
275
326
|
|
276
|
-
|
277
|
-
|
278
|
-
});
|
327
|
+
//trigger a FooTable initialize
|
328
|
+
$table.trigger(trg.initialize);
|
279
329
|
|
330
|
+
//bind to window resize
|
280
331
|
$window
|
281
332
|
.bind('resize.footable', function () {
|
282
333
|
ft.timers.resize.stop();
|
283
334
|
ft.timers.resize.start(function () {
|
284
|
-
ft.resize
|
335
|
+
ft.raise(trg.resize);
|
285
336
|
}, opt.delay);
|
286
337
|
});
|
338
|
+
};
|
339
|
+
|
340
|
+
ft.addRowToggle = function () {
|
341
|
+
if (!opt.addRowToggle) return;
|
342
|
+
|
343
|
+
var $table = $(ft.table),
|
344
|
+
hasToggleColumn = false;
|
345
|
+
|
346
|
+
//first remove all toggle spans
|
347
|
+
$table.find('span.' + cls.toggle).remove();
|
348
|
+
|
349
|
+
for (var c in ft.columns) {
|
350
|
+
var col = ft.columns[c];
|
351
|
+
if (col.toggle) {
|
352
|
+
hasToggleColumn = true;
|
353
|
+
var selector = '> tbody > tr:not(.' + cls.detail + ',.' + cls.disabled + ') > td:nth-child(' + (parseInt(col.index, 10) + 1) + ')';
|
354
|
+
$table.find(selector).not('.' + cls.detailCell).prepend($('<span />').addClass(cls.toggle));
|
355
|
+
return;
|
356
|
+
}
|
357
|
+
}
|
358
|
+
//check if we have an toggle column. If not then add it to the first column just to be safe
|
359
|
+
if (!hasToggleColumn) {
|
360
|
+
$table
|
361
|
+
.find('> tbody > tr:not(.' + cls.detail + ',.' + cls.disabled + ') > td:first-child')
|
362
|
+
.not('.' + cls.detailCell)
|
363
|
+
.prepend($('<span />').addClass(cls.toggle));
|
364
|
+
}
|
365
|
+
};
|
287
366
|
|
288
|
-
|
367
|
+
ft.setColumnClasses = function () {
|
368
|
+
$table = $(ft.table);
|
369
|
+
for (var c in ft.columns) {
|
370
|
+
var col = ft.columns[c];
|
371
|
+
if (col.className !== null) {
|
372
|
+
var selector = '', first = true;
|
373
|
+
$.each(col.matches, function (m, match) { //support for colspans
|
374
|
+
if (!first) selector += ', ';
|
375
|
+
selector += '> tbody > tr:not(.' + cls.detail + ') > td:nth-child(' + (parseInt(match, 10) + 1) + ')';
|
376
|
+
first = false;
|
377
|
+
});
|
378
|
+
//add the className to the cells specified by data-class="blah"
|
379
|
+
$table.find(selector).not('.' + cls.detailCell).addClass(col.className);
|
380
|
+
}
|
381
|
+
}
|
289
382
|
};
|
290
383
|
|
291
384
|
//moved this out into it's own function so that it can be called from other add-ons
|
292
385
|
ft.bindToggleSelectors = function () {
|
293
386
|
var $table = $(ft.table);
|
387
|
+
|
388
|
+
if (!ft.hasAnyBreakpointColumn()) return;
|
389
|
+
|
390
|
+
$table.find(opt.toggleSelector).unbind(trg.toggleRow).bind(trg.toggleRow, function (e) {
|
391
|
+
var $row = $(this).is('tr') ? $(this) : $(this).parents('tr:first');
|
392
|
+
ft.toggleDetail($row.get(0));
|
393
|
+
});
|
394
|
+
|
294
395
|
$table.find(opt.toggleSelector).unbind('click.footable').bind('click.footable', function (e) {
|
295
|
-
if ($table.is('.breakpoint') && $(e.target).is('td')) {
|
296
|
-
|
297
|
-
ft.toggleDetail($row.get(0));
|
396
|
+
if ($table.is('.breakpoint') && $(e.target).is('td,.footable-toggle')) {
|
397
|
+
$(this).trigger(trg.toggleRow);
|
298
398
|
}
|
299
399
|
});
|
300
400
|
};
|
@@ -307,13 +407,16 @@
|
|
307
407
|
ft.getColumnData = function (th) {
|
308
408
|
var $th = $(th), hide = $th.data('hide'), index = $th.index();
|
309
409
|
hide = hide || '';
|
310
|
-
hide = hide.split(',')
|
410
|
+
hide = jQuery.map(hide.split(','), function (a) {
|
411
|
+
return jQuery.trim(a);
|
412
|
+
});
|
311
413
|
var data = {
|
312
414
|
'index': index,
|
313
415
|
'hide': { },
|
314
416
|
'type': $th.data('type') || 'alpha',
|
315
417
|
'name': $th.data('name') || $.trim($th.text()),
|
316
418
|
'ignore': $th.data('ignore') || false,
|
419
|
+
'toggle': $th.data('toggle') || false,
|
317
420
|
'className': $th.data('class') || null,
|
318
421
|
'matches': [],
|
319
422
|
'names': { },
|
@@ -321,14 +424,14 @@
|
|
321
424
|
'groupName': null
|
322
425
|
};
|
323
426
|
|
324
|
-
if (data.group
|
427
|
+
if (data.group !== null) {
|
325
428
|
var $group = $(ft.table).find('> thead > tr.footable-group-row > th[data-group="' + data.group + '"], > thead > tr.footable-group-row > td[data-group="' + data.group + '"]').first();
|
326
429
|
data.groupName = ft.parse($group, { 'type': 'alpha' });
|
327
430
|
}
|
328
431
|
|
329
|
-
var pcolspan = parseInt($th.prev().attr('colspan') || 0);
|
432
|
+
var pcolspan = parseInt($th.prev().attr('colspan') || 0, 10);
|
330
433
|
indexOffset += pcolspan > 1 ? pcolspan - 1 : 0;
|
331
|
-
var colspan = parseInt($th.attr('colspan') || 0), curindex = data.index + indexOffset;
|
434
|
+
var colspan = parseInt($th.attr('colspan') || 0, 10), curindex = data.index + indexOffset;
|
332
435
|
if (colspan > 1) {
|
333
436
|
var names = $th.data('names');
|
334
437
|
names = names || '';
|
@@ -343,10 +446,13 @@
|
|
343
446
|
|
344
447
|
data.hide['default'] = ($th.data('hide') === "all") || ($.inArray('default', hide) >= 0);
|
345
448
|
|
449
|
+
var hasBreakpoint = false;
|
346
450
|
for (var name in opt.breakpoints) {
|
347
451
|
data.hide[name] = ($th.data('hide') === "all") || ($.inArray(name, hide) >= 0);
|
452
|
+
hasBreakpoint = hasBreakpoint || data.hide[name];
|
348
453
|
}
|
349
|
-
|
454
|
+
data.hasBreakpoint = hasBreakpoint;
|
455
|
+
var e = ft.raise(evt.columnData, { 'column': { 'data': data, 'th': th } });
|
350
456
|
return e.column.data;
|
351
457
|
};
|
352
458
|
|
@@ -371,6 +477,18 @@
|
|
371
477
|
ft.hasBreakpointColumn = function (breakpoint) {
|
372
478
|
for (var c in ft.columns) {
|
373
479
|
if (ft.columns[c].hide[breakpoint]) {
|
480
|
+
if (ft.columns[c].ignore) {
|
481
|
+
continue;
|
482
|
+
}
|
483
|
+
return true;
|
484
|
+
}
|
485
|
+
}
|
486
|
+
return false;
|
487
|
+
};
|
488
|
+
|
489
|
+
ft.hasAnyBreakpointColumn = function () {
|
490
|
+
for (var c in ft.columns) {
|
491
|
+
if (ft.columns[c].hasBreakpoint) {
|
374
492
|
return true;
|
375
493
|
}
|
376
494
|
}
|
@@ -379,6 +497,15 @@
|
|
379
497
|
|
380
498
|
ft.resize = function () {
|
381
499
|
var $table = $(ft.table);
|
500
|
+
|
501
|
+
if (!$table.is(':visible')) {
|
502
|
+
return;
|
503
|
+
} //we only care about FooTables that are visible
|
504
|
+
|
505
|
+
if (!ft.hasAnyBreakpointColumn()) {
|
506
|
+
return;
|
507
|
+
} //we only care about FooTables that have breakpoints
|
508
|
+
|
382
509
|
var info = {
|
383
510
|
'width': $table.width(), //the table width
|
384
511
|
'height': $table.height(), //the table height
|
@@ -386,16 +513,18 @@
|
|
386
513
|
'viewportHeight': ft.getViewportHeight(), //the width of the viewport
|
387
514
|
'orientation': null
|
388
515
|
};
|
516
|
+
|
389
517
|
info.orientation = info.viewportWidth > info.viewportHeight ? 'landscape' : 'portrait';
|
390
518
|
|
391
519
|
info = ft.calculateWidthAndHeight($table, info);
|
392
520
|
|
393
521
|
var pinfo = $table.data('footable_info');
|
394
522
|
$table.data('footable_info', info);
|
395
|
-
ft.raise(
|
523
|
+
ft.raise(evt.resizing, { 'old': pinfo, 'info': info });
|
396
524
|
|
397
525
|
// This (if) statement is here purely to make sure events aren't raised twice as mobile safari seems to do
|
398
|
-
if (!pinfo || ((pinfo && pinfo.width && pinfo.width
|
526
|
+
if (!pinfo || ((pinfo && pinfo.width && pinfo.width !== info.width) || (pinfo && pinfo.height && pinfo.height !== info.height))) {
|
527
|
+
|
399
528
|
var current = null, breakpoint;
|
400
529
|
for (var i = 0; i < ft.breakpoints.length; i++) {
|
401
530
|
breakpoint = ft.breakpoints[i];
|
@@ -405,90 +534,148 @@
|
|
405
534
|
}
|
406
535
|
}
|
407
536
|
|
408
|
-
var breakpointName = (current
|
409
|
-
|
410
|
-
|
537
|
+
var breakpointName = (current === null ? 'default' : current['name']),
|
538
|
+
hasBreakpointFired = ft.hasBreakpointColumn(breakpointName),
|
539
|
+
previousBreakpoint = $table.data('breakpoint');
|
411
540
|
|
412
541
|
$table
|
542
|
+
.data('breakpoint', breakpointName)
|
413
543
|
.removeClass('default breakpoint').removeClass(ft.breakpointNames)
|
414
|
-
.addClass(breakpointName + (hasBreakpointFired ? ' breakpoint' : ''))
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
selector += ', > tfoot > tr:not(.footable-row-detail) > td:nth-child(' + count + ')';
|
425
|
-
selector += ', > colgroup > col:nth-child(' + count + ')';
|
426
|
-
first = false;
|
427
|
-
});
|
544
|
+
.addClass(breakpointName + (hasBreakpointFired ? ' breakpoint' : ''));
|
545
|
+
|
546
|
+
//only do something if the breakpoint has changed
|
547
|
+
if (breakpointName !== previousBreakpoint) {
|
548
|
+
//trigger a redraw
|
549
|
+
$table.trigger(trg.redraw);
|
550
|
+
//raise a breakpoint event
|
551
|
+
ft.raise(evt.breakpoint, { 'breakpoint': breakpointName, 'info': info });
|
552
|
+
}
|
553
|
+
}
|
428
554
|
|
429
|
-
|
430
|
-
|
431
|
-
if (data.hide[breakpointName] == false) $column.show();
|
432
|
-
else $column.hide();
|
555
|
+
ft.raise(evt.resized, { 'old': pinfo, 'info': info });
|
556
|
+
};
|
433
557
|
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
groupspan = 0;
|
558
|
+
ft.redraw = function () {
|
559
|
+
//add the toggler to each row
|
560
|
+
ft.addRowToggle();
|
438
561
|
|
439
|
-
|
440
|
-
|
441
|
-
|
562
|
+
//bind the toggle selector click events
|
563
|
+
ft.bindToggleSelectors();
|
564
|
+
|
565
|
+
//set any cell classes defined for the columns
|
566
|
+
ft.setColumnClasses();
|
442
567
|
|
443
|
-
|
444
|
-
|
568
|
+
var $table = $(ft.table),
|
569
|
+
breakpointName = $table.data('breakpoint'),
|
570
|
+
hasBreakpointFired = ft.hasBreakpointColumn(breakpointName);
|
571
|
+
|
572
|
+
$table
|
573
|
+
.find('> tbody > tr:not(.' + cls.detail + ')').data('detail_created', false).end()
|
574
|
+
.find('> thead > tr:last-child > th')
|
575
|
+
.each(function () {
|
576
|
+
var data = ft.columns[$(this).index()], selector = '', first = true;
|
577
|
+
$.each(data.matches, function (m, match) {
|
578
|
+
if (!first) {
|
579
|
+
selector += ', ';
|
445
580
|
}
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
581
|
+
var count = match + 1;
|
582
|
+
selector += '> tbody > tr:not(.' + cls.detail + ') > td:nth-child(' + count + ')';
|
583
|
+
selector += ', > tfoot > tr:not(.' + cls.detail + ') > td:nth-child(' + count + ')';
|
584
|
+
selector += ', > colgroup > col:nth-child(' + count + ')';
|
585
|
+
first = false;
|
450
586
|
});
|
451
587
|
|
452
|
-
|
453
|
-
var $
|
454
|
-
if ($
|
455
|
-
|
456
|
-
|
588
|
+
selector += ', > thead > tr[data-group-row="true"] > th[data-group="' + data.group + '"]';
|
589
|
+
var $column = $table.find(selector).add(this);
|
590
|
+
if (data.hide[breakpointName] === false) $column.show();
|
591
|
+
else $column.hide();
|
592
|
+
|
593
|
+
if ($table.find('> thead > tr.footable-group-row').length === 1) {
|
594
|
+
var $groupcols = $table.find('> thead > tr:last-child > th[data-group="' + data.group + '"]:visible, > thead > tr:last-child > th[data-group="' + data.group + '"]:visible'),
|
595
|
+
$group = $table.find('> thead > tr.footable-group-row > th[data-group="' + data.group + '"], > thead > tr.footable-group-row > td[data-group="' + data.group + '"]'),
|
596
|
+
groupspan = 0;
|
597
|
+
|
598
|
+
$.each($groupcols, function () {
|
599
|
+
groupspan += parseInt($(this).attr('colspan') || 1, 10);
|
600
|
+
});
|
601
|
+
|
602
|
+
if (groupspan > 0) $group.attr('colspan', groupspan).show();
|
603
|
+
else $group.hide();
|
457
604
|
}
|
605
|
+
})
|
606
|
+
.end()
|
607
|
+
.find('> tbody > tr.' + cls.detailShow).each(function () {
|
608
|
+
ft.createOrUpdateDetailRow(this);
|
458
609
|
});
|
459
610
|
|
460
|
-
|
461
|
-
|
462
|
-
$
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
.end()
|
468
|
-
.find('> th:visible:first, > td:visible:first')
|
469
|
-
.addClass('footable-first-column');
|
470
|
-
|
471
|
-
ft.raise('footable_breakpoint_' + breakpointName, { 'info': info });
|
472
|
-
}
|
611
|
+
$table.find('> tbody > tr.' + cls.detailShow + ':visible').each(function () {
|
612
|
+
var $next = $(this).next();
|
613
|
+
if ($next.hasClass(cls.detail)) {
|
614
|
+
if (!hasBreakpointFired) $next.hide();
|
615
|
+
else $next.show();
|
616
|
+
}
|
617
|
+
});
|
473
618
|
|
474
|
-
|
619
|
+
// adding .footable-first-column and .footable-last-column to the first and last th and td of each row in order to allow
|
620
|
+
// for styling if the first or last column is hidden (which won't work using :first-child or :last-child)
|
621
|
+
$table.find('> thead > tr > th.footable-last-column, > tbody > tr > td.footable-last-column').removeClass('footable-last-column');
|
622
|
+
$table.find('> thead > tr > th.footable-first-column, > tbody > tr > td.footable-first-column').removeClass('footable-first-column');
|
623
|
+
$table.find('> thead > tr, > tbody > tr')
|
624
|
+
.find('> th:visible:last, > td:visible:last')
|
625
|
+
.addClass('footable-last-column')
|
626
|
+
.end()
|
627
|
+
.find('> th:visible:first, > td:visible:first')
|
628
|
+
.addClass('footable-first-column');
|
629
|
+
|
630
|
+
ft.raise(evt.redrawn);
|
475
631
|
};
|
476
632
|
|
477
|
-
ft.toggleDetail = function (
|
478
|
-
var $row = $(
|
479
|
-
created = ft.createOrUpdateDetailRow($row.get(0)),
|
633
|
+
ft.toggleDetail = function (row) {
|
634
|
+
var $row = (row.jquery) ? row : $(row),
|
480
635
|
$next = $row.next();
|
481
636
|
|
482
|
-
if
|
483
|
-
|
637
|
+
//check if the row is already expanded
|
638
|
+
if ($row.hasClass(cls.detailShow)) {
|
639
|
+
$row.removeClass(cls.detailShow);
|
640
|
+
|
484
641
|
//only hide the next row if it's a detail row
|
485
|
-
if ($next.hasClass(
|
642
|
+
if ($next.hasClass(cls.detail)) $next.hide();
|
643
|
+
|
644
|
+
ft.raise(evt.rowCollapsed, { 'row': $row[0] });
|
645
|
+
|
486
646
|
} else {
|
487
|
-
$row
|
488
|
-
$
|
647
|
+
ft.createOrUpdateDetailRow($row[0]);
|
648
|
+
$row.addClass(cls.detailShow);
|
649
|
+
$row.next().show();
|
650
|
+
|
651
|
+
ft.raise(evt.rowExpanded, { 'row': $row[0] });
|
489
652
|
}
|
490
653
|
};
|
491
654
|
|
655
|
+
ft.removeRow = function (row) {
|
656
|
+
var $row = (row.jquery) ? row : $(row);
|
657
|
+
if ($row.hasClass(cls.detail)) {
|
658
|
+
$row = $row.prev();
|
659
|
+
}
|
660
|
+
var $next = $row.next();
|
661
|
+
if ($row.data('detail_created') === true) {
|
662
|
+
//remove the detail row
|
663
|
+
$next.remove();
|
664
|
+
}
|
665
|
+
$row.remove();
|
666
|
+
|
667
|
+
//raise event
|
668
|
+
ft.raise(evt.rowRemoved);
|
669
|
+
};
|
670
|
+
|
671
|
+
ft.appendRow = function (row) {
|
672
|
+
var $row = (row.jquery) ? row : $(row);
|
673
|
+
$(ft.table).find('tbody').append($row);
|
674
|
+
|
675
|
+
//redraw the table
|
676
|
+
ft.redraw();
|
677
|
+
};
|
678
|
+
|
492
679
|
ft.getColumnFromTdIndex = function (index) {
|
493
680
|
/// <summary>Returns the correct column data for the supplied index taking into account colspans.</summary>
|
494
681
|
/// <param name="index">The index to retrieve the column data for.</param>
|
@@ -505,30 +692,37 @@
|
|
505
692
|
|
506
693
|
ft.createOrUpdateDetailRow = function (actualRow) {
|
507
694
|
var $row = $(actualRow), $next = $row.next(), $detail, values = [];
|
508
|
-
if ($row.
|
509
|
-
|
695
|
+
if ($row.data('detail_created') === true) return true;
|
696
|
+
|
697
|
+
if ($row.is(':hidden')) return false; //if the row is hidden for some reason (perhaps filtered) then get out of here
|
698
|
+
ft.raise(evt.rowDetailUpdating, { 'row': $row, 'detail': $next });
|
510
699
|
$row.find('> td:hidden').each(function () {
|
511
700
|
var index = $(this).index(), column = ft.getColumnFromTdIndex(index), name = column.name;
|
512
|
-
if (column.ignore
|
701
|
+
if (column.ignore === true) return true;
|
513
702
|
|
514
703
|
if (index in column.names) name = column.names[index];
|
515
704
|
values.push({ 'name': name, 'value': ft.parse(this, column), 'display': $.trim($(this).html()), 'group': column.group, 'groupName': column.groupName });
|
516
705
|
return true;
|
517
706
|
});
|
518
|
-
if (values.length
|
707
|
+
if (values.length === 0) return false; //return if we don't have any data to show
|
519
708
|
var colspan = $row.find('> td:visible').length;
|
520
|
-
var exists = $next.hasClass(
|
709
|
+
var exists = $next.hasClass(cls.detail);
|
521
710
|
if (!exists) { // Create
|
522
|
-
$next = $('<tr class="
|
711
|
+
$next = $('<tr class="' + cls.detail + '"><td class="' + cls.detailCell + '"><div class="' + cls.detailInner + '"></div></td></tr>');
|
523
712
|
$row.after($next);
|
524
713
|
}
|
525
714
|
$next.find('> td:first').attr('colspan', colspan);
|
526
|
-
$detail = $next.find('.
|
527
|
-
opt.createDetail($detail, values);
|
715
|
+
$detail = $next.find('.' + cls.detailInner).empty();
|
716
|
+
opt.createDetail($detail, values, opt.createGroupedDetail, opt.detailSeparator, cls);
|
717
|
+
$row.data('detail_created', true);
|
718
|
+
ft.raise(evt.rowDetailUpdated, { 'row': $row, 'detail': $next });
|
528
719
|
return !exists;
|
529
720
|
};
|
530
721
|
|
531
722
|
ft.raise = function (eventName, args) {
|
723
|
+
|
724
|
+
if (ft.options.debug === true && $.isFunction(ft.options.log)) ft.options.log(eventName, 'event');
|
725
|
+
|
532
726
|
args = args || { };
|
533
727
|
var def = { 'ft': ft };
|
534
728
|
$.extend(true, def, args);
|
@@ -542,5 +736,5 @@
|
|
542
736
|
|
543
737
|
ft.init();
|
544
738
|
return ft;
|
545
|
-
}
|
739
|
+
}
|
546
740
|
})(jQuery, window);
|