public inbox for [email protected]help / color / mirror / Atom feed
[pgAdmin4][Patch]: RM1938 - Backgrid sorting not working for Integer/Number types 3+ messages / 2 participants [nested] [flat]
* [pgAdmin4][Patch]: RM1938 - Backgrid sorting not working for Integer/Number types @ 2017-01-06 08:50 Surinder Kumar <[email protected]> 0 siblings, 1 reply; 3+ messages in thread From: Surinder Kumar @ 2017-01-06 08:50 UTC (permalink / raw) To: pgadmin-hackers Hi, As the type of data we get from server side is of string type, due to which the sorting for Integer/Number type columns is not working. To fix this issue, we are using BigNumber JS library. We are overriding Backgrid's sort and make_comparator method in backgrid.pgadmin.js. When sorting is performed based on column we identify the column type(integer/number) and then convert its value into BigInteger and the sorts data. This patch is dependent on patch sent for "Adding support for BigNumber JS library". Also, thanks to Murtuza for help. Please find attached patch and review. Thanks, Surinder Kumar -- Sent via pgadmin-hackers mailing list ([email protected]) To make changes to your subscription: http://www.postgresql.org/mailpref/pgadmin-hackers Attachments: [application/octet-stream] RM1938.patch (6.2K, 3-RM1938.patch) download | inline diff: diff --git a/web/pgadmin/static/js/backgrid/backgrid.pgadmin.js b/web/pgadmin/static/js/backgrid/backgrid.pgadmin.js index 5fee3b9..8e9d5e3 100644 --- a/web/pgadmin/static/js/backgrid/backgrid.pgadmin.js +++ b/web/pgadmin/static/js/backgrid/backgrid.pgadmin.js @@ -3,12 +3,12 @@ if (typeof define === 'function' && define.amd) { define([ 'underscore', 'jquery', 'backbone', 'backform', 'backgrid', 'alertify', - 'moment', 'bootstrap.datetimepicker' + 'moment', 'bignumber', 'bootstrap.datetimepicker' ], - function(_, $, Backbone, Backform, Backgrid, Alertify, moment) { + function(_, $, Backbone, Backform, Backgrid, Alertify, moment, BigNumber) { // Export global even in AMD case in case this script is loaded with // others that may still expect a global Backform. - return factory(root, _, $, Backbone, Backform, Alertify, moment); + return factory(root, _, $, Backbone, Backform, Alertify, moment, BigNumber); }); // Next for Node.js or CommonJS. jQuery may not be needed as a module. @@ -25,7 +25,7 @@ } else { factory(root, root._, (root.jQuery || root.Zepto || root.ender || root.$), root.Backbone, root.Backform); } -} (this, function(root, _, $, Backbone, Backform, Alertify, moment) { +} (this, function(root, _, $, Backbone, Backform, Alertify, moment, BigNumber) { /* * Add mechanism in backgrid to render different types of cells in * same column; @@ -47,6 +47,114 @@ } }); + /* Overriding backgrid sort method. + * As we are getting numeric, integer values as string + * from server side, but on client side javascript truncates + * large numbers automatically due to which backgrid was unable + * to sort numeric values properly in the grid. + * To fix this issue, now we check if cell type is integer/number + * convert it into BigNumber object and make comparison to perform sorting. + */ + + _.extend(Backgrid.Body.prototype, { + sort: function (column, direction) { + + if (!_.contains(["ascending", "descending", null], direction)) { + throw new RangeError('direction must be one of "ascending", "descending" or `null`'); + } + + if (_.isString(column)) column = this.columns.findWhere({name: column}); + + var collection = this.collection; + + var order; + if (direction === "ascending") order = -1; + else if (direction === "descending") order = 1; + else order = null; + + // Get column type and pass it to comparator. + var col_type = column.get('cell').prototype.className || 'string-cell', + comparator = this.makeComparator(column.get("name"), order, + order ? + column.sortValue() : + function (model) { + return model.cid.replace('c', '') * 1; + }, col_type); + + if (Backbone.PageableCollection && + collection instanceof Backbone.PageableCollection) { + + collection.setSorting(order && column.get("name"), order, + {sortValue: column.sortValue()}); + + if (collection.fullCollection) { + // If order is null, pageable will remove the comparator on both sides, + // in this case the default insertion order comparator needs to be + // attached to get back to the order before sorting. + if (collection.fullCollection.comparator == null) { + collection.fullCollection.comparator = comparator; + } + collection.fullCollection.sort(); + collection.trigger("backgrid:sorted", column, direction, collection); + } + else collection.fetch({reset: true, success: function () { + collection.trigger("backgrid:sorted", column, direction, collection); + }}); + } + else { + collection.comparator = comparator; + collection.sort(); + collection.trigger("backgrid:sorted", column, direction, collection); + } + + column.set("direction", direction); + + return this; + }, + makeComparator: function (attr, order, func, type) { + + return function (left, right) { + // extract the values from the models + + var l = func(left, attr), r = func(right, attr), t; + + var types = ['number-cell', 'integer-cell']; + if (_.include(types, type)) { + var _l, _r; + // NaN if invalid number + try { + _l = new BigNumber(l); + } catch(err) { + _l = NaN; + } + + try { + _r = new BigNumber(r); + } catch(err) { + _r = NaN; + } + + if (_l.gt(_r)) // If left is greater than right + return 1 + else if (_l.lt(_r)) // If left is less than right + return -1 + else if (_l.eq(_r)) // If both are equals + return 0; + } + + // if descending order, swap left and right + if (order === 1) t = l, l = r, r = t; + + // compare as usual + if (l === r) return 0; + else if (l < r) return -1; + return 1; + }; + } + + + }); + _.extend(Backgrid.Row.prototype, { makeCell: function (column) { return new (this.getCell(column))({ diff --git a/web/pgadmin/templates/base.html b/web/pgadmin/templates/base.html index d78b0a6..9a12f34 100755 --- a/web/pgadmin/templates/base.html +++ b/web/pgadmin/templates/base.html @@ -183,6 +183,7 @@ 'pgadmin.backform': "{{ url_for('static', filename='js/backform.pgadmin') }}", "jquery.event.drag": "{{ url_for('static', filename='js/jquery-ui/jquery.event.drag-2.2') }}", "jquery.ui": "{{ url_for('static', filename='js/jquery-ui/jquery-ui-1.11.3' if config.DEBUG else 'js/jquery-ui/jquery-ui-1.11.3.min') }}", + "bignumber": "{{ url_for('static', filename='js/bignumber/bignumber' if config.DEBUG else 'js/bignumber/bignumber.min') }}", bean :"{{ url_for('static', filename='js/flotr2/' + ('bean' if config.DEBUG else 'bean-min')) }}", flotr2 :"{{ url_for('static', filename='js/flotr2/flotr2.amd') }}"{% for script in current_app.javascripts %}, '{{ script.name }}': "{{ script.path }}"{% endfor %} ^ permalink raw reply [nested|flat] 3+ messages in thread
* Re: [pgAdmin4][Patch]: RM1938 - Backgrid sorting not working for Integer/Number types @ 2017-01-09 10:12 Surinder Kumar <[email protected]> parent: Surinder Kumar <[email protected]> 0 siblings, 1 reply; 3+ messages in thread From: Surinder Kumar @ 2017-01-09 10:12 UTC (permalink / raw) To: Dave Page <[email protected]>; +Cc: pgadmin-hackers Hi Dave, I just missed the code for swapping left and right values if order is descending. It's fixed. Please find attached patch and review. On Mon, Jan 9, 2017 at 9:05 AM, Dave Page <[email protected]> wrote: > Hi > > On Friday, January 6, 2017, Surinder Kumar <surinder.kumar@enterprisedb. > com> wrote: > >> Hi, >> >> As the type of data we get from server side is of string type, due to >> which the sorting for Integer/Number type columns is not working. >> >> To fix this issue, we are using BigNumber JS library. >> We are overriding Backgrid's sort and make_comparator method in >> backgrid.pgadmin.js. >> >> When sorting is performed based on column we identify the column >> type(integer/number) and then convert its value into BigInteger and the >> sorts data. >> >> This patch is dependent on patch sent for "Adding support for BigNumber >> JS library". >> >> Also, thanks to Murtuza for help. >> >> Please find attached patch and review. >> > > This works fine for ascending sorts, but if i click the row header a > second time for a descending sort, the order isn't reversed as expected. > > Thanks, Dave. > > > -- > Dave Page > Blog: http://pgsnake.blogspot.com > Twitter: @pgsnake > > EnterpriseDB UK: http://www.enterprisedb.com > The Enterprise PostgreSQL Company > > -- Sent via pgadmin-hackers mailing list ([email protected]) To make changes to your subscription: http://www.postgresql.org/mailpref/pgadmin-hackers Attachments: [application/octet-stream] RM1938_v1.patch (6.2K, 3-RM1938_v1.patch) download | inline diff: diff --git a/web/pgadmin/static/js/backgrid/backgrid.pgadmin.js b/web/pgadmin/static/js/backgrid/backgrid.pgadmin.js index 1d2a3c4..82af5a6 100644 --- a/web/pgadmin/static/js/backgrid/backgrid.pgadmin.js +++ b/web/pgadmin/static/js/backgrid/backgrid.pgadmin.js @@ -3,12 +3,12 @@ if (typeof define === 'function' && define.amd) { define([ 'underscore', 'jquery', 'backbone', 'backform', 'backgrid', 'alertify', - 'moment', 'bootstrap.datetimepicker' + 'moment', 'bignumber', 'bootstrap.datetimepicker' ], - function(_, $, Backbone, Backform, Backgrid, Alertify, moment) { + function(_, $, Backbone, Backform, Backgrid, Alertify, moment, BigNumber) { // Export global even in AMD case in case this script is loaded with // others that may still expect a global Backform. - return factory(root, _, $, Backbone, Backform, Alertify, moment); + return factory(root, _, $, Backbone, Backform, Alertify, moment, BigNumber); }); // Next for Node.js or CommonJS. jQuery may not be needed as a module. @@ -25,7 +25,7 @@ } else { factory(root, root._, (root.jQuery || root.Zepto || root.ender || root.$), root.Backbone, root.Backform); } -} (this, function(root, _, $, Backbone, Backform, Alertify, moment) { +} (this, function(root, _, $, Backbone, Backform, Alertify, moment, BigNumber) { /* * Add mechanism in backgrid to render different types of cells in * same column; @@ -47,6 +47,107 @@ } }); + /* Overriding backgrid sort method. + * As we are getting numeric, integer values as string + * from server side, but on client side javascript truncates + * large numbers automatically due to which backgrid was unable + * to sort numeric values properly in the grid. + * To fix this issue, now we check if cell type is integer/number + * convert it into BigNumber object and make comparison to perform sorting. + */ + + _.extend(Backgrid.Body.prototype, { + sort: function (column, direction) { + + if (!_.contains(["ascending", "descending", null], direction)) { + throw new RangeError('direction must be one of "ascending", "descending" or `null`'); + } + + if (_.isString(column)) column = this.columns.findWhere({name: column}); + + var collection = this.collection; + + var order; + if (direction === "ascending") order = -1; + else if (direction === "descending") order = 1; + else order = null; + + // Get column type and pass it to comparator. + var col_type = column.get('cell').prototype.className || 'string-cell', + comparator = this.makeComparator(column.get("name"), order, + order ? + column.sortValue() : + function (model) { + return model.cid.replace('c', '') * 1; + }, col_type); + + if (Backbone.PageableCollection && + collection instanceof Backbone.PageableCollection) { + + collection.setSorting(order && column.get("name"), order, + {sortValue: column.sortValue()}); + + if (collection.fullCollection) { + // If order is null, pageable will remove the comparator on both sides, + // in this case the default insertion order comparator needs to be + // attached to get back to the order before sorting. + if (collection.fullCollection.comparator == null) { + collection.fullCollection.comparator = comparator; + } + collection.fullCollection.sort(); + collection.trigger("backgrid:sorted", column, direction, collection); + } + else collection.fetch({reset: true, success: function () { + collection.trigger("backgrid:sorted", column, direction, collection); + }}); + } + else { + collection.comparator = comparator; + collection.sort(); + collection.trigger("backgrid:sorted", column, direction, collection); + } + + column.set("direction", direction); + + return this; + }, + makeComparator: function (attr, order, func, type) { + + return function (left, right) { + // extract the values from the models + + var l = func(left, attr), r = func(right, attr), t; + + var types = ['number-cell', 'integer-cell']; + if (_.include(types, type)) { + var _l, _r; + // NaN if invalid number + try { + _l = new BigNumber(l); + } catch(err) { + _l = NaN; + } + + try { + _r = new BigNumber(r); + } catch(err) { + _r = NaN; + } + + // if descending order, swap left and right + if (order === 1) t = _l, _l = _r, _r = t; + + if (_l.eq(_r)) // If both are equals + return 0; + else if (_l.lt(_r)) // If left is less than right + return -1; + else + return 1; + } + }; + } + }); + _.extend(Backgrid.Row.prototype, { makeCell: function (column) { return new (this.getCell(column))({ diff --git a/web/pgadmin/templates/base.html b/web/pgadmin/templates/base.html index d78b0a6..9a12f34 100755 --- a/web/pgadmin/templates/base.html +++ b/web/pgadmin/templates/base.html @@ -183,6 +183,7 @@ 'pgadmin.backform': "{{ url_for('static', filename='js/backform.pgadmin') }}", "jquery.event.drag": "{{ url_for('static', filename='js/jquery-ui/jquery.event.drag-2.2') }}", "jquery.ui": "{{ url_for('static', filename='js/jquery-ui/jquery-ui-1.11.3' if config.DEBUG else 'js/jquery-ui/jquery-ui-1.11.3.min') }}", + "bignumber": "{{ url_for('static', filename='js/bignumber/bignumber' if config.DEBUG else 'js/bignumber/bignumber.min') }}", bean :"{{ url_for('static', filename='js/flotr2/' + ('bean' if config.DEBUG else 'bean-min')) }}", flotr2 :"{{ url_for('static', filename='js/flotr2/flotr2.amd') }}"{% for script in current_app.javascripts %}, '{{ script.name }}': "{{ script.path }}"{% endfor %} ^ permalink raw reply [nested|flat] 3+ messages in thread
* Re: [pgAdmin4][Patch]: RM1938 - Backgrid sorting not working for Integer/Number types @ 2017-01-09 10:28 Dave Page <[email protected]> parent: Surinder Kumar <[email protected]> 0 siblings, 0 replies; 3+ messages in thread From: Dave Page @ 2017-01-09 10:28 UTC (permalink / raw) To: Surinder Kumar <[email protected]>; +Cc: pgadmin-hackers Thanks - that works nicely, so patch applied. On Mon, Jan 9, 2017 at 3:42 PM, Surinder Kumar <[email protected]> wrote: > Hi Dave, > > I just missed the code for swapping left and right values if order is > descending. It's fixed. > Please find attached patch and review. > > On Mon, Jan 9, 2017 at 9:05 AM, Dave Page <[email protected]> wrote: >> >> Hi >> >> On Friday, January 6, 2017, Surinder Kumar >> <[email protected]> wrote: >>> >>> Hi, >>> >>> As the type of data we get from server side is of string type, due to >>> which the sorting for Integer/Number type columns is not working. >>> >>> To fix this issue, we are using BigNumber JS library. >>> We are overriding Backgrid's sort and make_comparator method in >>> backgrid.pgadmin.js. >>> >>> When sorting is performed based on column we identify the column >>> type(integer/number) and then convert its value into BigInteger and the >>> sorts data. >>> >>> This patch is dependent on patch sent for "Adding support for BigNumber >>> JS library". >>> >>> Also, thanks to Murtuza for help. >>> >>> Please find attached patch and review. >> >> >> This works fine for ascending sorts, but if i click the row header a >> second time for a descending sort, the order isn't reversed as expected. >> >> Thanks, Dave. >> >> >> -- >> Dave Page >> Blog: http://pgsnake.blogspot.com >> Twitter: @pgsnake >> >> EnterpriseDB UK: http://www.enterprisedb.com >> The Enterprise PostgreSQL Company >> > -- Dave Page Blog: http://pgsnake.blogspot.com Twitter: @pgsnake EnterpriseDB UK: http://www.enterprisedb.com The Enterprise PostgreSQL Company -- Sent via pgadmin-hackers mailing list ([email protected]) To make changes to your subscription: http://www.postgresql.org/mailpref/pgadmin-hackers ^ permalink raw reply [nested|flat] 3+ messages in thread
end of thread, other threads:[~2017-01-09 10:28 UTC | newest] Thread overview: 3+ messages (download: mbox mbox.gz follow: Atom feed) -- links below jump to the message on this page -- 2017-01-06 08:50 [pgAdmin4][Patch]: RM1938 - Backgrid sorting not working for Integer/Number types Surinder Kumar <[email protected]> 2017-01-09 10:12 ` Surinder Kumar <[email protected]> 2017-01-09 10:28 ` Dave Page <[email protected]>
This inbox is served by agora; see mirroring instructions for how to clone and mirror all data and code used for this inbox