1
0
Fork 0
mirror of https://github.com/koalyptus/TableFilter.git synced 2024-04-24 19:20:40 +02:00

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: { coverage: {
disposeCollector: true, disposeCollector: true,
src: ['dist/tablefilter/*.js'], src: ['dist/tablefilter/*.js'],
instrumentedFiles: 'temp/', instrumentedFiles: 'report/temp/',
htmlReport: 'report/coverage', htmlReport: 'report/coverage',
coberturaReport: 'report/', coberturaReport: 'report/',
lcovReport: 'report/', lcovReport: 'report/',

4
dist/starter.html vendored
View file

@ -1,10 +1,10 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<title>tablefilter v0.6.93 - Starter</title> <title>tablefilter v0.6.94 - Starter</title>
</head> </head>
<body> <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", "name": "tablefilter",
"version": "0.6.93", "version": "0.6.94",
"description": "A Javascript library making HTML tables filterable and a bit more", "description": "A Javascript library making HTML tables filterable and a bit more",
"license": "MIT", "license": "MIT",
"author": { "author": {

View file

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

View file

@ -337,7 +337,7 @@ export class TableFilter {
this.onAfterFilter = defaultsFn(f.on_after_filter, EMPTY_FN); this.onAfterFilter = defaultsFn(f.on_after_filter, EMPTY_FN);
/** /**
* Enable/disable case sensitivity filtering * Enable/disable case sensitivity for filtering, default false
* @type {Boolean} * @type {Boolean}
*/ */
this.caseSensitive = Boolean(f.case_sensitive); this.caseSensitive = Boolean(f.case_sensitive);
@ -534,38 +534,24 @@ export class TableFilter {
* by default globally or on a column basis * by default globally or on a column basis
* @type {Boolean|Array} * @type {Boolean|Array}
*/ */
this.sortSlc = isUndef(f.sort_select) ? true : this.sortSlc = isUndef(f.sort_select)
isArray(f.sort_select) ? f.sort_select : Boolean(f.sort_select); ? true
: defaultsArr(f.sort_select, Boolean(f.sort_select));
/** /**
* Indicate whether options in drop-down filter types are sorted in a * List of columns implementing filter options sorting in ascending
* ascending numeric manner * manner based on column data type
* @type {Boolean}
* @private
*/
this.isSortNumAsc = Boolean(f.sort_num_asc);
/**
* List of columns implementing options sorting in a ascending numeric
* manner
* @type {Array} * @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 * List of columns implementing filter options sorting in descending
* descending numeric manner * manner based on column data type
* @type {Boolean}
* @private
*/
this.isSortNumDesc = Boolean(f.sort_num_desc);
/**
* List of columns implementing options sorting in a descending numeric
* manner
* @type {Array} * @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 * 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.destroy();
tf = new TableFilter('demo', { tf = new TableFilter('demo', {
base_path: '../dist/tablefilter/', base_path: '../dist/tablefilter/',
col_0: 'checklist',
col_1: 'checklist',
col_2: 'checklist', col_2: 'checklist',
col_3: 'checklist', col_3: 'checklist',
col_4: 'checklist', col_4: 'checklist',
col_types: ['string', 'string', 'number', 'number', 'number'], col_types: ['string', 'string', 'number', 'number', 'number'],
sort_num_asc: [2, 3], sort_filter_options_asc: [0, 2, 3],
sort_num_desc: [4] sort_filter_options_desc: [1, 4]
}); });
tf.init(); tf.init();
var flt0 = id(tf.fltIds[0]);
var flt1 = id(tf.fltIds[1]);
var flt2 = id(tf.fltIds[2]); var flt2 = id(tf.fltIds[2]);
var flt3 = id(tf.fltIds[3]); var flt3 = id(tf.fltIds[3]);
var flt4 = id(tf.fltIds[4]); 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( deepEqual(
flt2.getElementsByTagName('li')[1].firstChild.firstChild.value, flt2.getElementsByTagName('li')[1].firstChild.firstChild.value,
'286', '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 // TODO: add sort to test it with different column types
var tf = new TableFilter('demo', { var tf = new TableFilter('demo', {
base_path: '../dist/tablefilter/', base_path: '../dist/tablefilter/',
@ -17,7 +19,6 @@
] ]
}); });
tf.init(); tf.init();
window.tf = tf;
module('Sanity checks'); module('Sanity checks');
test('Data types', function() { test('Data types', function() {
@ -300,10 +301,92 @@
deepEqual(result, '.', 'Decimal separator for given column'); 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'); module('Tear-down');
test('can destroy TableFilter DOM elements', function() { test('can destroy TableFilter DOM elements', function() {
tf.destroy(); tf.destroy();
deepEqual(tf.isInitialized(), false, 'Filters removed'); 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'); 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.clearFilters();
tf.destroy(); tf.destroy();
tf = new TableFilter('demo', { tf = new TableFilter('demo', {
base_path: '../dist/tablefilter/', base_path: '../dist/tablefilter/',
col_0: 'select',
col_2: 'multiple', col_2: 'multiple',
col_3: 'select', col_3: 'select',
col_4: 'multiple', col_4: 'multiple',
col_types: ['string', 'string', 'number', 'number', 'number'], col_types: ['string', 'string', 'number', 'number', 'number'],
sort_num_asc: [2, 3], case_sensitive: true,
sort_num_desc: [4] sort_filter_options_asc: [2, 3],
sort_filter_options_desc: [0, 4]
}); });
tf.init(); tf.init();
var flt0 = id(tf.fltIds[0]);
var flt2 = id(tf.fltIds[2]); var flt2 = id(tf.fltIds[2]);
var flt3 = id(tf.fltIds[3]); var flt3 = id(tf.fltIds[3]);
var flt4 = id(tf.fltIds[4]); 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[1].value, '286', 'First option value for column 2');
deepEqual(flt2.options[7].value, '2781', 'Last 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'); deepEqual(flt3.options[1].value, '.6', 'First option value for column 3');