forked from rstudio/shiny
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoutput_binding_datatable.js
86 lines (82 loc) · 3.13 KB
/
output_binding_datatable.js
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
var datatableOutputBinding = new OutputBinding();
$.extend(datatableOutputBinding, {
find: function(scope) {
return $(scope).find('.shiny-datatable-output');
},
onValueError: function(el, err) {
exports.unbindAll(el);
this.renderError(el, err);
},
renderValue: function(el, data) {
var $el = $(el).empty();
if (!data || !data.colnames) return;
var colnames = $.makeArray(data.colnames);
var header = $.map(colnames, function(x) {
return '<th>' + x + '</th>';
}).join('');
header = '<thead><tr>' + header + '</tr></thead>';
var footer = '';
if (data.options === null || data.options.searching !== false) {
footer = $.map(colnames, function(x) {
// placeholder needs to be escaped (and HTML tags are stripped off)
return '<th><input type="text" placeholder="' +
escapeHTML(x.replace(/(<([^>]+)>)/ig, '')) +
'" /></th>';
}).join('');
footer = '<tfoot>' + footer + '</tfoot>';
}
var content = '<table class="table table-striped table-hover">' +
header + footer + '</table>';
$el.append(content);
// options that should be eval()ed
if (data.evalOptions)
$.each(data.evalOptions, function(i, x) {
/*jshint evil: true */
data.options[x] = eval('(' + data.options[x] + ')');
});
// caseInsensitive searching? default true
var searchCI = data.options === null || typeof(data.options.search) === 'undefined' ||
data.options.search.caseInsensitive !== false;
var oTable = $(el).children("table").DataTable($.extend({
"processing": true,
"serverSide": true,
"order": [],
"orderClasses": false,
"pageLength": 25,
"ajax": {
"url": data.action,
"type": "POST",
"data": function(d) {
d.search.caseInsensitive = searchCI;
d.escape = data.escape;
}
}
}, data.options));
// the table object may need post-processing
if (typeof data.callback === 'string') {
/*jshint evil: true */
var callback = eval('(' + data.callback + ')');
if (typeof callback === 'function') callback(oTable);
}
// use debouncing for searching boxes
$el.find('label input').first().unbind('keyup')
.keyup(debounce(data.searchDelay, function() {
oTable.search(this.value).draw();
}));
var searchInputs = $el.find("tfoot input");
if (searchInputs.length > 0) {
// this is a little weird: aoColumns/bSearchable are still in DT 1.10
// https://github.com/DataTables/DataTables/issues/388
$.each(oTable.settings()[0].aoColumns, function(i, x) {
// hide the text box if not searchable
if (!x.bSearchable) searchInputs.eq(i).hide();
});
searchInputs.keyup(debounce(data.searchDelay, function() {
oTable.column(searchInputs.index(this)).search(this.value).draw();
}));
}
// FIXME: ugly scrollbars in tab panels b/c Bootstrap uses 'visible: auto'
$el.parents('.tab-content').css('overflow', 'visible');
}
});
outputBindings.register(datatableOutputBinding, 'shiny.datatableOutput');