Skip to content

Commit

Permalink
Simpler way of sorting empty/null values to the bottom. Adds support …
Browse files Browse the repository at this point in the history
…for es6 import syntax.
  • Loading branch information
Ian Witherow committed Jan 23, 2019
1 parent 6f431db commit 7e632d0
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 81 deletions.
1 change: 0 additions & 1 deletion README.md
Expand Up @@ -58,7 +58,6 @@ const fields = [
* `iconSortedDesc` - `object` - Element to use for the desc sort icon next to a field name. If not provided, the default uses icons from FontAwesome.
* `initialSort` - `string` - The field name on which to sort on initially
* `initialSortDir` - `bool` - The sort direction to use initially - true is ascending, false is descending. Default: `true`
* `stickySorting` - `bool` - If true, empty values will always sort to the bottom. Default: `false`
* `noRecordsMessage` - `string` - Message to show when there are no records
* `noFilteredRecordsMessage` - `string` - Message to show when the user has applied filters which result in no records to show
* `serverErrorMessage` - `string` or `object` - Message to show when an error is encountered from the `dataEndpoint` (if used). Can be a string or a React component
Expand Down
55 changes: 16 additions & 39 deletions dist/react-filterable-table.js
Expand Up @@ -63,7 +63,12 @@ return /******/ (function(modules) { // webpackBootstrap

'use strict';

module.exports = __webpack_require__(2);
Object.defineProperty(exports, "__esModule", {
value: true
});
var FilterableTable = __webpack_require__(2);
module.exports = FilterableTable;
exports.FilterableTable = FilterableTable;

/***/ },
/* 2 */
Expand Down Expand Up @@ -418,7 +423,6 @@ return /******/ (function(modules) { // webpackBootstrap
filter: this.state.filter,
exactFilters: this.state.exactFilters,
sortFields: this.state.sortFields,
stickySorting: this.props.stickySorting,
fields: fields
});

Expand Down Expand Up @@ -502,7 +506,6 @@ return /******/ (function(modules) { // webpackBootstrap
return {
noRecordsMessage: "There are no records to display",
noFilteredRecordsMessage: "There are no records to display",
stickySorting: false,
tableClassName: "table table-condensed table-hover filterable-table",
pageSizes: [10, 20, 30, 50]
};
Expand Down Expand Up @@ -1091,7 +1094,6 @@ return /******/ (function(modules) { // webpackBootstrap
var filter = options.filter,
exactFilters = options.exactFilters,
sortFields = options.sortFields,
stickySorting = options.stickySorting,
fields = options.fields;


Expand Down Expand Up @@ -1134,7 +1136,7 @@ return /******/ (function(modules) { // webpackBootstrap
sortKeys[field.name] = field.reverse ? "desc" : "asc";
});
return {
v: MultiSort(records, sortKeys, stickySorting)
v: MultiSort(records, sortKeys)
};
}();

Expand All @@ -1143,35 +1145,8 @@ return /******/ (function(modules) { // webpackBootstrap
return records;
}

// Push empty values to the bottom, regardless of sort direction
function StickySortValues(recordA, recordB, reverse) {
if (typeof recordA === "string" || typeof recordB === "string") {
// If desc, set it to 0 so it ends up at the end.
// If asc, set to a bunch of zzzz so it ends up at the end.
var emptySortCompare = reverse ? "0" : "zzzzzzzzzzzz";
// For strings, set both to lowercase for comparison
recordA = hasValue(recordA) ? recordA.toString().toLowerCase() : emptySortCompare;
recordB = hasValue(recordB) ? recordB.toString().toLowerCase() : emptySortCompare;
} else if (hasValue(recordA) && typeof recordA.getMonth === "function" || hasValue(recordB) && typeof recordB.getMonth === "function") {
// For dates, we'll need different "emptySortCompare" values
// If desc, set to some really early date, like 1/1/1000.
// If asc, set to some really late date, like 1/1/2999.
var _emptySortCompare = reverse ? new Date("1/1/1000") : new Date("1/1/2999");
recordA = hasValue(recordA) ? recordA : _emptySortCompare;
recordB = hasValue(recordB) ? recordB : _emptySortCompare;
} else if (typeof recordA === "number" || typeof recordB === "number") {
// If desc, set to negative infinity
// If asc, set to positive infinity
var _emptySortCompare2 = reverse ? -Infinity : Infinity;
recordA = hasValue(recordA) ? recordA : _emptySortCompare2;
recordB = hasValue(recordB) ? recordB : _emptySortCompare2;
}

return { a: recordA, b: recordB };
}

// Adapted from: https://stackoverflow.com/questions/2784230/how-do-you-sort-an-array-on-multiple-columns#answer-15668310
function MultiSort(array, keys, stickySort) {
function MultiSort(array, keys) {

keys = keys || {};

Expand All @@ -1193,17 +1168,19 @@ return /******/ (function(modules) { // webpackBootstrap
var keySort = function keySort(a, b, d) {
d = d !== null ? d : 1;

if (stickySort) {
var sortDirection = d === -1;
var stickyValues = StickySortValues(a, b, sortDirection);
a = stickyValues.a;
b = stickyValues.b;
}
a = hasValue(a) ? a : null;
b = hasValue(b) ? b : null;

// force any string values to lowercase
a = typeof a === 'string' ? a.toLowerCase() : a;
b = typeof b === 'string' ? b.toLowerCase() : b;

if (a === null) {
return 1;
}
if (b === null) {
return -1;
}
// Return either 1 or -1 *d to indicate a sort priority. d is sort direction
if (a > b) {
return 1 * d;
Expand Down
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "react-filterable-table",
"version": "0.3.432",
"version": "0.3.433",
"description": "Extendable table with filtering, sorting, paging, and more",
"main": "dist/react-filterable-table.js",
"scripts": {
Expand Down
2 changes: 0 additions & 2 deletions src/Components/FilterableTable.jsx
Expand Up @@ -43,7 +43,6 @@ class FilterableTable extends React.Component {
return {
noRecordsMessage: "There are no records to display",
noFilteredRecordsMessage: "There are no records to display",
stickySorting: false,
tableClassName: "table table-condensed table-hover filterable-table",
pageSizes: [10, 20, 30, 50]
}
Expand Down Expand Up @@ -298,7 +297,6 @@ class FilterableTable extends React.Component {
filter: this.state.filter,
exactFilters: this.state.exactFilters,
sortFields: this.state.sortFields,
stickySorting: this.props.stickySorting,
fields: fields
});

Expand Down
47 changes: 10 additions & 37 deletions src/Helpers/FilterAndSort.js
Expand Up @@ -7,7 +7,6 @@ function FilterAndSort(array, options) {
filter,
exactFilters,
sortFields,
stickySorting,
fields
} = options;

Expand Down Expand Up @@ -51,41 +50,13 @@ function FilterAndSort(array, options) {
sortFields.forEach(field => {
sortKeys[field.name] = (field.reverse) ? "desc" : "asc";
});
return MultiSort(records, sortKeys, stickySorting);
return MultiSort(records, sortKeys);
}
return records;
}

// Push empty values to the bottom, regardless of sort direction
function StickySortValues(recordA, recordB, reverse) {
if (typeof recordA === "string" || typeof recordB === "string") {
// If desc, set it to 0 so it ends up at the end.
// If asc, set to a bunch of zzzz so it ends up at the end.
let emptySortCompare = reverse ? "0" : "zzzzzzzzzzzz";
// For strings, set both to lowercase for comparison
recordA = hasValue(recordA) ? recordA.toString().toLowerCase() : emptySortCompare;
recordB = hasValue(recordB) ? recordB.toString().toLowerCase() : emptySortCompare;
} else if ((hasValue(recordA) && typeof recordA.getMonth === "function") || (hasValue(recordB) && typeof recordB.getMonth === "function")) {
// For dates, we'll need different "emptySortCompare" values
// If desc, set to some really early date, like 1/1/1000.
// If asc, set to some really late date, like 1/1/2999.
let emptySortCompare = reverse ? new Date("1/1/1000") : new Date("1/1/2999");
recordA = hasValue(recordA) ? recordA : emptySortCompare;
recordB = hasValue(recordB) ? recordB : emptySortCompare;
} else if (typeof recordA === "number" || typeof recordB === "number") {
// If desc, set to negative infinity
// If asc, set to positive infinity
let emptySortCompare = reverse ? -Infinity : Infinity;
recordA = hasValue(recordA) ? recordA : emptySortCompare;
recordB = hasValue(recordB) ? recordB : emptySortCompare;
}

return { a: recordA, b: recordB };
}


// Adapted from: https://stackoverflow.com/questions/2784230/how-do-you-sort-an-array-on-multiple-columns#answer-15668310
function MultiSort(array, keys, stickySort) {
function MultiSort(array, keys) {

keys = keys || {};

Expand All @@ -107,17 +78,19 @@ function MultiSort(array, keys, stickySort) {
var keySort = function(a, b, d) {
d = d !== null ? d : 1;

if (stickySort) {
let sortDirection = d === -1;
let stickyValues = StickySortValues(a, b, sortDirection);
a = stickyValues.a;
b = stickyValues.b;
}
a = (hasValue(a)) ? a : null;
b = (hasValue(b)) ? b : null;

// force any string values to lowercase
a = typeof a === 'string' ? a.toLowerCase() : a;
b = typeof b === 'string' ? b.toLowerCase() : b;

if (a === null) {
return 1;
}
if (b === null) {
return -1;
}
// Return either 1 or -1 *d to indicate a sort priority. d is sort direction
if (a > b) {
return 1 * d;
Expand Down
4 changes: 3 additions & 1 deletion src/index.js
@@ -1 +1,3 @@
module.exports = require('./Components/FilterableTable.jsx');
const FilterableTable = require('./Components/FilterableTable.jsx');
module.exports = FilterableTable;
export { FilterableTable };

0 comments on commit 7e632d0

Please sign in to comment.