diff --git a/index.html b/index.html
index 63d89d6..8d56d41 100644
--- a/index.html
+++ b/index.html
@@ -185,7 +185,7 @@ ul.task-list li input[type="checkbox"] {
Modified
-
February 19, 2024
+
February 20, 2024
diff --git a/projects.html b/projects.html
index 05c9741..ff5fd3e 100644
--- a/projects.html
+++ b/projects.html
@@ -68,7 +68,7 @@ ul.task-list li input[type="checkbox"] {
}
-
+
@@ -153,8 +153,8 @@ ul.task-list li input[type="checkbox"] {
Table 1: Projects
diff --git a/site_libs/datatables-binding-0.31/datatables.js b/site_libs/datatables-binding-0.32/datatables.js
similarity index 96%
rename from site_libs/datatables-binding-0.31/datatables.js
rename to site_libs/datatables-binding-0.32/datatables.js
index d21dff0..6a3c3d5 100644
--- a/site_libs/datatables-binding-0.31/datatables.js
+++ b/site_libs/datatables-binding-0.32/datatables.js
@@ -348,6 +348,15 @@ HTMLWidgets.widget({
var table = $table.DataTable(options);
$el.data('datatable', table);
+ if ('rowGroup' in options) {
+ // Maintain RowGroup dataSrc when columns are reordered (#1109)
+ table.on('column-reorder', function(e, settings, details) {
+ var oldDataSrc = table.rowGroup().dataSrc();
+ var newDataSrc = details.mapping[oldDataSrc];
+ table.rowGroup().dataSrc(newDataSrc);
+ });
+ }
+
// Unregister previous Crosstalk event subscriptions, if they exist
if (instance.ctfilterSubscription) {
instance.ctfilterHandle.off("change", instance.ctfilterSubscription);
@@ -438,6 +447,7 @@ HTMLWidgets.widget({
};
if (data.filter !== 'none') {
+ if (!data.hasOwnProperty('filterSettings')) data.filterSettings = {};
filterRow.each(function(i, td) {
@@ -501,7 +511,7 @@ HTMLWidgets.widget({
}
});
var $input2 = $x.children('select');
- filter = $input2.selectize({
+ filter = $input2.selectize($.extend({
options: $input2.data('options').map(function(v, i) {
return ({text: v, value: v});
}),
@@ -520,8 +530,7 @@ HTMLWidgets.widget({
$td.data('filter', value.length > 0);
table.draw(); // redraw table, and filters will be applied
}
- });
- if (searchCol) filter[0].selectize.setValue(JSON.parse(searchCol));
+ }, data.filterSettings.select));
filter[0].selectize.on('blur', function() {
$x.hide().trigger('hide'); $input.parent().show(); $input.trigger('blur');
});
@@ -530,10 +539,12 @@ HTMLWidgets.widget({
var fun = function() {
searchColumn(i, $input.val()).draw();
};
- if (server) {
- fun = $.fn.dataTable.util.throttle(fun, options.searchDelay);
- }
- $input.on('input', fun);
+ // throttle searching for server-side processing
+ var throttledFun = $.fn.dataTable.util.throttle(fun, options.searchDelay);
+ $input.on('input', function(e, immediate) {
+ // always bypass throttling when immediate = true (via the updateSearch method)
+ (immediate || !server) ? fun() : throttledFun();
+ });
} else if (inArray(type, ['number', 'integer', 'date', 'time'])) {
var $x0 = $x;
$x = $x0.children('div').first();
@@ -619,13 +630,11 @@ HTMLWidgets.widget({
filter.val(v);
}
});
- var formatDate = function(d, isoFmt) {
+ var formatDate = function(d) {
d = scaleBack(d, scale);
if (type === 'number') return d;
if (type === 'integer') return parseInt(d);
var x = new Date(+d);
- var fmt = ('filterDateFmt' in data) ? data.filterDateFmt[i] : undefined;
- if (fmt !== undefined && isoFmt === false) return x[fmt.method].apply(x, fmt.params);
if (type === 'date') {
var pad0 = function(x) {
return ('0' + x).substr(-2, 2);
@@ -646,7 +655,7 @@ HTMLWidgets.widget({
start: [r1, r2],
range: {min: r1, max: r2},
connect: true
- }, opts));
+ }, opts, data.filterSettings.slider));
if (scale > 1) (function() {
var t1 = r1, t2 = r2;
var val = filter.val();
@@ -661,13 +670,28 @@ HTMLWidgets.widget({
start: [t1, t2],
range: {min: t1, max: t2},
connect: true
- }, opts), true);
+ }, opts, data.filterSettings.slider), true);
val = filter.val();
}
r1 = t1; r2 = t2;
})();
+ // format with active column renderer, if defined
+ var colDef = data.options.columnDefs.find(function(def) {
+ return (def.targets === i || inArray(i, def.targets)) && 'render' in def;
+ });
var updateSliderText = function(v1, v2) {
- $span1.text(formatDate(v1, false)); $span2.text(formatDate(v2, false));
+ // we only know how to use function renderers
+ if (colDef && typeof colDef.render === 'function') {
+ var restore = function(v) {
+ v = scaleBack(v, scale);
+ return inArray(type, ['date', 'time']) ? new Date(+v) : v;
+ }
+ $span1.text(colDef.render(restore(v1), 'display'));
+ $span2.text(colDef.render(restore(v2), 'display'));
+ } else {
+ $span1.text(formatDate(v1));
+ $span2.text(formatDate(v2));
+ }
};
updateSliderText(r1, r2);
var updateSlider = function(e) {
@@ -700,7 +724,7 @@ HTMLWidgets.widget({
// processing
if (server) {
// if a search string has been pre-set, search now
- if (searchCol) searchColumn(i, searchCol).draw();
+ if (searchCol) $input.trigger('input').trigger('change');
return;
}
@@ -746,15 +770,7 @@ HTMLWidgets.widget({
$.fn.dataTable.ext.search.push(customFilter);
// search for the preset search strings if it is non-empty
- if (searchCol) {
- if (inArray(type, ['factor', 'logical'])) {
- filter[0].selectize.setValue(JSON.parse(searchCol));
- } else if (type === 'character') {
- $input.trigger('input');
- } else if (inArray(type, ['number', 'integer', 'date', 'time'])) {
- $input.trigger('change');
- }
- }
+ if (searchCol) $input.trigger('input').trigger('change');
});
@@ -1402,8 +1418,9 @@ HTMLWidgets.widget({
console.log('The search keyword for column ' + i + ' is undefined')
return;
}
- $(td).find('input').first().val(v).trigger('input');
- searchColumn(i, v);
+ // Update column search string and values on linked filter widgets.
+ // 'input' for factor and char filters, 'change' for numeric filters.
+ $(td).find('input').first().val(v).trigger('input', [true]).trigger('change');
});
table.draw();
}