From 2ccb014d9e4abe988e139929100b6e529b47696e Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Wed, 29 May 2019 00:45:35 +1000 Subject: [PATCH] FINALLY sorting is working well - Wrote a custom sorter which takes group rows into account --- .../bootstrap/bootstrap-table-group-by.js | 32 ++++++--- InvenTree/static/script/inventree/stock.js | 9 +-- InvenTree/static/script/inventree/tables.js | 71 +++++++++++++++++++ 3 files changed, 100 insertions(+), 12 deletions(-) diff --git a/InvenTree/static/script/bootstrap/bootstrap-table-group-by.js b/InvenTree/static/script/bootstrap/bootstrap-table-group-by.js index fd65e6b560..0f11c4c98d 100644 --- a/InvenTree/static/script/bootstrap/bootstrap-table-group-by.js +++ b/InvenTree/static/script/bootstrap/bootstrap-table-group-by.js @@ -64,19 +64,19 @@ _initBody = BootstrapTable.prototype.initBody, _updateSelected = BootstrapTable.prototype.updateSelected; + function isNumeric(n) { + return !isNaN(parseFloat(n)) && isFinite(n); + } + BootstrapTable.prototype.initSort = function () { _initSort.apply(this, Array.prototype.slice.apply(arguments)); var that = this; tableGroups = []; - if (this.options.groupBy && this.options.groupByField !== '') { + /* Sort the items into groups */ - if (this.options.sortName != this.options.groupByField) { - this.data.sort(function (a, b) { - return a[that.options.groupByField] == b[that.options.groupByField]; - }); - } + if (this.options.groupBy && this.options.groupByField !== '') { var that = this; var groups = groupBy(that.data, function (item) { @@ -96,7 +96,14 @@ item._data = {}; } - item._data['parent-index'] = index; + if (value.length > 1) { + item._data['parent-index'] = index; + } else { + item._data['parent-index'] = null; + } + + item._data['group-data'] = value; + item._data['table'] = that; }); index++; @@ -148,7 +155,7 @@ var cell = ''; if (typeof that.options.groupByFormatter == 'function') { - cell += '' + that.options.groupByFormatter(col.title, item.id, item.data) + ""; + cell += '' + that.options.groupByFormatter(col.field, item.id, item.data) + ""; } cell += ""; @@ -175,6 +182,15 @@ that.$body.find('tr[data-parent-index=' + item.id + ']').addClass('hidden stock-sub-group'); that.$body.find('tr[data-parent-index=' + item.id + ']:first').before($(html.join(''))); + + var group_header = that.$body.find('tr[data-group-index=' + item.id + ']'); + + // Ensure all the sub-items are in the right place... + + that.$body.find('tr[data-parent-index=' + item.id + ']').each(function() { + $(this).detach(); + group_header.after(this); + }); } }); diff --git a/InvenTree/static/script/inventree/stock.js b/InvenTree/static/script/inventree/stock.js index 5794333ae8..8fd121c23e 100644 --- a/InvenTree/static/script/inventree/stock.js +++ b/InvenTree/static/script/inventree/stock.js @@ -387,13 +387,14 @@ function loadStockTable(table, options) { formatNoMatches: function() { return 'No stock items matching query'; }, + customSort: customGroupSorter, groupBy: true, groupByField: options.groupByField || 'part', groupByFormatter: function(field, id, data) { var row = data[0]; - if (field == 'Part') { + if (field == 'part__name') { var name = row.part__IPN; @@ -405,10 +406,10 @@ function loadStockTable(table, options) { return imageHoverIcon(row.part__image) + name + ' (' + data.length + ' items)'; } - else if (field == 'Description') { + else if (field == 'part__description') { return row.part__description; } - else if (field == 'Stock') { + else if (field == 'quantity') { var stock = 0; data.forEach(function(item) { @@ -416,7 +417,7 @@ function loadStockTable(table, options) { }); return stock; - } else if (field == 'Location') { + } else if (field == 'location__path') { /* Determine how many locations */ var locations = []; diff --git a/InvenTree/static/script/inventree/tables.js b/InvenTree/static/script/inventree/tables.js index 979a7d5a21..59bc446d5e 100644 --- a/InvenTree/static/script/inventree/tables.js +++ b/InvenTree/static/script/inventree/tables.js @@ -37,3 +37,74 @@ function linkButtonsToSelection(table, buttons) { enableButtons(buttons, table.bootstrapTable('getSelections').length > 0); }); } + + +function isNumeric(n) { + return !isNaN(parseFloat(n)) && isFinite(n); +} + + +function customGroupSorter(sortName, sortOrder, sortData) { + + console.log('got here'); + + var order = sortOrder === 'desc' ? -1 : 1; + + sortData.sort(function(a, b) { + + // Extract default field values + var aa = a[sortName]; + var bb = b[sortName]; + + // Extract parent information + var aparent = a._data && a._data['parent-index']; + var bparent = b._data && b._data['parent-index']; + + // If either of the comparisons are in a group + if (aparent || bparent) { + + // If the parents are different (or one item does not have a parent, + // then we need to extract the parent value for the selected column. + + if (aparent != bparent) { + if (aparent) { + aa = a._data['table'].options.groupByFormatter(sortName, 0, a._data['group-data']); + } + + if (bparent) { + bb = b._data['table'].options.groupByFormatter(sortName, 0, b._data['group-data']); + } + } + } + + if (aa === undefined || aa === null) { + aa = ''; + } + if (bb === undefined || bb === null) { + bb = ''; + } + + if (isNumeric(aa) && isNumeric(bb)) { + if (aa < bb) { + return order * -1; + } else if (aa > bb) { + return order; + } else { + return 0; + } + } + + aa = aa.toString(); + bb = bb.toString(); + + var cmp = aa.localeCompare(bb); + + if (cmp === -1) { + return order * -1; + } else if (cmp === 1) { + return order; + } else { + return 0; + } + }); +} \ No newline at end of file