Enhance filter options sorting based on column data type

This commit is contained in:
koalyptus 2019-06-07 18:26:33 +10:00
parent 2e1af5efb3
commit 78ae09c861
12 changed files with 151 additions and 50 deletions

View File

@ -13,7 +13,7 @@ module.exports = function (grunt) {
coverage: {
disposeCollector: true,
src: ['dist/tablefilter/*.js'],
instrumentedFiles: 'temp/',
instrumentedFiles: 'report/temp/',
htmlReport: 'report/coverage',
coberturaReport: 'report/',
lcovReport: 'report/',

4
dist/starter.html vendored
View File

@ -1,10 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>tablefilter v0.6.93 - Starter</title>
<title>tablefilter v0.6.94 - Starter</title>
</head>
<body>
<h1>tablefilter v0.6.93</h1>
<h1>tablefilter v0.6.94</h1>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
{
"name": "tablefilter",
"version": "0.6.93",
"version": "0.6.94",
"description": "A Javascript library making HTML tables filterable and a bit more",
"license": "MIT",
"author": {

View File

@ -1,7 +1,7 @@
import {Feature} from '../feature';
import {
ignoreCase, numSortAsc, numSortDesc,
dateSortAsc, sortNumberStr, sortDateStr
dateSortAsc, dateSortDesc, sortNumberStr, sortDateStr
} from '../sort';
import {isArray, isObj, isEmpty} from '../types';
import {NUMBER, FORMATTED_NUMBER, DATE} from '../const';
@ -72,14 +72,15 @@ export class BaseDropdown extends Feature {
* @private
*/
sortOptions(colIndex, options = []) {
let tf = this.tf;
let {tf} = this;
if (tf.isCustomOptions(colIndex) || !tf.sortSlc ||
(isArray(tf.sortSlc) && tf.sortSlc.indexOf(colIndex) === -1)) {
return options;
}
let { caseSensitive, sortNumDesc } = tf;
let { caseSensitive, sortFilterOptionsDesc } = tf;
let isSortDesc = sortFilterOptionsDesc.indexOf(colIndex) !== -1;
let compareFn;
if (this.customSorter &&
@ -89,18 +90,18 @@ export class BaseDropdown extends Feature {
}
else if (tf.hasType(colIndex, [NUMBER, FORMATTED_NUMBER])) {
let decimal = tf.getDecimal(colIndex);
let comparer = numSortAsc;
if (sortNumDesc === true || sortNumDesc.indexOf(colIndex) !== -1) {
comparer = numSortDesc;
}
let comparer = isSortDesc ? numSortDesc : numSortAsc;
compareFn = sortNumberStr(comparer, decimal);
}
else if (tf.hasType(colIndex, [DATE])) {
let locale = tf.feature('dateType').getLocale(colIndex);
let comparer = dateSortAsc;
let comparer = isSortDesc ? dateSortDesc : dateSortAsc;
compareFn = sortDateStr(comparer, locale);
} else { // string
compareFn = caseSensitive ? undefined : ignoreCase;
if (isSortDesc) {
return options.sort(compareFn).reverse();
}
}
return options.sort(compareFn);

View File

@ -337,7 +337,7 @@ export class TableFilter {
this.onAfterFilter = defaultsFn(f.on_after_filter, EMPTY_FN);
/**
* Enable/disable case sensitivity filtering
* Enable/disable case sensitivity for filtering, default false
* @type {Boolean}
*/
this.caseSensitive = Boolean(f.case_sensitive);
@ -534,38 +534,24 @@ export class TableFilter {
* by default globally or on a column basis
* @type {Boolean|Array}
*/
this.sortSlc = isUndef(f.sort_select) ? true :
isArray(f.sort_select) ? f.sort_select : Boolean(f.sort_select);
this.sortSlc = isUndef(f.sort_select)
? true
: defaultsArr(f.sort_select, Boolean(f.sort_select));
/**
* Indicate whether options in drop-down filter types are sorted in a
* ascending numeric manner
* @type {Boolean}
* @private
*/
this.isSortNumAsc = Boolean(f.sort_num_asc);
/**
* List of columns implementing options sorting in a ascending numeric
* manner
* List of columns implementing filter options sorting in ascending
* manner based on column data type
* @type {Array}
*/
this.sortNumAsc = this.isSortNumAsc ? f.sort_num_asc : [];
this.sortFilterOptionsAsc = defaultsArr(f.sort_filter_options_asc, []);
/**
* Indicate whether options in drop-down filter types are sorted in a
* descending numeric manner
* @type {Boolean}
* @private
*/
this.isSortNumDesc = Boolean(f.sort_num_desc);
/**
* List of columns implementing options sorting in a descending numeric
* manner
* List of columns implementing filter options sorting in descending
* manner based on column data type
* @type {Array}
*/
this.sortNumDesc = this.isSortNumDesc ? f.sort_num_desc : [];
this.sortFilterOptionsDesc =
defaultsArr(f.sort_filter_options_desc, []);
/**
* Indicate whether drop-down filter types are populated on demand at

View File

@ -100,19 +100,43 @@ test('Can sort options', function() {
tf.destroy();
tf = new TableFilter('demo', {
base_path: '../dist/tablefilter/',
col_0: 'checklist',
col_1: 'checklist',
col_2: 'checklist',
col_3: 'checklist',
col_4: 'checklist',
col_types: ['string', 'string', 'number', 'number', 'number'],
sort_num_asc: [2, 3],
sort_num_desc: [4]
sort_filter_options_asc: [0, 2, 3],
sort_filter_options_desc: [1, 4]
});
tf.init();
var flt0 = id(tf.fltIds[0]);
var flt1 = id(tf.fltIds[1]);
var flt2 = id(tf.fltIds[2]);
var flt3 = id(tf.fltIds[3]);
var flt4 = id(tf.fltIds[4]);
deepEqual(
flt0.getElementsByTagName('li')[1].firstChild.firstChild.value,
'Adelaide',
'First option value for column 0'
);
deepEqual(
flt0.getElementsByTagName('li')[2].firstChild.firstChild.value,
'Sydney',
'Last option value for column 0'
);
deepEqual(
flt1.getElementsByTagName('li')[1].firstChild.firstChild.value,
'Perth',
'First option value for column 1'
);
deepEqual(
flt1.getElementsByTagName('li')[6].firstChild.firstChild.value,
'Adelaide',
'Last option value for column 1'
);
deepEqual(
flt2.getElementsByTagName('li')[1].firstChild.firstChild.value,
'286',

View File

@ -1,4 +1,6 @@
(function(win, TableFilter){
(function(TableFilter) {
var id = function (id) { return document.getElementById(id); };
// TODO: add sort to test it with different column types
var tf = new TableFilter('demo', {
base_path: '../dist/tablefilter/',
@ -17,7 +19,6 @@
]
});
tf.init();
window.tf = tf;
module('Sanity checks');
test('Data types', function() {
@ -300,10 +301,92 @@
deepEqual(result, '.', 'Decimal separator for given column');
});
module('Data types filters options sorting');
test('Can sort date types', function () {
// setup
tf.clearFilters();
tf.destroy();
tf = new TableFilter('demo', {
base_path: '../dist/tablefilter/',
col_6: 'checklist',
col_7: 'multiple',
col_8: 'checklist',
col_10: 'select',
col_types: [
null, null, null,
{type: 'formatted-number', decimal: ',', thousands: ','},
'formatted-number', null,
{type: 'date', locale: 'fr',},
{type: 'date', locale: 'en', format: '{dd}-{MM}-{yyyy|yy}'},
{
type: 'date', locale: 'en',
format: ['{dd}-{months}-{yyyy|yy}']
},
'IpAddress',
{
type: 'date', locale: 'en',
format: ['{yyyy|yy}-{MM}-{dd} {HH}:{mm}:{ss}']
}
],
sort_filter_options_asc: [6, 7],
sort_filter_options_desc: [8, 10]
});
// act
tf.init();
var flt6 = id(tf.fltIds[6]);
var flt7 = id(tf.fltIds[7]);
var flt8 = id(tf.fltIds[8]);
var flt10 = id(tf.fltIds[10]);
// assert
deepEqual(
flt6.getElementsByTagName('li')[1].firstChild.firstChild.value,
'19/1/1984',
'First option value for column 6'
);
deepEqual(
flt6.getElementsByTagName('li')[20].firstChild.firstChild.value,
'3/7/2002',
'Last option value for column 6'
);
deepEqual(
flt7.options[1].value,
'1/19/1984',
'First option value for column 7'
);
deepEqual(
flt7.options[20].value,
'7/3/2002',
'Last option value for column 7'
);
deepEqual(
flt8.getElementsByTagName('li')[1].firstChild.firstChild.value,
'3-Jul-2002',
'First option value for column 8'
);
deepEqual(
flt8.getElementsByTagName('li')[20].firstChild.firstChild.value,
'19-Jan-1984',
'Last option value for column 8'
);
deepEqual(
flt10.options[1].value,
'03-11-21 12:02:04',
'First option value for column 10'
);
deepEqual(
flt10.options[19].value,
'1899-11-27 02:02:04',
'Last option value for column 10'
);
});
module('Tear-down');
test('can destroy TableFilter DOM elements', function() {
tf.destroy();
deepEqual(tf.isInitialized(), false, 'Filters removed');
});
})(window, TableFilter);
})(TableFilter);

View File

@ -157,24 +157,31 @@ test('Can enable options sorting on a column basis', function() {
deepEqual(flt4.options[7].value, '40', 'Last option value for column 4');
});
test('Can sort numeric options in asc and desc manner', function() {
test('Can sort options in asc and desc manner', function() {
tf.clearFilters();
tf.destroy();
tf = new TableFilter('demo', {
base_path: '../dist/tablefilter/',
col_0: 'select',
col_2: 'multiple',
col_3: 'select',
col_4: 'multiple',
col_types: ['string', 'string', 'number', 'number', 'number'],
sort_num_asc: [2, 3],
sort_num_desc: [4]
case_sensitive: true,
sort_filter_options_asc: [2, 3],
sort_filter_options_desc: [0, 4]
});
tf.init();
var flt0 = id(tf.fltIds[0]);
var flt2 = id(tf.fltIds[2]);
var flt3 = id(tf.fltIds[3]);
var flt4 = id(tf.fltIds[4]);
deepEqual(flt0.options[1].value, 'Sydney',
'First option value for column 0');
deepEqual(flt0.options[2].value, 'Adelaide',
'Last option value for column 0');
deepEqual(flt2.options[1].value, '286', 'First option value for column 2');
deepEqual(flt2.options[7].value, '2781', 'Last option value for column 2');
deepEqual(flt3.options[1].value, '.6', 'First option value for column 3');