← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 13105: (PT) Basic column sorting implemented.

 

Merge authors:
  Jan Henrik Øverland (janhenrik-overland)
------------------------------------------------------------
revno: 13105 [merge]
committer: Jan Henrik Overland <janhenrik.overland@xxxxxxxxx>
branch nick: dhis2
timestamp: Mon 2013-12-02 17:48:42 +0100
message:
  (PT) Basic column sorting implemented.
added:
  dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/images/arrowupdown.png
modified:
  dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/app.js
  dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/core.js
  dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/styles/style.css


--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== added file 'dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/images/arrowupdown.png'
Binary files dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/images/arrowupdown.png	1970-01-01 00:00:00 +0000 and dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/images/arrowupdown.png	2013-12-02 13:03:40 +0000 differ
=== modified file 'dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/app.js'
--- dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/app.js	2013-11-29 11:52:49 +0000
+++ dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/app.js	2013-12-02 16:45:04 +0000
@@ -354,7 +354,7 @@
 									return;
 								}
 
-								ns.core.web.pivot.createTable(layout, false);
+								ns.core.web.pivot.getData(layout, false);
 
 								window.hide();
 							});
@@ -709,7 +709,7 @@
 							return;
 						}
 
-						ns.core.web.pivot.createTable(layout, false);
+						ns.core.web.pivot.getData(layout, false);
 
 						window.hide();
 					}
@@ -1940,7 +1940,7 @@
 			// mouse events
 			web.events = web.events || {};
 
-			web.events.setMouseHandlers = function(layout, response, uuidDimUuidsMap, uuidObjectMap) {
+			web.events.setValueMouseHandlers = function(layout, response, uuidDimUuidsMap, uuidObjectMap) {
 				var valueEl;
 
 				for (var key in uuidDimUuidsMap) {
@@ -1948,18 +1948,22 @@
 						valueEl = Ext.get(key);
 
 						if (parseFloat(valueEl.dom.textContent)) {
-							valueEl.dom.onMouseClick = web.events.onMouseClick;
+							valueEl.dom.onValueMouseClick = web.events.onValueMouseClick;
+							valueEl.dom.onValueMouseOver = web.events.onValueMouseOver;
+							valueEl.dom.onValueMouseOut = web.events.onValueMouseOut;
 							valueEl.dom.layout = layout;
 							valueEl.dom.response = response;
 							valueEl.dom.uuidDimUuidsMap = uuidDimUuidsMap;
 							valueEl.dom.uuidObjectMap = uuidObjectMap;
-							valueEl.dom.setAttribute('onclick', 'this.onMouseClick(this.layout, this.response, this.uuidDimUuidsMap, this.uuidObjectMap, this.id);');
+							valueEl.dom.setAttribute('onclick', 'this.onValueMouseClick(this.layout, this.response, this.uuidDimUuidsMap, this.uuidObjectMap, this.id);');
+							valueEl.dom.setAttribute('onmouseover', 'this.onValueMouseOver(this.id);');
+							valueEl.dom.setAttribute('onmouseout', 'this.onValueMouseOut(this.id);');
 						}
 					}
 				}
 			};
 
-			web.events.onMouseClick = function(layout, response, uuidDimUuidsMap, uuidObjectMap, uuid) {
+			web.events.onValueMouseClick = function(layout, response, uuidDimUuidsMap, uuidObjectMap, uuid) {
 				var uuids = uuidDimUuidsMap[uuid],
 					layoutConfig = Ext.clone(layout),
 					parentGraphMap = ns.app.viewport.treePanel.getParentGraphMap(),
@@ -2018,11 +2022,11 @@
 							listeners: {
 								render: function() {
 									this.getEl().on('mouseover', function() {
-										web.events.onMouseHover(uuidDimUuidsMap, uuid, 'mouseover', 'chart');
+										web.events.onValueMenuMouseHover(uuidDimUuidsMap, uuid, 'mouseover', 'chart');
 									});
 
 									this.getEl().on('mouseout', function() {
-										web.events.onMouseHover(uuidDimUuidsMap, uuid, 'mouseout', 'chart');
+										web.events.onValueMenuMouseHover(uuidDimUuidsMap, uuid, 'mouseout', 'chart');
 									});
 								}
 							}
@@ -2038,11 +2042,11 @@
 							listeners: {
 								render: function() {
 									this.getEl().on('mouseover', function() {
-										web.events.onMouseHover(uuidDimUuidsMap, uuid, 'mouseover', 'map');
+										web.events.onValueMenuMouseHover(uuidDimUuidsMap, uuid, 'mouseover', 'map');
 									});
 
 									this.getEl().on('mouseout', function() {
-										web.events.onMouseHover(uuidDimUuidsMap, uuid, 'mouseout', 'map');
+										web.events.onValueMenuMouseHover(uuidDimUuidsMap, uuid, 'mouseout', 'map');
 									});
 								}
 							}
@@ -2061,9 +2065,18 @@
 				}());
 			};
 
