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(); }