From 7e632d00ed281522aabeeeef7bf181a77642cd72 Mon Sep 17 00:00:00 2001 From: Ian Witherow Date: Tue, 22 Jan 2019 17:02:54 -0700 Subject: [PATCH] Simpler way of sorting empty/null values to the bottom. Adds support for es6 import syntax. --- README.md | 1 - dist/react-filterable-table.js | 55 +++++++++--------------------- package.json | 2 +- src/Components/FilterableTable.jsx | 2 -- src/Helpers/FilterAndSort.js | 47 ++++++------------------- src/index.js | 4 ++- 6 files changed, 30 insertions(+), 81 deletions(-) diff --git a/README.md b/README.md index 4f7fab5..bf47992 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/dist/react-filterable-table.js b/dist/react-filterable-table.js index c3db45a..d331ca9 100644 --- a/dist/react-filterable-table.js +++ b/dist/react-filterable-table.js @@ -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 */ @@ -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 }); @@ -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] }; @@ -1091,7 +1094,6 @@ return /******/ (function(modules) { // webpackBootstrap var filter = options.filter, exactFilters = options.exactFilters, sortFields = options.sortFields, - stickySorting = options.stickySorting, fields = options.fields; @@ -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) }; }(); @@ -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 || {}; @@ -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; diff --git a/package.json b/package.json index 83baa74..272b4c7 100644 --- a/package.json +++ b/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": { diff --git a/src/Components/FilterableTable.jsx b/src/Components/FilterableTable.jsx index 5c044c0..c595ed4 100644 --- a/src/Components/FilterableTable.jsx +++ b/src/Components/FilterableTable.jsx @@ -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] } @@ -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 }); diff --git a/src/Helpers/FilterAndSort.js b/src/Helpers/FilterAndSort.js index d45c23f..1c753f0 100644 --- a/src/Helpers/FilterAndSort.js +++ b/src/Helpers/FilterAndSort.js @@ -7,7 +7,6 @@ function FilterAndSort(array, options) { filter, exactFilters, sortFields, - stickySorting, fields } = options; @@ -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 || {}; @@ -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; diff --git a/src/index.js b/src/index.js index a40a5d2..2f909b1 100644 --- a/src/index.js +++ b/src/index.js @@ -1 +1,3 @@ -module.exports = require('./Components/FilterableTable.jsx'); +const FilterableTable = require('./Components/FilterableTable.jsx'); +module.exports = FilterableTable; +export { FilterableTable };