-			web.events.onMouseHover = function(uuidDimUuidsMap, uuid, event, param) {
+			web.events.onValueMouseOver = function(uuid) {
+				Ext.get(uuid).addCls('highlighted');
+			};
+
+			web.events.onValueMouseOut = function(uuid) {
+				Ext.get(uuid).removeCls('highlighted');
+			};
+
+			web.events.onValueMenuMouseHover = function(uuidDimUuidsMap, uuid, event, param) {
 				var dimUuids;
 
+				// dimension elements
 				if (param === 'chart') {
 					if (Ext.isString(uuid) && Ext.isArray(uuidDimUuidsMap[uuid])) {
 						dimUuids = uuidDimUuidsMap[uuid];
@@ -2084,6 +2097,48 @@
 				}
 			};
 
+			web.events.setColumnHeaderMouseHandlers = function(xLayout, response) {
+				if (Ext.isArray(xLayout.sortableIdObjects)) {
+					for (var i = 0, obj, el; i < xLayout.sortableIdObjects.length; i++) {
+						obj = xLayout.sortableIdObjects[i];
+						el = Ext.get(obj.uuid);
+
+						el.dom.xLayout = xLayout;
+						el.dom.response = response;
+						el.dom.metaDataId = obj.id;
+						el.dom.onColumnHeaderMouseClick = web.events.onColumnHeaderMouseClick;
+						el.dom.onColumnHeaderMouseOver = web.events.onColumnHeaderMouseOver;
+						el.dom.onColumnHeaderMouseOut = web.events.onColumnHeaderMouseOut;
+
+						el.dom.setAttribute('onclick', 'this.onColumnHeaderMouseClick(this.xLayout, this.response, this.metaDataId)');
+						el.dom.setAttribute('onmouseover', 'this.onColumnHeaderMouseOver(this)');
+						el.dom.setAttribute('onmouseout', 'this.onColumnHeaderMouseOut(this)');
+					}
+				}
+			};
+
+			web.events.onColumnHeaderMouseClick = function(xLayout, response, id) {
+				if (xLayout.sorting && xLayout.sorting.id === id) {
+					xLayout.sorting.direction = support.prototype.str.toggleDirection(xLayout.sorting.direction);
+				}
+				else {
+					xLayout.sorting = {
+						id: id,
+						direction: 'DESC'
+					};
+				}
+
+				ns.core.web.pivot.sort(xLayout, response, id);
+			};
+
+			web.events.onColumnHeaderMouseOver = function(el) {
+				Ext.get(el).addCls('pointer highlighted');
+			};
+
+			web.events.onColumnHeaderMouseOut = function(el) {
+				Ext.get(el).removeCls('pointer highlighted');
+			};
+
 			// pivot
 			web.pivot = web.pivot || {};
 
@@ -2163,13 +2218,13 @@
 							layout = api.layout.Layout(layoutConfig);
 
 						if (layout) {
-							web.pivot.createTable(layout, true);
+							web.pivot.getData(layout, true);
 						}
 					}
 				});
 			};
 
