public inbox for [email protected]
help / color / mirror / Atom feedFrom: Surinder Kumar <[email protected]>
To: pgadmin-hackers <[email protected]>
Subject: [pgAdmin4][Patch]: RM1938 - Backgrid sorting not working for Integer/Number types
Date: Fri, 6 Jan 2017 14:20:17 +0530
Message-ID: <CAM5-9D9GdhuaxHKk__a+QgNStjE=EKV=jZZKK2cyMJX=ZB6SaQ@mail.gmail.com> (raw)
List-Unsubscribe: <mailto:[email protected]?body=unsub%20pgadmin-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 %}
view thread (3+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected]
Subject: Re: [pgAdmin4][Patch]: RM1938 - Backgrid sorting not working for Integer/Number types
In-Reply-To: <CAM5-9D9GdhuaxHKk__a+QgNStjE=EKV=jZZKK2cyMJX=ZB6SaQ@mail.gmail.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox