diff --git a/__test__/sort.test.js b/__test__/sort.test.js index c30503f8..5f5364af 100644 --- a/__test__/sort.test.js +++ b/__test__/sort.test.js @@ -184,19 +184,19 @@ describe('Sort', function () { expect(list.items[5].values().val).toBe('my.string_41299.tif') }) it('should show order of sorted floates (a bit wrong)', function () { - i1.values({ val: '10.0401' }) - i2.values({ val: '10.022' }) - i3.values({ val: '10.021999' }) - i4.values({ val: '11.231' }) - i5.values({ val: '0003.123' }) - i6.values({ val: '09.2123' }) + i1.values({ val: '0.5' }) + i2.values({ val: '0.26' }) + i3.values({ val: '0.040' }) + i4.values({ val: '0.50' }) + i5.values({ val: '0.500' }) + i6.values({ val: '0.3' }) list.sort('val', { order: 'asc' }) - expect(list.items[0].values().val).toBe('0003.123') - expect(list.items[1].values().val).toBe('09.2123') - expect(list.items[2].values().val).toBe('10.022') - expect(list.items[3].values().val).toBe('10.0401') - expect(list.items[4].values().val).toBe('10.021999') - expect(list.items[5].values().val).toBe('11.231') + expect(list.items[0].values().val).toBe('0.040') + expect(list.items[1].values().val).toBe('0.26') + expect(list.items[2].values().val).toBe('0.3') + expect(list.items[3].values().val).toBe('0.5') + expect(list.items[4].values().val).toBe('0.50') + expect(list.items[5].values().val).toBe('0.500') }) it('should sort IP addresses', function () { i1.values({ val: '192.168.1.1' }) diff --git a/src/sort.js b/src/sort.js index 4e4b415f..58dde0d9 100644 --- a/src/sort.js +++ b/src/sort.js @@ -45,11 +45,30 @@ module.exports = function (list) { }, } + function isFloatString(value) { + if (value === undefined || value === null || !value || typeof value !== 'string' || value.split(".").length !== 2) { + return false + } + + return !Number.isInteger(parseFloat(value)) + } + + function getFloatingPointLength(value) { + return value.split(".")[1].length + } + + function getMaxFloatingPointLengthFromItems(itemA, itemB) { + const itemAFloatingNumberLength = getFloatingPointLength(itemA) + const itemBFloatingNumberLength = getFloatingPointLength(itemB) + + return Math.max(itemAFloatingNumberLength, itemBFloatingNumberLength) + } + var sort = function () { list.trigger('sortStart') var options = {} - var target = arguments[0].currentTarget || arguments[0].srcElement || undefined + var target = arguments[0].currentTarget || arguments[0].srcElement || undefined // arg[0] : val, arg[1] : { order: 'asc' } if (target) { options.valueName = list.utils.getAttribute(target, 'data-sort') @@ -68,8 +87,8 @@ module.exports = function (list) { // caseInsensitive // alphabet var customSortFunction = options.sortFunction || list.sortFunction || null, - multi = options.order === 'desc' ? -1 : 1, - sortFunction + multi = options.order === 'desc' ? -1 : 1, + sortFunction if (customSortFunction) { sortFunction = function (itemA, itemB) { @@ -82,7 +101,19 @@ module.exports = function (list) { if (!sort.alphabet && options.insensitive) { sort = list.utils.naturalSort.caseInsensitive } - return sort(itemA.values()[options.valueName], itemB.values()[options.valueName]) * multi + + const itemAValue = itemA.values()[options.valueName] + const itemBValue = itemB.values()[options.valueName] + if (isFloatString(itemAValue) && isFloatString(itemBValue)) { + const multiplier = 10 ** getMaxFloatingPointLengthFromItems(itemAValue, itemBValue) // multiply by max length for making float to integer + + const valueA = (parseInt(parseFloat(itemAValue) * multiplier)).toString() + const valueB = (parseInt(parseFloat(itemBValue) * multiplier)).toString() + + return sort(valueA, valueB) * multi + } + + return sort(itemAValue, itemBValue) * multi } }