-			web.pivot.createTable = function(layout, isUpdateGui) {
+			web.pivot.getData = function(layout, isUpdateGui) {
 				var xLayout,
 					paramString;
 
@@ -2200,11 +2255,7 @@
 						alert(r.responseText);
 					},
 					success: function(r) {
-						var response = api.response.Response(Ext.decode(r.responseText)),
-							xResponse,
-							xColAxis,
-							xRowAxis,
-							config;
+						var response = api.response.Response(Ext.decode(r.responseText));
 
 						if (!response) {
 							web.mask.hide(ns.app.centerRegion);
@@ -2219,43 +2270,101 @@
 							return;
 						}
 
-						// extend response
-						xResponse = service.response.getExtendedResponse(xLayout, response);
-
-						// extended axes
-						xColAxis = service.layout.getExtendedAxis(xLayout, xResponse, 'col');
-						xRowAxis = service.layout.getExtendedAxis(xLayout, xResponse, 'row');
-
-						// update viewport
-						config = web.pivot.getHtml(xLayout, xResponse, xColAxis, xRowAxis);
-						ns.app.centerRegion.removeAll(true);
-						ns.app.centerRegion.update(config.html);
-
-						// after render
-						ns.app.layout = layout;
-						ns.app.xLayout = xLayout;
-						ns.app.response = response;
-						ns.app.xResponse = xResponse;
 						ns.app.paramString = paramString;
-						ns.app.uuidDimUuidsMap = config.uuidDimUuidsMap;
-						ns.app.uuidObjectMap = Ext.applyIf((xColAxis ? xColAxis.uuidObjectMap : {}), (xRowAxis ? xRowAxis.uuidObjectMap : {}));
-
-						if (NS.isSessionStorage) {
-							web.events.setMouseHandlers(layout, response, ns.app.uuidDimUuidsMap, ns.app.uuidObjectMap);
-							web.storage.session.set(layout, 'table');
-						}
-
-						ns.app.viewport.setGui(layout, xLayout, isUpdateGui);
-
-						web.mask.hide(ns.app.centerRegion);
-
-						if (NS.isDebug) {
-							console.log("core", ns.core);
-							console.log("app", ns.app);
-						}
+
+						web.pivot.createTable(layout, xLayout, response, isUpdateGui);
 					}
 				});
 			};
+
+			web.pivot.createTable = function(layout, xLayout, response, isUpdateGui) {
+				var xResponse,
+					xColAxis,
+					xRowAxis,
+					config;
+
+				if (!xLayout) {
+					xLayout = service.layout.getExtendedLayout(layout);
+				}
+
+				// extend response
+				xResponse = service.response.getExtendedResponse(xLayout, response);
+
+				// extended axes
+				xColAxis = service.layout.getExtendedAxis(xLayout, xResponse, 'col');
+				xRowAxis = service.layout.getExtendedAxis(xLayout, xResponse, 'row');
+
+				// update viewport
+				config = web.pivot.getHtml(xLayout, xResponse, xColAxis, xRowAxis);
+				ns.app.centerRegion.removeAll(true);
+				ns.app.centerRegion.update(config.html);
+
+				// after render
+				ns.app.layout = layout;
+				ns.app.xLayout = xLayout;
+				ns.app.response = response;
+				ns.app.xResponse = xResponse;
+				ns.app.uuidDimUuidsMap = config.uuidDimUuidsMap;
+				ns.app.uuidObjectMap = Ext.applyIf((xColAxis ? xColAxis.uuidObjectMap : {}), (xRowAxis ? xRowAxis.uuidObjectMap : {}));
+
+				if (NS.isSessionStorage) {
+					web.events.setValueMouseHandlers(layout, response, ns.app.uuidDimUuidsMap, ns.app.uuidObjectMap);
+					web.events.setColumnHeaderMouseHandlers(xLayout, response);
+					web.storage.session.set(layout, 'table');
+				}
+
+
+
+							//valueEl.dom.onValueMouseClick = web.events.onValueMouseClick;
+							//valueEl.dom.layout = layout;
+							//valueEl.dom.response = response;
+							//valueEl.dom.uuidDimUuidsMap = uuidDimUuidsMap;
+							//valueEl.dom.uuidObjectMap = uuidObjectMap;
+							//valueEl.dom.setAttribute('onclick', 'this.onValueMouseClick(this.layout, this.response, this.uuidDimUuidsMap, this.uuidObjectMap, this.id);');
+
+				ns.app.viewport.setGui(layout, xLayout, isUpdateGui);
+
+				web.mask.hide(ns.app.centerRegion);
+
+				if (NS.isDebug) {
+					console.log("core", ns.core);
+					console.log("app", ns.app);
+				}
+			};
+
+			web.pivot.sort = function(xLayout, response, id) {
+				var xLayout = Ext.clone(xLayout),
+					response = Ext.clone(response),
+					dim = xLayout.rows[0],
+					valueMap = response.idValueMap,
+					direction = xLayout.sorting ? xLayout.sorting.direction : 'DESC',
+					layout;
+
+				dim.ids = [];
+
+				// collect values
+				for (var i = 0, item, key, value; i < dim.items.length; i++) {
+					item = dim.items[i];
+					key = id + item.id;
+					value = parseFloat(valueMap[key]);
+
+					item.value = Ext.isNumber(value) ? value : (Number.MAX_VALUE * -1);
+				}
+
+				// sort
+				support.prototype.array.sort(dim.items, direction, 'value');
+
+				// new id order
+				for (var i = 0; i < dim.items.length; i++) {
+					dim.ids.push(dim.items[i].id);
+				}
+
+				// re-layout
+				layout = api.layout.Layout(xLayout);
+
+				// re-create table
+				web.pivot.createTable(layout, null, response, false);
+			};
 		}());
 	};
 
@@ -4387,7 +4496,7 @@
 				return;
 			}
 
-			ns.core.web.pivot.createTable(layout, false);
+			ns.core.web.pivot.getData(layout, false);
 		};
 
 		accordionBody = Ext.create('Ext.panel.Panel', {
@@ -4846,7 +4955,9 @@
 						xtype: 'button',
 						text: NS.i18n.home,
 						handler: function() {
-							window.location.href = ns.core.init.contextPath + '/dhis-web-commons-about/redirect.action';
+							//window.location.href = ns.core.init.contextPath + '/dhis-web-commons-about/redirect.action';
+
+							ns.core.web.pivot.sort(ns.app.xLayout, ns.app.response, 'Uvn6LCg7dVU');
 						}
 					}
 				]
@@ -5149,7 +5260,7 @@
 						layout = ns.core.api.layout.Layout(JSON.parse(sessionStorage.getItem('dhis2'))[session]);
 
 						if (layout) {
-							ns.core.web.pivot.createTable(layout, true);
+							ns.core.web.pivot.getData(layout, true);
 						}
 					}
 

=== modified file 'dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/core.js'
--- dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/core.js	2013-11-26 15:51:17 +0000
+++ dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/core.js	2013-12-02 16:23:55 +0000
@@ -283,6 +283,8 @@
 
 				// parentGraphMap: object
 
+				// sorting: transient object
+
 				// reportingPeriod: boolean (false) //report tables only
 
 				// organisationUnit: boolean (false) //report tables only
@@ -441,6 +443,8 @@
 
 					layout.parentGraphMap = Ext.isObject(config.parentGraphMap) ? config.parentGraphMap : null;
 
+					layout.sorting = Ext.isObject(config.sorting) && Ext.isString(config.sorting.id) && Ext.isString(config.sorting.direction) ? config.sorting : null;
+
 					layout.reportingPeriod = Ext.isObject(config.reportParams) && Ext.isBoolean(config.reportParams.paramReportingPeriod) ? config.reportParams.paramReportingPeriod : (Ext.isBoolean(config.reportingPeriod) ? config.reportingPeriod : false);
 					layout.organisationUnit =  Ext.isObject(config.reportParams) && Ext.isBoolean(config.reportParams.paramOrganisationUnit) ? config.reportParams.paramOrganisationUnit : (Ext.isBoolean(config.organisationUnit) ? config.organisationUnit : false);
 					layout.parentOrganisationUnit =  Ext.isObject(config.reportParams) && Ext.isBoolean(config.reportParams.paramParentOrganisationUnit) ? config.reportParams.paramParentOrganisationUnit : (Ext.isBoolean(config.parentOrganisationUnit) ? config.parentOrganisationUnit : false);
@@ -550,7 +554,7 @@
 			};
 
 			support.prototype.array.sort = function(array, direction, key) {
-				// accepts [number], [string], [{prop: number}], [{prop: string}]
+				// accepts [number], [string], [{key: number}], [{key: string}]
 
 				if (!support.prototype.array.getLength(array)) {
 					return;
@@ -584,7 +588,7 @@
 						return direction === 'DESC' ? b - a : a - b;
 					}
 
-					return 0;
+					return -1;
 				});
 
 				return array;
@@ -636,6 +640,9 @@
 				return str.replace(new RegExp(find, 'g'), replace);
 			};
 
+			support.prototype.str.toggleDirection = function(direction) {
+				return direction === 'DESC' ? 'ASC' : 'DESC';
+			};
 				// number
 			support.prototype.number = {};
 
@@ -848,7 +855,10 @@
 					dimensionNameIdsMap: {},
 
 						// for param string
-					dimensionNameSortedIdsMap: {}
+					dimensionNameSortedIdsMap: {},
+
+					// sort table by column
+					sortableIdObjects: []
 				};
 
 				Ext.applyIf(xLayout, layout);
@@ -1483,8 +1493,6 @@
 
 //console.log("aaAllFloorObjects", aaAllFloorObjects);
 
-
-	alle = aaAllFloorObjects;
 				return {
 					type: type,
 					items: aDimensions,
@@ -1757,7 +1765,7 @@
 					return parseFloat(support.prototype.number.roundIf(value, 2)).toString();
 				};
 
-				getTdHtml = function(config) {
+				getTdHtml = function(config, metaDataId) {
 					var bgColor,
 						mapLegends,
 						colSpan,
@@ -1769,7 +1777,6 @@
 						isValue = Ext.isObject(config) && Ext.isString(config.type) && config.type === 'value' && !config.empty,
 						cls = '',
 						html = '';
-//console.log(config.type);
 
 					if (!Ext.isObject(config)) {
 						return '';
@@ -1779,7 +1786,6 @@
 					if (isNumeric && xLayout.legendSet) {
 						var value = parseFloat(config.value);
 						mapLegends = xLayout.legendSet.mapLegends;
-console.log(config.type);
 
 						for (var i = 0; i < mapLegends.length; i++) {
 							if (Ext.Number.constrain(value, mapLegends[i].startValue, mapLegends[i].endValue) === value) {
@@ -1800,7 +1806,19 @@
 					cls += isValue ? ' pointer' : '';
 					cls += bgColor ? ' legend' : (config.cls ? ' ' + config.cls : '');
 
-					html += '<td ' + (config.uuid ? ('id="' + config.uuid + '" ') : '') + ' class="' + cls + '" ' + colSpan + rowSpan;
+					// sorting
+					if (Ext.isString(metaDataId)) {
+						cls += ' td-sortable';
+
+						xLayout.sortableIdObjects.push({
+							id: metaDataId,
+							uuid: config.uuid
+						});
+					}
+
+					html += '<td ' + (config.uuid ? ('id="' + config.uuid + '" ') : '');
+					html += ' class="' + cls + '" ' + colSpan + rowSpan
+
 
 					if (bgColor) {
 						html += '>';
@@ -1855,6 +1873,10 @@
 					return !!xLayout.showTotals;
 				};
 
+				doSortableColumnHeaders = function() {
+					return (xRowAxis && xRowAxis.dims === 1);// && !doSubTotals(
+				};
+
 				getColAxisHtmlArray = function() {
 					var a = [],
 						getEmptyHtmlArray;
@@ -1872,6 +1894,7 @@
 						return a;
 					}
 
+					// for each col dimension
 					for (var i = 0, dimHtml; i < xColAxis.dims; i++) {
 						dimHtml = [];
 
@@ -1879,7 +1902,7 @@
 							dimHtml.push(getEmptyHtmlArray());
 						}
 
-						for (var j = 0, obj, spanCount = 0; j < xColAxis.size; j++) {
+						for (var j = 0, obj, spanCount = 0, condoId; j < xColAxis.size; j++) {
 							spanCount++;
 
 							obj = xColAxis.objects.all[i][j];
@@ -1889,7 +1912,12 @@
 							obj.hidden = !(obj.rowSpan || obj.colSpan);
 							obj.htmlValue = service.layout.getItemName(xLayout, xResponse, obj.id, true);
 
-							dimHtml.push(getTdHtml(obj));
+							// sortable column headers. only if last dim and no subtotals.
+							if (i === xColAxis.dims - 1 && doSortableColumnHeaders()) {
+								condoId = xColAxis.ids[j];
+							}
+
+							dimHtml.push(getTdHtml(obj, condoId));
 
 							if (i === 0 && spanCount === xColAxis.span[i] && doSubTotals(xColAxis) ) {
 								dimHtml.push(getTdHtml({

=== modified file 'dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/styles/style.css'
--- dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/styles/style.css	2013-11-29 11:52:49 +0000
+++ dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/styles/style.css	2013-12-02 16:40:37 +0000
@@ -147,6 +147,13 @@
 	display: none;
 }
 
+.td-sortable {
+	background-image: url('../images/arrowupdown.png');
+	background-repeat: no-repeat;
+	background-position: right center;
+	padding-right: 15px !important;
+}
+
 .text-weak {
 	color: #303038;
 }
@@ -201,6 +208,10 @@
 	white-space: nowrap;
 	text-align: right;
 }
+.pivot-value.highlighted {
+	background-color: #f5f5f5;
+}
+
 .pivot-value-subtotal {
 	background-color: #f4f4f4;
 	white-space: nowrap;