From c55c3a51ab1e624985dcfda49a4c236441aaa4e7 Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" Date: Fri, 17 Mar 2017 23:19:07 +0000 Subject: [PATCH 01/41] fix(package): update eslint to version 3.18.0 https://greenkeeper.io/ --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a83a5b61f..c2920a399 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "dependencies": { "babel-eslint": "~7.1.1", "csslint": "1.0.x", - "eslint": "~3.17.0", + "eslint": "~3.18.0", "grunt": "1.0.x", "grunt-contrib-clean": "1.0.x", "grunt-contrib-compress": "~1.4.1", From 93e7427494397179a2a4585cba0113e775144033 Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" Date: Mon, 20 Mar 2017 22:15:39 +0000 Subject: [PATCH 02/41] fix(package): update babel-eslint to version 7.2.0 https://greenkeeper.io/ --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a83a5b61f..1581e0b60 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "homepage": "https://cmv.io/", "repository": "https://github.com/cmv/cmv-app/", "dependencies": { - "babel-eslint": "~7.1.1", + "babel-eslint": "~7.2.0", "csslint": "1.0.x", "eslint": "~3.17.0", "grunt": "1.0.x", From 64b0a2fbdc07fcb7652cc8d75aac205729a341a2 Mon Sep 17 00:00:00 2001 From: Gregg Roemhildt Date: Tue, 28 Mar 2017 19:49:51 -0500 Subject: [PATCH 03/41] fix dynamic layer identifies for sublayerid 0 add example with layer 0 add formatter example --- viewer/js/config/identify.js | 15 +++++++++++++++ viewer/js/config/nls/main.js | 1 + viewer/js/config/viewer.js | 7 +++++++ viewer/js/gis/dijit/Identify.js | 2 +- 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/viewer/js/config/identify.js b/viewer/js/config/identify.js index a85fb35b1..4f177aba0 100644 --- a/viewer/js/config/identify.js +++ b/viewer/js/config/identify.js @@ -34,6 +34,21 @@ define([ // for details on pop-up definition see: https://developers.arcgis.com/javascript/jshelp/intro_popuptemplate.html identifies: { + population: { + 0: { + fieldInfos: [{ + visible: true, + fieldName: 'Pixel value', + alias: 'Population' + }, { + visible: true, + fieldName: 'Rounded Value', + formatter: function (none, attrs) { + return Math.round(attrs['Pixel value'] * 100) / 100; + } + }] + } + }, louisvillePubSafety: { 2: { title: i18n.identify.louisvillePubSafety.policeStation, diff --git a/viewer/js/config/nls/main.js b/viewer/js/config/nls/main.js index d4e18302b..832c49b36 100644 --- a/viewer/js/config/nls/main.js +++ b/viewer/js/config/nls/main.js @@ -22,6 +22,7 @@ define({ }, viewer: { operationalLayers: { + population: 'Population density', damageAssessment: 'Damage Assessment', louisvillePubSafety: 'Louisville Public Safety', restaurants: 'Restaurants', diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index d11dc7490..ea950e6a7 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -175,6 +175,13 @@ define([ iconClass: 'fa fa-smile-o' }] } + }, { + type: 'dynamic', + url: 'https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Population_World/MapServer', + title: i18n.viewer.operationalLayers.population, + options: { + id: 'population' + } }, { type: 'dynamic', url: 'https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/PublicSafety/PublicSafetyOperationalLayers/MapServer', diff --git a/viewer/js/gis/dijit/Identify.js b/viewer/js/gis/dijit/Identify.js index ccae23bc5..50efe59f5 100644 --- a/viewer/js/gis/dijit/Identify.js +++ b/viewer/js/gis/dijit/Identify.js @@ -397,7 +397,7 @@ define([ getInfoTemplate: function (layer, layerId, result) { var popup, config; if (result) { - layerId = result.layerId || layer.layerId; + layerId = typeof result.layerId === 'number' ? result.layerId : layer.layerId; } else if (layerId === null) { layerId = layer.layerId; } From 7e659aa7a07d95ce67ece0377d963db5d0a1d062 Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" Date: Fri, 31 Mar 2017 20:56:54 +0000 Subject: [PATCH 04/41] fix(package): update eslint to version 3.19.0 https://greenkeeper.io/ --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2ced2c888..bfb2ae804 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "dependencies": { "babel-eslint": "~7.2.0", "csslint": "1.0.x", - "eslint": "~3.18.0", + "eslint": "~3.19.0", "grunt": "1.0.x", "grunt-contrib-clean": "1.0.x", "grunt-contrib-compress": "~1.4.1", From f8f8700a33b5badc42599882fa6f2abe624f362f Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Mon, 3 Apr 2017 08:48:05 -0500 Subject: [PATCH 05/41] Switch to sampleserver6 world cities layer --- viewer/js/config/identify.js | 31 ++++++++++++++++++++++++------- viewer/js/config/nls/main.js | 2 +- viewer/js/config/viewer.js | 7 ++++--- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/viewer/js/config/identify.js b/viewer/js/config/identify.js index 4f177aba0..ac23b0fb6 100644 --- a/viewer/js/config/identify.js +++ b/viewer/js/config/identify.js @@ -10,6 +10,24 @@ define([ text: 'Get Directions' }); } + + /** + * A simple number formatter that adds commas to a number + * @param {number} num The number to commafy + * @return {String} The formatted number + */ + function commafy (num) { + var str = num.toString().split('.'); + if (str[0].length >= 5) { + str[0] = str[0].replace(/(\d)(?=(\d{3})+$)/g, '$1,'); + } + if (str[1] && str[1].length >= 5) { + str[1] = str[1].replace(/(\d{3})/g, '$1 '); + } + return str.join('.'); + } + + return { map: true, mapClickMode: true, @@ -34,18 +52,17 @@ define([ // for details on pop-up definition see: https://developers.arcgis.com/javascript/jshelp/intro_popuptemplate.html identifies: { - population: { + cities: { 0: { fieldInfos: [{ visible: true, - fieldName: 'Pixel value', - alias: 'Population' + fieldName: 'CITY_NAME', + label: 'Name' }, { visible: true, - fieldName: 'Rounded Value', - formatter: function (none, attrs) { - return Math.round(attrs['Pixel value'] * 100) / 100; - } + fieldName: 'POP', + label: 'Population', + formatter: commafy }] } }, diff --git a/viewer/js/config/nls/main.js b/viewer/js/config/nls/main.js index 832c49b36..2a9a8a606 100644 --- a/viewer/js/config/nls/main.js +++ b/viewer/js/config/nls/main.js @@ -22,7 +22,7 @@ define({ }, viewer: { operationalLayers: { - population: 'Population density', + cities: 'World Cities', damageAssessment: 'Damage Assessment', louisvillePubSafety: 'Louisville Public Safety', restaurants: 'Restaurants', diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index ea950e6a7..ace54ec1f 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -177,10 +177,11 @@ define([ } }, { type: 'dynamic', - url: 'https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Population_World/MapServer', - title: i18n.viewer.operationalLayers.population, + url: 'http://sampleserver6.arcgisonline.com/arcgis/rest/services/SampleWorldCities/MapServer', + title: i18n.viewer.operationalLayers.cities, options: { - id: 'population' + id: 'cities', + visible: false } }, { type: 'dynamic', From b0a78d2ca62c20ca2ace29cb2a9b8ddaecef1655 Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" Date: Tue, 4 Apr 2017 21:28:11 +0000 Subject: [PATCH 06/41] fix(package): update grunt-contrib-uglify to version 2.3.0 https://greenkeeper.io/ --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bfb2ae804..ffcad05b7 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "grunt-contrib-copy": "1.0.x", "grunt-contrib-csslint": "~2.0.x", "grunt-contrib-cssmin": "~2.0.0", - "grunt-contrib-uglify": "~2.2.0", + "grunt-contrib-uglify": "~2.3.0", "grunt-contrib-watch": "1.0.x", "grunt-eslint": "19.0.x", "grunt-newer": "1.2.x", From e55000810c5aad3e36c561e9905f5eaac22ad2fc Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Mon, 10 Apr 2017 14:34:08 -0700 Subject: [PATCH 07/41] Replace custom `commafy` function with dojo's `number.format`. --- viewer/js/config/identify.js | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/viewer/js/config/identify.js b/viewer/js/config/identify.js index ac23b0fb6..7a6e81185 100644 --- a/viewer/js/config/identify.js +++ b/viewer/js/config/identify.js @@ -1,7 +1,8 @@ define([ 'dojo/i18n!./nls/main', - 'dojo/_base/lang' -], function (i18n, lang) { + 'dojo/_base/lang', + 'dojo/number' +], function (i18n, lang, number) { var linkTemplate = '{text}'; function directionsFormatter (noValue, attributes) { @@ -11,23 +12,6 @@ define([ }); } - /** - * A simple number formatter that adds commas to a number - * @param {number} num The number to commafy - * @return {String} The formatted number - */ - function commafy (num) { - var str = num.toString().split('.'); - if (str[0].length >= 5) { - str[0] = str[0].replace(/(\d)(?=(\d{3})+$)/g, '$1,'); - } - if (str[1] && str[1].length >= 5) { - str[1] = str[1].replace(/(\d{3})/g, '$1 '); - } - return str.join('.'); - } - - return { map: true, mapClickMode: true, @@ -62,7 +46,9 @@ define([ visible: true, fieldName: 'POP', label: 'Population', - formatter: commafy + formatter: function (value) { + return number.format(value); + } }] } }, From 3d11d343bdf175b2f9c34b552a6617c233c9b57c Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Mon, 10 Apr 2017 14:34:57 -0700 Subject: [PATCH 08/41] use sampleserver6 for SF 311 incidents --- viewer/js/config/viewer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index ace54ec1f..05154fe13 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -159,7 +159,7 @@ define([ } }, { type: 'feature', - url: 'https://sampleserver3.arcgisonline.com/ArcGIS/rest/services/SanFrancisco/311Incidents/FeatureServer/0', + url: 'https://sampleserver6.arcgisonline.com/ArcGIS/rest/services/SF311/FeatureServer/0', title: i18n.viewer.operationalLayers.sf311Incidents, options: { id: 'sf311Incidents', From b7032cd99d079e60a394f91cfe0dec19e2f76e92 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Mon, 10 Apr 2017 14:36:40 -0700 Subject: [PATCH 09/41] use HTTPS, not HTTP move `World Cities` to be lowest layer --- viewer/js/config/viewer.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index 05154fe13..cd1b18bb1 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -175,14 +175,6 @@ define([ iconClass: 'fa fa-smile-o' }] } - }, { - type: 'dynamic', - url: 'http://sampleserver6.arcgisonline.com/arcgis/rest/services/SampleWorldCities/MapServer', - title: i18n.viewer.operationalLayers.cities, - options: { - id: 'cities', - visible: false - } }, { type: 'dynamic', url: 'https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/PublicSafety/PublicSafetyOperationalLayers/MapServer', @@ -232,6 +224,14 @@ define([ iconClass: 'fa fa-smile-o' }] } + }, { + type: 'dynamic', + url: 'https://sampleserver6.arcgisonline.com/arcgis/rest/services/SampleWorldCities/MapServer', + title: i18n.viewer.operationalLayers.cities, + options: { + id: 'cities', + visible: false + } /* //examples of vector tile layers (beta in v3.15) }, { From 37bf51f6633b45c5bdd8264fe7ad441ef66ce96e Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" Date: Wed, 12 Apr 2017 01:04:05 +0000 Subject: [PATCH 10/41] fix(package): update grunt-newer to version 1.3.0 https://greenkeeper.io/ --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ffcad05b7..84d2a6457 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "grunt-contrib-uglify": "~2.3.0", "grunt-contrib-watch": "1.0.x", "grunt-eslint": "19.0.x", - "grunt-newer": "1.2.x", + "grunt-newer": "~1.3.0", "grunt-open": "0.2.x", "grunt-postcss": "0.8.x", "body-parser": "~1.17.0", From ff07c00b12d4ab1be34e3469e8931a963334707d Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" Date: Thu, 13 Apr 2017 00:40:10 +0000 Subject: [PATCH 11/41] fix(package): update grunt-contrib-clean to version 1.1.0 https://greenkeeper.io/ --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 84d2a6457..8fd678c22 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "csslint": "1.0.x", "eslint": "~3.19.0", "grunt": "1.0.x", - "grunt-contrib-clean": "1.0.x", + "grunt-contrib-clean": "~1.1.0", "grunt-contrib-compress": "~1.4.1", "grunt-contrib-connect": "1.0.x", "grunt-contrib-copy": "1.0.x", From 5795a4ac16d95a257ff52ffeecb8a93b43e36c53 Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" Date: Wed, 10 May 2017 15:08:32 +0000 Subject: [PATCH 12/41] fix(package): update grunt-contrib-cssmin to version 2.2.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8fd678c22..34cc88ee2 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "grunt-contrib-connect": "1.0.x", "grunt-contrib-copy": "1.0.x", "grunt-contrib-csslint": "~2.0.x", - "grunt-contrib-cssmin": "~2.0.0", + "grunt-contrib-cssmin": "~2.2.0", "grunt-contrib-uglify": "~2.3.0", "grunt-contrib-watch": "1.0.x", "grunt-eslint": "19.0.x", From 8dd4ae468230236230c52cbb31a1349697d48986 Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" Date: Fri, 12 May 2017 12:05:33 +0000 Subject: [PATCH 13/41] fix(package): update grunt-contrib-uglify to version 3.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 34cc88ee2..26ad361f4 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "grunt-contrib-copy": "1.0.x", "grunt-contrib-csslint": "~2.0.x", "grunt-contrib-cssmin": "~2.2.0", - "grunt-contrib-uglify": "~2.3.0", + "grunt-contrib-uglify": "~3.0.0", "grunt-contrib-watch": "1.0.x", "grunt-eslint": "19.0.x", "grunt-newer": "~1.3.0", From 4c89132bfe77396361915c0e2305be41c95c9a52 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Wed, 17 May 2017 21:15:11 -0700 Subject: [PATCH 14/41] Add initial support for "group" layers provided by carrbrpoa --- viewer/js/config/viewer.js | 6 +- viewer/js/gis/dijit/LayerControl.js | 46 ++++++- .../dijit/LayerControl/controls/Grouped.js | 130 ++++++++++++++++++ .../dijit/LayerControl/controls/_Control.js | 6 +- 4 files changed, 183 insertions(+), 5 deletions(-) create mode 100644 viewer/js/gis/dijit/LayerControl/controls/Grouped.js diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index cd1b18bb1..03fe9d5de 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -146,7 +146,8 @@ define([ opacity: 1.0, visible: true, outFields: ['*'], - mode: 0 + mode: 0, + groupID: 'Grouped Feature Layers' }, editorLayerInfos: { disableGeometryUpdate: false @@ -166,7 +167,8 @@ define([ opacity: 1.0, visible: true, outFields: ['req_type', 'req_date', 'req_time', 'address', 'district'], - mode: 0 + mode: 0, + groupID: 'Grouped Feature Layers' }, layerControlLayerInfos: { menu: [{ diff --git a/viewer/js/gis/dijit/LayerControl.js b/viewer/js/gis/dijit/LayerControl.js index 4a8f14098..0ebc8d170 100644 --- a/viewer/js/gis/dijit/LayerControl.js +++ b/viewer/js/gis/dijit/LayerControl.js @@ -61,6 +61,7 @@ define([ _overlayContainer: null, _swiper: null, _swipeLayerToggleHandle: null, + _groupedLayerInfos: {}, _controls: { dynamic: './LayerControl/controls/Dynamic', feature: './LayerControl/controls/Feature', @@ -75,7 +76,8 @@ define([ webtiled: './LayerControl/controls/WebTiled', imagevector: './LayerControl/controls/ImageVector', raster: './LayerControl/controls/Raster', - stream: './LayerControl/controls/Stream' + stream: './LayerControl/controls/Stream', + grouped: './LayerControl/controls/Grouped' }, constructor: function (options) { options = options || {}; @@ -165,6 +167,30 @@ define([ require([control], lang.hitch(this, '_addControl', layerInfo)); } }, this); + + for (var key in this._groupedLayerInfos) { + if (this._groupedLayerInfos.hasOwnProperty(key)) { + var control = this._controls.grouped; + var hasAnyVisibleLayer = this._groupedLayerInfos[key].some(function (layerDetail) { + return layerDetail.layerInfo.layer.visible; + }); + + var layerInfo = { + title: key, + layer: { + id: key.replace(/\s/g, ''), + loaded: true, + minScale: 0, + maxScale: 0, + _params: {}, + visible: hasAnyVisibleLayer // initial visibility depends on grouped layers + }, + layerDetails: this._groupedLayerInfos[key] + }; + require([control], lang.hitch(this, '_addControl', layerInfo)); + } + } + this._checkReorder(); })); }, @@ -214,6 +240,7 @@ define([ controller: this, layer: layer, layerTitle: layerInfo.title, + layerDetails: layerInfo.layerDetails, controlOptions: lang.mixin({ noLegend: null, noZoom: null, @@ -236,6 +263,23 @@ define([ } else { this.addChild(layerControl, position); } + this._storeGroupedLayerInfo(layerInfo, layerControl); + }, + _storeGroupedLayerInfo: function (layerInfo, layerControl) { + var groupID = layerInfo.layer._params.groupID; + if (!groupID) { + // Not a grouped layer + return; + } + + if (!this._groupedLayerInfos.hasOwnProperty(groupID)) { + this._groupedLayerInfos[groupID] = []; + } + + this._groupedLayerInfos[groupID].push({ + layerInfo: layerInfo, + layerControl: layerControl + }); }, _applyLayerControlOptions: function (controlOptions, layer) { if (typeof controlOptions.includeUnspecifiedLayers === 'undefined' && typeof controlOptions.subLayerInfos === 'undefined' && typeof controlOptions.excludedLayers === 'undefined') { diff --git a/viewer/js/gis/dijit/LayerControl/controls/Grouped.js b/viewer/js/gis/dijit/LayerControl/controls/Grouped.js new file mode 100644 index 000000000..bc40a1dae --- /dev/null +++ b/viewer/js/gis/dijit/LayerControl/controls/Grouped.js @@ -0,0 +1,130 @@ +define([ + 'dojo/_base/declare', + 'dojo/_base/lang', + 'dojo/on', + 'dojo/topic', + 'dojo/html', + 'dojo/dom-class', + 'dojo/dom-style', + 'dojo/dom-construct', + 'dijit/_WidgetBase', + 'dijit/_TemplatedMixin', + 'dijit/_Contained', + './_Control' // layer control base class +], function ( + declare, + lang, + on, + topic, + html, + domClass, + domStyle, + domConstruct, + _WidgetBase, + _TemplatedMixin, + _Contained, + _Control +) { + var GroupedControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { + layerDetails: null, + _layerType: 'grouped', // constant + _esriLayerType: null, // constant + + // create and legend + _layerTypePreInit: function () { + this.layerDetails.forEach(lang.hitch(this, function (layerDetail) { + domConstruct.place(layerDetail.layerControl.domNode, this.expandNode, 'first'); + })); + }, + + _layerTypeInit: function () { + this._expandClick(); + }, + + hasAnyVisibleLayer: function () { + return this.layerDetails.some(function (layerDetail) { + return layerDetail.layerInfo.layer.visible; + }); + }, + + hasAnyInvisibleLayer: function () { + return this.layerDetails.some(function (layerDetail) { + return !layerDetail.layerInfo.layer.visible; + }); + }, + + _initialize: function () { + // an optional function in each control widget called before widget init + if (this._layerTypePreInit) { + this._layerTypePreInit(); + } + var layer = this.layer, + controlOptions = this.controlOptions, + layerDetails = this.layerDetails; + + // set checkbox + this._setLayerCheckbox(layer, this.checkNode); + + // wire up layer visibility + on(this.checkNode, 'click', lang.hitch(this, '_setLayerVisibility', layerDetails, this.checkNode)); + + // set title + html.set(this.labelNode, this.layerTitle); + + // create layer menu + domClass.remove(this.menuNode, 'fa, layerControlMenuIcon, ' + this.icons.menu); + domStyle.set(this.menuClickNode, 'cursor', 'default'); + + // if layer has scales set + if (layer.minScale !== 0 || layer.maxScale !== 0) { + this._checkboxScaleRange(); + this._scaleRangeHandler = layer.getMap().on('zoom-end', lang.hitch(this, '_checkboxScaleRange')); + } + + // a function in each control widget for layer type specifics like legends and such + this._layerTypeInit(); + + // show expandNode + // no harm if click handler wasn't created + if (controlOptions.expanded) { + this.expandClickNode.click(); + } + + topic.subscribe('layerControl/layerToggle', lang.hitch(this, function (options) { + if (options.params && !options.forced && options.id !== layer.id && options.params.groupID === this.layerTitle) { + var layerVisible = this.layer.visible; + if (layerVisible && !this.hasAnyVisibleLayer()) { + this.toggleVisibility(); + } else if (!layerVisible && !this.hasAnyInvisibleLayer()) { + this.toggleVisibility(); + } + } + })); + }, + + toggleVisibility: function () { + var layer = this.layer; + layer.visible = !layer.visible; + + this._setLayerCheckbox(layer, this.checkNode); + topic.publish('layerControl/layerToggle', { + id: layer.id, + visible: layer.visible, + forced: true + }); + }, + + _setLayerVisibility: function (layerDetails, checkNode, event) { + this.toggleSelfVisibility(); + + var _arguments = arguments; + // Calls _setLayerVisibility for each grouped layer + layerDetails.forEach(lang.hitch(this, function (layerDetail) { + if (this.layer.visible !== layerDetail.layerInfo.layer.visible) { + this.inherited(_arguments, [layerDetail.layerInfo.layer, layerDetail.layerControl.checkNode, event]); + } + })); + } + }); + return GroupedControl; +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/LayerControl/controls/_Control.js b/viewer/js/gis/dijit/LayerControl/controls/_Control.js index 58e7f6179..229a5e33c 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/_Control.js +++ b/viewer/js/gis/dijit/LayerControl/controls/_Control.js @@ -177,14 +177,16 @@ define([ layer.hide(); topic.publish('layerControl/layerToggle', { id: layer.id, - visible: layer.visible + visible: layer.visible, + params: layer._params }); } else { this._setLayerCheckbox(layer, checkNode); layer.show(); topic.publish('layerControl/layerToggle', { id: layer.id, - visible: layer.visible + visible: layer.visible, + params: layer._params }); } if (layer.minScale !== 0 || layer.maxScale !== 0) { From 14568753857f075a7429dcae31b97e44aa1d5316 Mon Sep 17 00:00:00 2001 From: Donald Duncan Date: Mon, 22 May 2017 10:56:34 +1200 Subject: [PATCH 15/41] Allow choosing output scale in the print widget settings --- viewer/js/gis/dijit/Print.js | 1 + viewer/js/gis/dijit/Print/templates/Print.html | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/viewer/js/gis/dijit/Print.js b/viewer/js/gis/dijit/Print.js index 7fa56891f..8f2262608 100644 --- a/viewer/js/gis/dijit/Print.js +++ b/viewer/js/gis/dijit/Print.js @@ -216,6 +216,7 @@ define([ template.format = form.format; template.layout = form.layout; template.preserveScale = eval(form.preserveScale); //turns a string 'true' into true + template.outScale = form.outScale; template.label = form.title; template.exportOptions = mapOnlyForm; template.layoutOptions = { diff --git a/viewer/js/gis/dijit/Print/templates/Print.html b/viewer/js/gis/dijit/Print/templates/Print.html index c8ed5cdab..453c6c9a1 100644 --- a/viewer/js/gis/dijit/Print/templates/Print.html +++ b/viewer/js/gis/dijit/Print/templates/Print.html @@ -52,6 +52,14 @@ ${i18n.mapExtent} + + + ${i18n.mapScale}: + + + + +
From 8ea9c934f4061e734cdec273ab6ac575a3c8cc09 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Mon, 22 May 2017 22:20:33 -0700 Subject: [PATCH 16/41] Add support for Graphics layer as layer type and layerControl widget Add OSM layer in layerControl widget Remove `label` layer type since it has been deprecated by Esri. --- viewer/js/gis/dijit/LayerControl.js | 4 +++- .../dijit/LayerControl/controls/Graphics.js | 24 +++++++++++++++++++ .../LayerControl/controls/OpenStreetMap.js | 23 ++++++++++++++++++ viewer/js/viewer/_MapMixin.js | 2 +- 4 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 viewer/js/gis/dijit/LayerControl/controls/Graphics.js create mode 100644 viewer/js/gis/dijit/LayerControl/controls/OpenStreetMap.js diff --git a/viewer/js/gis/dijit/LayerControl.js b/viewer/js/gis/dijit/LayerControl.js index 0ebc8d170..cea78be91 100644 --- a/viewer/js/gis/dijit/LayerControl.js +++ b/viewer/js/gis/dijit/LayerControl.js @@ -77,7 +77,9 @@ define([ imagevector: './LayerControl/controls/ImageVector', raster: './LayerControl/controls/Raster', stream: './LayerControl/controls/Stream', - grouped: './LayerControl/controls/Grouped' + grouped: './LayerControl/controls/Grouped', + graphics: './LayerControl/controls/Graphics', + osm: './LayerControl/controls/OpenStreetMap' }, constructor: function (options) { options = options || {}; diff --git a/viewer/js/gis/dijit/LayerControl/controls/Graphics.js b/viewer/js/gis/dijit/LayerControl/controls/Graphics.js new file mode 100644 index 000000000..080049563 --- /dev/null +++ b/viewer/js/gis/dijit/LayerControl/controls/Graphics.js @@ -0,0 +1,24 @@ +define([ + 'dojo/_base/declare', + 'dijit/_WidgetBase', + 'dijit/_TemplatedMixin', + 'dijit/_Contained', + './_Control' // layer control base class +], function ( + declare, + _WidgetBase, + _TemplatedMixin, + _Contained, + _Control +) { + + var GraphicsControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { + _layerType: 'vector', // constant + _esriLayerType: 'graphics', // constant + _layerTypeInit: function () { + this._expandRemove(); + // legend or no legend??? + } + }); + return GraphicsControl; +}); \ No newline at end of file diff --git a/viewer/js/gis/dijit/LayerControl/controls/OpenStreetMap.js b/viewer/js/gis/dijit/LayerControl/controls/OpenStreetMap.js new file mode 100644 index 000000000..6846f474d --- /dev/null +++ b/viewer/js/gis/dijit/LayerControl/controls/OpenStreetMap.js @@ -0,0 +1,23 @@ +define([ + 'dojo/_base/declare', + 'dijit/_WidgetBase', + 'dijit/_TemplatedMixin', + 'dijit/_Contained', + './_Control' // layer control base class +], function ( + declare, + _WidgetBase, + _TemplatedMixin, + _Contained, + _Control +) { + + var OpenStreetMapControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], { + _layerType: 'overlay', // constant + _esriLayerType: 'osm', // constant + _layerTypeInit: function () { + this._expandRemove(); + } + }); + return OpenStreetMapControl; +}); \ No newline at end of file diff --git a/viewer/js/viewer/_MapMixin.js b/viewer/js/viewer/_MapMixin.js index 71e658d0a..3d26795b4 100644 --- a/viewer/js/viewer/_MapMixin.js +++ b/viewer/js/viewer/_MapMixin.js @@ -109,10 +109,10 @@ define([ dynamic: 'esri/layers/ArcGISDynamicMapServiceLayer', feature: 'esri/layers/FeatureLayer', georss: 'esri/layers/GeoRSSLayer', + graphics: 'esri/layers/GraphicsLayer', image: 'esri/layers/ArcGISImageServiceLayer', imagevector: 'esri/layers/ArcGISImageServiceVectorLayer', kml: 'esri/layers/KMLLayer', - label: 'esri/layers/LabelLayer', //untested mapimage: 'esri/layers/MapImageLayer', //untested osm: 'esri/layers/OpenStreetMapLayer', raster: 'esri/layers/RasterLayer', From cc4fa5e4fd3bd08a9d2ec5718554b0a01fde1e7a Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Tue, 23 May 2017 00:09:39 -0700 Subject: [PATCH 17/41] Enhancements for grouped layers * enable tri-state (indeterminate) checkbox for grouped layers * fixes for new icons for checked/unchecked layers * don't group layers when there is only 1 layer in group * don't allow reordering when grouped layers are used * add a `getMap` function for grouped layers to avoid error * use dojo/array --- viewer/js/config/viewer.js | 12 +- viewer/js/gis/dijit/LayerControl.js | 88 +++++++++------ .../dijit/LayerControl/controls/Grouped.js | 40 ++++++- .../dijit/LayerControl/css/LayerControl.css | 106 ++++++++++++------ 4 files changed, 166 insertions(+), 80 deletions(-) diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index 03fe9d5de..e3511b6ff 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -146,8 +146,7 @@ define([ opacity: 1.0, visible: true, outFields: ['*'], - mode: 0, - groupID: 'Grouped Feature Layers' + mode: 0 }, editorLayerInfos: { disableGeometryUpdate: false @@ -157,6 +156,9 @@ define([ layerInfo: { title: i18n.viewer.operationalLayers.restaurants } + }, + layerControlLayerInfos: { + layerGroup: 'Grouped Feature Layers' } }, { type: 'feature', @@ -165,12 +167,12 @@ define([ options: { id: 'sf311Incidents', opacity: 1.0, - visible: true, + visible: false, outFields: ['req_type', 'req_date', 'req_time', 'address', 'district'], - mode: 0, - groupID: 'Grouped Feature Layers' + mode: 0 }, layerControlLayerInfos: { + layerGroup: 'Grouped Feature Layers', menu: [{ topic: 'hello', label: 'Say Hello Custom', diff --git a/viewer/js/gis/dijit/LayerControl.js b/viewer/js/gis/dijit/LayerControl.js index 0ebc8d170..bdd3ef9c6 100644 --- a/viewer/js/gis/dijit/LayerControl.js +++ b/viewer/js/gis/dijit/LayerControl.js @@ -33,14 +33,15 @@ define([ map: null, layerInfos: [], icons: { - expand: 'fa-caret-right', - collapse: 'fa-caret-down', - checked: 'fa-check-square-o', - unchecked: 'fa-square-o', - update: 'fa-refresh', - menu: 'fa-bars', - folder: 'fa-folder-o', - folderOpen: 'fa-folder-open-o' + expand: 'fa-caret-right fa-fw layerControlIcon-Expand', + collapse: 'fa-caret-down fa-fw layerControlIcon-Collapse', + checked: 'fa-check fa-fw fa-border layerControlIcon-Checked', + unchecked: 'fa-square fa-fw fa-border layerControlIcon-Unchecked', + indeterminate: 'fa-minus fa-fw fa-border layerControlIcon-Indeterminate', + update: 'fa-refresh layerControlIcon-Update', + menu: 'fa-bars layerControlIcon-Menu', + folder: 'fa-folder-o fa-fw layerControlIcon-Folder', + folderOpen: 'fa-folder-open-o fa-fw layerControlIcon-Folder layerControlIcon-FolderOpen' }, separated: false, overlayReorder: false, @@ -139,11 +140,17 @@ define([ var modules = []; // push layer control mods array.forEach(layerInfos, function (layerInfo) { + layerInfo.controlOptions = layerInfo.controlOptions || {}; // check if control is excluded var controlOptions = layerInfo.controlOptions; - if (controlOptions && controlOptions.exclude === true) { + if (controlOptions.exclude === true) { return; } + // if layerGroups are used, disallow re-ordering + if (controlOptions.layerGroup) { + this.overlayReorder = false; + this.vectorReorder = false; + } var mod = this._controls[layerInfo.type]; if (mod) { modules.push(mod); @@ -159,7 +166,7 @@ define([ array.forEach(layerInfos, function (layerInfo) { // exclude from widget var controlOptions = layerInfo.controlOptions; - if (controlOptions && controlOptions.exclude === true) { + if (controlOptions.exclude === true) { return; } var control = this._controls[layerInfo.type]; @@ -170,24 +177,27 @@ define([ for (var key in this._groupedLayerInfos) { if (this._groupedLayerInfos.hasOwnProperty(key)) { - var control = this._controls.grouped; - var hasAnyVisibleLayer = this._groupedLayerInfos[key].some(function (layerDetail) { - return layerDetail.layerInfo.layer.visible; - }); - - var layerInfo = { - title: key, - layer: { - id: key.replace(/\s/g, ''), - loaded: true, - minScale: 0, - maxScale: 0, - _params: {}, - visible: hasAnyVisibleLayer // initial visibility depends on grouped layers - }, - layerDetails: this._groupedLayerInfos[key] - }; - require([control], lang.hitch(this, '_addControl', layerInfo)); + var layerDetails = this._groupedLayerInfos[key]; + if (layerDetails && layerDetails.length > 1) { + var control = this._controls.grouped; + var layerInfo = { + title: key, + type: 'grouped', + controlOptions: {}, + layer: { + id: key.replace(/\s/g, ''), + loaded: true, + getMap: lang.hitch(this, function () { + return this.map; + }), + minScale: 0, + maxScale: 0, + _params: {} + }, + layerDetails: layerDetails + }; + require([control], lang.hitch(this, '_addControl', layerInfo)); + } } } @@ -229,7 +239,7 @@ define([ // create layer control and add to appropriate _container _addControl: function (layerInfo, Control) { var layer = (typeof layerInfo.layer === 'string') ? this.map.getLayer(layerInfo.layer) : layerInfo.layer; - if (layerInfo.controlOptions && (layerInfo.type === 'dynamic' || layerInfo.type === 'feature')) { + if (layerInfo.type === 'dynamic' || layerInfo.type === 'feature') { if (layer.loaded) { this._applyLayerControlOptions(layerInfo.controlOptions, layer); } else { @@ -248,14 +258,21 @@ define([ swipe: null, expanded: false, sublayers: true, + layerGroup: null, menu: this.menu[layerInfo.type], subLayerMenu: this.subLayerMenu[layerInfo.type] }, layerInfo.controlOptions) }); layerControl.startup(); var position = layerInfo.position || 0; + var layerType = layerControl._layerType; + if (layerType === 'grouped') { + if (layerControl.layerDetails && layerControl.layerDetails.length > 0) { + layerControl._layerType = layerControl.layerDetails[0].layerControl._layerType; + } + } if (this.separated) { - if (layerControl._layerType === 'overlay') { + if (layerType === 'overlay') { this._overlayContainer.addChild(layerControl, position); } else { this._vectorContainer.addChild(layerControl, position); @@ -266,17 +283,16 @@ define([ this._storeGroupedLayerInfo(layerInfo, layerControl); }, _storeGroupedLayerInfo: function (layerInfo, layerControl) { - var groupID = layerInfo.layer._params.groupID; - if (!groupID) { + if (!layerInfo.controlOptions.layerGroup) { // Not a grouped layer return; } - - if (!this._groupedLayerInfos.hasOwnProperty(groupID)) { - this._groupedLayerInfos[groupID] = []; + var layerGroup = layerInfo.controlOptions.layerGroup; + if (!this._groupedLayerInfos.hasOwnProperty(layerGroup)) { + this._groupedLayerInfos[layerGroup] = []; } - this._groupedLayerInfos[groupID].push({ + this._groupedLayerInfos[layerGroup].push({ layerInfo: layerInfo, layerControl: layerControl }); diff --git a/viewer/js/gis/dijit/LayerControl/controls/Grouped.js b/viewer/js/gis/dijit/LayerControl/controls/Grouped.js index bc40a1dae..707d1d480 100644 --- a/viewer/js/gis/dijit/LayerControl/controls/Grouped.js +++ b/viewer/js/gis/dijit/LayerControl/controls/Grouped.js @@ -1,6 +1,7 @@ define([ 'dojo/_base/declare', 'dojo/_base/lang', + 'dojo/_base/array', 'dojo/on', 'dojo/topic', 'dojo/html', @@ -14,6 +15,7 @@ define([ ], function ( declare, lang, + array, on, topic, html, @@ -32,7 +34,7 @@ define([ // create and legend _layerTypePreInit: function () { - this.layerDetails.forEach(lang.hitch(this, function (layerDetail) { + array.forEach(this.layerDetails, lang.hitch(this, function (layerDetail) { domConstruct.place(layerDetail.layerControl.domNode, this.expandNode, 'first'); })); }, @@ -42,13 +44,13 @@ define([ }, hasAnyVisibleLayer: function () { - return this.layerDetails.some(function (layerDetail) { + return array.some(this.layerDetails, function (layerDetail) { return layerDetail.layerInfo.layer.visible; }); }, hasAnyInvisibleLayer: function () { - return this.layerDetails.some(function (layerDetail) { + return array.some(this.layerDetails, function (layerDetail) { return !layerDetail.layerInfo.layer.visible; }); }, @@ -99,13 +101,16 @@ define([ this.toggleVisibility(); } } + this._setLayerCheckbox(); })); }, toggleVisibility: function () { var layer = this.layer; layer.visible = !layer.visible; - + if (this.hasAnyVisibleLayer() && this.hasAnyInvisibleLayer()) { + layer.visible = true; + } this._setLayerCheckbox(layer, this.checkNode); topic.publish('layerControl/layerToggle', { id: layer.id, @@ -115,15 +120,38 @@ define([ }, _setLayerVisibility: function (layerDetails, checkNode, event) { - this.toggleSelfVisibility(); + this.toggleVisibility(); var _arguments = arguments; // Calls _setLayerVisibility for each grouped layer - layerDetails.forEach(lang.hitch(this, function (layerDetail) { + array.forEach(layerDetails, lang.hitch(this, function (layerDetail) { if (this.layer.visible !== layerDetail.layerInfo.layer.visible) { this.inherited(_arguments, [layerDetail.layerInfo.layer, layerDetail.layerControl.checkNode, event]); } })); + this._setLayerCheckbox(); + }, + + // overrides the method in _Control + _setLayerCheckbox: function () { + var checkNode = this.checkNode, + i = this.icons; + + domClass.remove(checkNode, i.checked); + domClass.remove(checkNode, i.unchecked); + domClass.remove(checkNode, i.indeterminate); + + var hasVisible = this.hasAnyVisibleLayer(); + var hasHidden = this.hasAnyInvisibleLayer(); + + // indeterminate - both visible and invisible layers in group + if (hasVisible && hasHidden) { + domClass.add(checkNode, i.indeterminate); + } else if (hasVisible) { + domClass.add(checkNode, i.checked); + } else { + domClass.add(checkNode, i.unchecked); + } } }); return GroupedControl; diff --git a/viewer/js/gis/dijit/LayerControl/css/LayerControl.css b/viewer/js/gis/dijit/LayerControl/css/LayerControl.css index c3fa09b4e..e50621c76 100644 --- a/viewer/js/gis/dijit/LayerControl/css/LayerControl.css +++ b/viewer/js/gis/dijit/LayerControl/css/LayerControl.css @@ -1,13 +1,8 @@ .layerControlDijit .vectorLayerContainer {} -.layerControlDijit .vectorLabelContainer { - font-size: 15px; - font-weight: 600; - padding-bottom: 4px; -} - .layerControlDijit .overlayLayerContainer {} +.layerControlDijit .vectorLabelContainer, .layerControlDijit .overlayLabelContainer { font-size: 15px; font-weight: 600; @@ -31,43 +26,32 @@ } .layerControlDijit .layerControlTable tr { - vertical-align: middle; + vertical-align: top; } .layerControlDijit .layerControlTable td { padding: 0; } -.layerControlDijit .layerControlTableExpand { +.layerControlDijit .layerControlTableExpand, +.layerControlDijit .layerControlTableCheck, +.layerControlDijit .layerControlTableMenu, +.layerControlDijit .layerControlTableLabel { cursor: pointer; - width: 18px; - height: 15px; - line-height: 15px; } -.layerControlDijit .layerControlTableCheck, .layerControlDijit .layerControlTableMenu { - cursor: pointer; - width: 19px; - height: 16px; - line-height: 16px; +.layerControlDijit .layerControlTableExpand, +.layerControlDijit .layerControlTableCheck, +.layerControlDijit .layerControlTableMenu, +.layerControlDijit .layerControlTableUpdate { + text-align: center; } .layerControlDijit .layerControlTableLabel { - cursor: pointer; font-size: 15px; - height: 16px; line-height: 16px; -} - -.layerControlDijit .layerControlTableMenu { - cursor: pointer; -} - -.layerControlDijit .layerControlTableUpdate { - width: 21px; - height: 16px; - line-height: 16px; - text-align: center; + padding-top: 2px; + width: 100%; } .layerControlDijit .layerControlHidden { @@ -79,27 +63,79 @@ } .layerControlDijit .layerControlIndent { - padding-left: 22px; + padding-left: 20px; } .layerControlDijit .layerControlIcon { - font-size: 17px; + font-size: 18px; + margin-right: 4px; +} + +.layerControlDijit .layerControlTableExpand .layerControlIcon { + margin-right: 0; + width: 1em; +} + +.layerControlDijit .layerControlIndent .layerControlTableExpand .layerControlIcon { + margin-right: 4px; +} + +.layerControlDijit .layerControlIndent .layerControlIndent .layerControlTableExpand .layerControlIcon, +.layerControlDijit .layerControlSublayer .layerControlTableExpand .layerControlIcon { + margin-left: 4px; + margin-right: 4px; +} + +.layerControlDijit .layerControlTableCheck .layerControlIcon { + font-size: 12px; + height: 13px; + width: 13px; +} + +.layerControlDijit .layer-folder { + color: #666; +} + +.layerControlDijit .layerControlTableCheck .fa-border { + border-color: #333; + border-radius: 3px; + padding: 0.15em 0.1875em 0.1125em; +} + + +.layerControlDijit .layerControlTableCheck .layerControlIcon-Folder { + color: #333; +} + +.layerControlDijit .layerControlTableCheck .layerControlIcon-Checked { + color: #090; +} + +.layerControlDijit .layerControlTableCheck .layerControlIcon-Unchecked:before { + color: transparent; +} + +.layerControlDijit .layerControlTableCheck .layerControlIcon-Indeterminate { + color: #666; } .layerControlDijit .layerControlUpdateIcon { + color: #666; font-size: 12px; } .layerControlDijit .layerControlMenuIcon { font-size: 15px; color: #666; + margin-left: 4px; } .layerControlDijit .layerControlMenuIcon:hover { color: #111; } -.layerControlDijit .layerControlCheckIconOutScale { +.layerControlDijit .layerControlTableCheck .layerControlCheckIconOutScale { + border-color: #BBB; color: #BBB; } @@ -120,6 +156,10 @@ text-decoration: underline; } +.layerControlDijit .layerControlLegendTable { + margin: 4px 0; +} + .layerControlDijit .layerControlLegendTable tr { vertical-align: middle; } @@ -151,7 +191,7 @@ /* sublayer menu */ .layerControlDijit .layerControlSublayer .layerControlTable td.layerControlTableMenu { - padding-right: 20px; + padding-right: 16px; } .layerControlDijit .menuClickNode.hidden { From f45334b32efa8f62f5e676f17c0bd4915eeae39f Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Fri, 26 May 2017 14:20:12 -0500 Subject: [PATCH 18/41] Add conditional css to hide basemap text on small screens --- viewer/js/gis/dijit/Basemaps/css/Basemaps.css | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/viewer/js/gis/dijit/Basemaps/css/Basemaps.css b/viewer/js/gis/dijit/Basemaps/css/Basemaps.css index d35d4ec8c..45b2da4e6 100644 --- a/viewer/js/gis/dijit/Basemaps/css/Basemaps.css +++ b/viewer/js/gis/dijit/Basemaps/css/Basemaps.css @@ -11,4 +11,13 @@ .basemapsIcon:before { font-family: FontAwesome; content: "\f009"; -} \ No newline at end of file +} + + +/* condense dropdown on small screens */ + +@media screen and (max-width: 600px) { + #basemaps_widget .dijitButtonText { + display: none; + } +} From fe976ff268af0248c2bc14fbc3559a4a16c7eb97 Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Fri, 26 May 2017 14:31:32 -0500 Subject: [PATCH 19/41] Add baseClass property to basemap widget --- viewer/js/gis/dijit/Basemaps.js | 4 ++-- viewer/js/gis/dijit/Basemaps/css/Basemaps.css | 19 +++++++++++-------- .../dijit/Basemaps/templates/Basemaps.html | 2 +- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/viewer/js/gis/dijit/Basemaps.js b/viewer/js/gis/dijit/Basemaps.js index 72a9dbbce..11d24d62c 100644 --- a/viewer/js/gis/dijit/Basemaps.js +++ b/viewer/js/gis/dijit/Basemaps.js @@ -44,7 +44,7 @@ define([ widgetsInTemplate: true, i18n: i18n, title: i18n.title, - + baseClass: 'basemapWidget', basemaps: {}, currentBasemap: null, mapStartBasemap: null, @@ -174,4 +174,4 @@ define([ } } }); -}); \ No newline at end of file +}); diff --git a/viewer/js/gis/dijit/Basemaps/css/Basemaps.css b/viewer/js/gis/dijit/Basemaps/css/Basemaps.css index 45b2da4e6..f628aa892 100644 --- a/viewer/js/gis/dijit/Basemaps/css/Basemaps.css +++ b/viewer/js/gis/dijit/Basemaps/css/Basemaps.css @@ -1,23 +1,26 @@ .selectedIcon:before { - font-family: FontAwesome; - content: "\f046"; + font-family: FontAwesome; + content: "\f046"; } .emptyIcon:before { - font-family: FontAwesome; - content: "\f096"; + font-family: FontAwesome; + content: "\f096"; } .basemapsIcon:before { - font-family: FontAwesome; - content: "\f009"; + font-family: FontAwesome; + content: "\f009"; } /* condense dropdown on small screens */ -@media screen and (max-width: 600px) { - #basemaps_widget .dijitButtonText { +@media (max-width: 768px) { + .cmv .map .basemapWidget .dijitDropDownButton .dijitButtonNode { + padding: 4px 8px; + } + .cmv .map .basemapWidget .dijitButtonText { display: none; } } diff --git a/viewer/js/gis/dijit/Basemaps/templates/Basemaps.html b/viewer/js/gis/dijit/Basemaps/templates/Basemaps.html index fa8b65db1..637bf5056 100644 --- a/viewer/js/gis/dijit/Basemaps/templates/Basemaps.html +++ b/viewer/js/gis/dijit/Basemaps/templates/Basemaps.html @@ -1,4 +1,4 @@ -
+
${title} From 565e210cd3447c16484ce14faa694b784fc563f9 Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Fri, 26 May 2017 14:59:33 -0500 Subject: [PATCH 20/41] Add additional basemapWidget scope to css --- viewer/js/gis/dijit/Basemaps/css/Basemaps.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/viewer/js/gis/dijit/Basemaps/css/Basemaps.css b/viewer/js/gis/dijit/Basemaps/css/Basemaps.css index f628aa892..27e7c4134 100644 --- a/viewer/js/gis/dijit/Basemaps/css/Basemaps.css +++ b/viewer/js/gis/dijit/Basemaps/css/Basemaps.css @@ -1,14 +1,14 @@ -.selectedIcon:before { +.basemapWidget .selectedIcon:before { font-family: FontAwesome; content: "\f046"; } -.emptyIcon:before { +.basemapWidget .emptyIcon:before { font-family: FontAwesome; content: "\f096"; } -.basemapsIcon:before { +.basemapWidget .basemapsIcon:before { font-family: FontAwesome; content: "\f009"; } From 152106fc7a40adcef206873b128e04ff573d2260 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Wed, 31 May 2017 18:01:35 -0700 Subject: [PATCH 21/41] add the new _Sidebar mixin. --- viewer/js/config/app.js | 12 +- viewer/js/viewer/_SidebarMixin.js | 139 ++++++++++ viewer/js/viewer/sidebar/Sidebar.js | 204 ++++++++++++++ viewer/js/viewer/sidebar/css/Sidebar.css | 259 ++++++++++++++++++ .../js/viewer/sidebar/templates/Sidebar.html | 9 + 5 files changed, 621 insertions(+), 2 deletions(-) create mode 100644 viewer/js/viewer/_SidebarMixin.js create mode 100644 viewer/js/viewer/sidebar/Sidebar.js create mode 100644 viewer/js/viewer/sidebar/css/Sidebar.css create mode 100644 viewer/js/viewer/sidebar/templates/Sidebar.html diff --git a/viewer/js/config/app.js b/viewer/js/config/app.js index f83155e22..4727f61bd 100644 --- a/viewer/js/config/app.js +++ b/viewer/js/config/app.js @@ -34,9 +34,12 @@ 'viewer/_ConfigMixin', // manage the Configuration 'viewer/_LayoutMixin', // build and manage the Page Layout and User Interface 'viewer/_MapMixin', // build and manage the Map - 'viewer/_WidgetsMixin' // build and manage the Widgets + 'viewer/_WidgetsMixin', // build and manage the Widgets // 'viewer/_WebMapMixin' // for WebMaps + + 'viewer/_SidebarMixin' // for mobile sidebar + //'config/_customMixin' ], function ( @@ -46,9 +49,11 @@ _ConfigMixin, _LayoutMixin, _MapMixin, - _WidgetsMixin + _WidgetsMixin, // _WebMapMixin + + _SidebarMixin //_MyCustomMixin ) { @@ -66,6 +71,9 @@ // _WebMapMixin, _MapMixin, + // Mixin for Mobile Sidebar + _SidebarMixin, + // configMixin should be right before _ControllerBase so it is // called first to initialize the config object _ConfigMixin, diff --git a/viewer/js/viewer/_SidebarMixin.js b/viewer/js/viewer/_SidebarMixin.js new file mode 100644 index 000000000..aaecb0ccc --- /dev/null +++ b/viewer/js/viewer/_SidebarMixin.js @@ -0,0 +1,139 @@ +define([ + 'dojo/_base/declare', + 'dojo/_base/lang', + 'dojo/dom', + 'dojo/sniff', + + 'dojo/Deferred', + + 'put-selector', + 'module' + +], function ( + declare, + lang, + dom, + has, + + Deferred, + + put, + module, + + Sidebar +) { + + return declare(null, { + + postConfig: function () { + this.config.layout = this.config.layout || {}; + this._checkForSidebarLayout(); + + if (this.config.layout.sidebar) { + this.inherited(arguments); + + this.config.panes = this.mixinDeep(this.config.panes || {}, { + left: { + collapsible: false, + style: 'display:none !important' + } + }); + + var deferred = new Deferred(); + var modulesPath = module.uri.substring(0, module.uri.lastIndexOf('/')) + '/sidebar'; + window.dojoConfig.packages.push({ + name: 'sidebar', + main: 'Sidebar', + location: modulesPath + }); + require(window.dojoConfig, [ + 'sidebar/Sidebar' + ], lang.hitch(this, function (sidebar) { + Sidebar = sidebar; + this.mapDeferred.then(lang.hitch(this, '_createSidebar')); + deferred.resolve(); + })); + return deferred; + } + return this.inherited(arguments); + }, + + _checkForSidebarLayout: function () { + var sidebar = this.config.layout.sidebar; + + switch (sidebar) { + // all devices + case true: + break; + + // no devices + case false: + break; + + // tablets and phones + case 'mobile': + if (has('mobile')) { + sidebar = true; + } + break; + + // phones + case 'phone': + if (has('phone')) { + sidebar = true; + } + break; + default: + // perhaps they've configured something we don't expect + if (typeof(sidebar) === 'string') { + if (has(sidebar)) { + sidebar = true; + } + // default is just for phones + } else if (has('phone')) { + sidebar = true; + } + break; + } + this.config.layout.sidebar = sidebar; + }, + + _createSidebar: function () { + var mapContainer = dom.byId(this.config.layout.map || 'mapCenter'); + //create controls div + var mapControlsNode = put(this.map.root, 'div.sidebar-map'); + //move the slider into the controls div + put(mapControlsNode, '>', this.map._slider); + //create sidebar + this.sidebar = new Sidebar({ + map: this.map, + mapContainer: mapContainer, + collapseSyncNode: mapControlsNode + }, put(this.map.root, 'div')); + this.sidebar.startup(); + + this._createTitlePaneWidget = this._createTabPaneWidget; + }, + + _createTabPaneWidget: function (parentId, widgetConfig) { + var tabOptions = widgetConfig.tabOptions || { + id: parentId, + title: widgetConfig.title, + iconClass: widgetConfig.iconClass + }; + + var tab = this.sidebar.createTab(tabOptions); + tab.contentNode = put(tab.containerNode, 'div.sidebar-widget div.sidebar-widget-content'); + + var node = put(tab.contentNode, 'div'); + widgetConfig.type = 'domNode'; + widgetConfig.srcNodeRef = node; + this.createWidgets([ + { + options: widgetConfig + } + ]); + } + + }); +}); \ No newline at end of file diff --git a/viewer/js/viewer/sidebar/Sidebar.js b/viewer/js/viewer/sidebar/Sidebar.js new file mode 100644 index 000000000..7df98b78d --- /dev/null +++ b/viewer/js/viewer/sidebar/Sidebar.js @@ -0,0 +1,204 @@ +define([ + 'dojo/_base/declare', + 'dijit/_WidgetBase', + 'dijit/_TemplatedMixin', + + 'dojo/_base/lang', + 'dojo/_base/array', + 'dojo/query', + 'dojo/dom-class', + 'dojo/dom-geometry', + 'dojo/on', + 'dojo/aspect', + + 'dijit/registry', + + 'put-selector/put', + + 'dojo/text!./templates/Sidebar.html', + + 'xstyle/css!./css/Sidebar.css', + + 'dojo/NodeList-traverse' + +], function ( + declare, + _WidgetBase, + _TemplatedMixin, + + lang, + array, + query, + domClass, + domGeom, + on, + aspect, + + registry, + + put, + + template +) { + return declare([_WidgetBase, _TemplatedMixin], { + templateString: template, + baseClass: 'sidebar', + + defaultTabParams: { + title: 'Title', + iconClass: 'fa-bars' + }, + + viewPadding: { + top: 0, + left: 0, + right: 0, + bottom: 0 + }, + + showCloseIcon: true, + + collapseSyncNode: null, + + postCreate: function () { + this.inherited(arguments); + + this.tabs = []; + if (this.collapseSyncNode) { + if (domClass.contains(this.domNode, 'collapsed')) { + put(this.mapContainer, '.sidebar-collapsed'); + } + //wire up css transition callback covering all event name bases + on(this.collapseSyncNode, 'transitionend, oTransitionEnd, webkitTransitionEnd, animationend, webkitAnimationEnd', lang.hitch(this, '_setViewPadding')); + } + aspect.before(this.map, 'setExtent', lang.hitch(this, '_viewPaddingHandler')); + + // resize tab and any widgets within the tab when it is opened + on(this.domNode, 'transitionend, oTransitionEnd, webkitTransitionEnd, animationend, webkitAnimationEnd', lang.hitch(this, '_resizeActiveTab')); + + + // resize tab and any widgets within the tab when the browser is resized + on(window, 'resize', lang.hitch(this, function () { + window.setTimeout(lang.hitch(this, '_resizeActiveTab'), 300); // 300ms to wait for the animation to complete + })); + + }, + + createTab: function (options) { + options = lang.mixin(lang.clone(this.defaultTabParams), options || {}); + var tab = { + id: options.id, + buttonNode: null, + containerNode: null, + titleNode: null, + closeBtnNode: null, + contentNode: null + }; + //create and place dom elements for the tab button and pane + tab.buttonNode = put(this.tabsButtonNode, 'li a[role=tab] i.fa.' + options.iconClass + '<<'); + tab.containerNode = put(this.tabsContainerNode, 'div.' + this.baseClass + '-pane'); + tab.titleNode = put(tab.containerNode, 'div.' + this.baseClass + '-pane-title $', options.title); + + if (this.showCloseIcon) { + tab.closeBtnNode = put(tab.titleNode, 'i.fa.fa-chevron-left.' + this.baseClass + '-closeIcon'); + // listen for the tab close button click + on(tab.closeBtnNode, 'click', lang.hitch(this, 'tabClickHandler', tab)); + } + + // listen for the tab button click + on(tab.buttonNode, 'click', lang.hitch(this, 'tabClickHandler', tab)); + + //keep a reference to this tab + this.tabs.push(tab); + + //return the tabs pane node + return tab; + }, + + openTab: function (tab) { + array.forEach(this.tabs, function (childTab) { + put(childTab.buttonNode, '!active'); + put(childTab.containerNode, '!active'); + put(childTab.contentNode, '!active'); + }); + put(tab.buttonNode, '.active'); + put(tab.containerNode, '.active'); + put(tab.contentNode, '.active'); + put(this.tabsButtonNode, '.active'); + put(this.domNode, '!collapsed'); + put(this.mapContainer, '!sidebar-collapsed'); + }, + + closeTab: function () { + array.forEach(this.tabs, function (tab) { + put(tab.buttonNode, '!active'); + put(tab.containerNode, '!active'); + put(tab.contentNode, '!active'); + }, this); + put(this.tabsButtonNode, '!active'); + put(this.domNode, '.collapsed'); + put(this.mapContainer, '.sidebar-collapsed'); + }, + + tabClickHandler: function (tab) { + if (domClass.contains(tab.buttonNode, 'active')) { + this.closeTab(tab); + } else { + this.openTab(tab); + } + }, + + _setViewPadding: function () { + var dims = domGeom.getContentBox(this.domNode); + this.viewPadding = { + top: 0, + left: dims.w + dims.l, + right: 0, + bottom: 0 + }; + this._viewPaddingHandler(this.map.extent); + }, + + _viewPaddingHandler: function (extent) { + var map = this.map, + vp = this.viewPadding, + w = map.width - vp.left - vp.right, + h = map.height - vp.top - vp.bottom, + res = Math.max(extent.getWidth() / w, extent.getHeight() / h), + center = extent.getCenter(), + result = map.extent.expand(res / (map.extent.getWidth() / map.width)); + result = result.centerAt({ + x: center.x - (vp.left - vp.right) * 0.5 * res, + y: center.y - (vp.top - vp.bottom) * 0.5 * res + }); + return [result]; + }, + + _resizeActiveTab: function () { + var childTabs = array.filter(this.tabs, function (tab) { + return domClass.contains(tab.contentNode, 'active'); + }); + if (childTabs && childTabs.length > 0) { + var contentNode = query(childTabs[0].contentNode); + this._resizeWidgetsInNodeList(contentNode); + var children = contentNode.children(); + this._resizeWidgetsInNodeList(children); + } + }, + + _resizeWidgetsInNodeList: function (nodes) { + array.forEach(nodes, function (node) { + // resize any widgets + var childWidgets = registry.findWidgets(node); + array.forEach(childWidgets, function (widget) { + if (widget.resize && typeof(widget.resize) === 'function') { + window.setTimeout(function () { + widget.resize(); + }, 50); + } + }); + + }); + } + }); +}); \ No newline at end of file diff --git a/viewer/js/viewer/sidebar/css/Sidebar.css b/viewer/js/viewer/sidebar/css/Sidebar.css new file mode 100644 index 000000000..dcf02e15e --- /dev/null +++ b/viewer/js/viewer/sidebar/css/Sidebar.css @@ -0,0 +1,259 @@ +.cmv .sidebar { + bottom: 0; + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.5); + height: auto; + left: 0; + overflow: hidden; + position: absolute; + top: 0; + width: 100%; + z-index: 40; +} + +.cmv .sidebar.collapsed { + height: auto; + width: 40px; +} + +.cmv .sidebar-tabs { + background-color: #fff; + color: #444; + height: 100%; + margin: 0; + overflow-y: auto; + padding: 0; + position: absolute; + top: 0; + width: 40px; + z-index: 41; +} + +.cmv .sidebar-tabs.active { + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.5); +} + +.cmv .sidebar-tabs > li { + cursor: pointer; + float: none; + font-size: 14pt; + height: 40px; + overflow: hidden; + transition: all 80ms; + width: 100%; +} + +.cmv .sidebar-tabs > li:hover { + background-color: #444; + color: #fff; +} + +.cmv .sidebar-tabs > li.active { + background-color: #444; + color: #fff; +} + +.cmv .sidebar-tabs > li > a { + color: inherit; + display: block; + height: 100%; + line-height: 40px; + text-align: center; + text-decoration: none; + width: 100%; +} + +.cmv .sidebar-content { + background-color: #fff; + bottom: 0; + left: 40px; + overflow-x: hidden; + overflow-y: auto; + position: absolute; + right: 0; + top: 0; +} + +.cmv .sidebar-pane { + display: none; + right: 0; + width: 100%; +} + +.cmv .sidebar-pane.active { + display: block; +} + +.cmv .sidebar-pane-title { + background-color: #eee; + color: #333; + border-bottom: 1px solid #333; + font-size: 16px; + font-weight: bold; + height: 28px; + left: 0; + padding: 12px 10px 0 10px; + position: absolute; + right: 0; + top: 0; +} + +.cmv .sidebar .sidebar-pane-title .sidebar-closeIcon { + cursor: pointer; + float: right; +} + +.cmv .sidebar-widget { + bottom: 0; + left: 0; + overflow-x: hidden; + overflow-y: auto; + padding: 10px; + position: absolute; + right: 0; + top: 40px; +} + +.cmv .sidebar-widget .sidebar-widget-content { + position: relative; +} + + +/* esri map widgets */ +.cmv .map .sidebar-map { + left: 40px; + position: absolute; + top: 0; +} + +.cmv .map .cmv-widget-geocoder { + top: 15px; +} + +.cmv .sidebar, +.cmv .map .sidebar-map, +.cmv .map .cmv-widget, +.cmv .map .scalebar_bottom-left { + transition: left 300ms; +} + +@media (min-width: 768px) and (max-width: 991px) { + .cmv .sidebar { + width: 300px; + } + .cmv .map .sidebar-map { + left: 300px; + } + .cmv .map .cmv-widget-mapinfo { + left: 300px; + } + .cmv .map .cmv-widgets-left { + left: 314px; + } + .cmv .map .scalebar_bottom-left { + left: 325px !important; + } + .cmv .map .cmv-widget-geocoder { + left: 360px; + } + .cmv .sidebar .arcgisSearch .searchGroup .searchInput { + width: 150px; + } +} + +@media (min-width: 992px) and (max-width: 1199px) { + .cmv .sidebar { + width: 350px; + } + .cmv .map .sidebar-map { + left: 350px; + } + .cmv .map .cmv-widget-mapinfo { + left: 350px; + } + .cmv .map .cmv-widgets-left { + left: 364px; + } + .cmv .map .cmv-widget-geocoder { + left: 410px; + } + .cmv .map .scalebar_bottom-left { + left: 375px !important; + } + .cmv .sidebar .arcgisSearch .searchGroup .searchInput { + width: 200px; + } +} + +@media (min-width: 1200px) { + .cmv .sidebar { + width: 400px; + } + .cmv .map .sidebar-map { + left: 400px; + } + .cmv .map .cmv-widget-mapinfo { + left: 400px; + } + .cmv .map .cmv-widgets-left { + left: 414px; + } + .cmv .map .cmv-widget-geocoder { + left: 460px; + } + .cmv .map .scalebar_bottom-left { + left: 425px !important; + } + .cmv .sidebar .arcgisSearch .searchGroup .searchInput { + width: 250px; + } +} + +.cmv .sidebar-collapsed .sidebar-map { + left: 40px; +} + +.cmv .sidebar-collapsed .cmv-widget-mapinfo { + left: 40px; +} + +.cmv .sidebar-collapsed .cmv-widgets-left { + left: 54px; +} + +.cmv .sidebar-collapsed .cmv-widget-geocoder { + left: 100px; +} + +.cmv .sidebar-collapsed .scalebar_bottom-left { + left: 65px !important; +} + +/* simple zoom slider: positioning */ +.cmv .map .esriSimpleSliderTL { + left: 15px; + top: 15px; +} + +.cmv .map .esriSimpleSliderTR { + right: 15px; + top: 15px; +} + +/* simple zoom slider: horizontal */ + +.cmv .map .esriSimpleSliderHorizontal { + top: 10px; +} + +.cmv .map .esriSimpleSliderHorizontal.esriSimpleSliderBL { + left: 10px; +} + +.cmv .map .esriSimpleSliderHorizontal.esriSimpleSliderBR { + right: 10px; +} + +.cmv .map .cmv-widget-basemaps { + right: 10px; + top: 10px; +} \ No newline at end of file diff --git a/viewer/js/viewer/sidebar/templates/Sidebar.html b/viewer/js/viewer/sidebar/templates/Sidebar.html new file mode 100644 index 000000000..025e27262 --- /dev/null +++ b/viewer/js/viewer/sidebar/templates/Sidebar.html @@ -0,0 +1,9 @@ + From 67014f32934410adb0c03626925eb7fd20c22559 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Wed, 31 May 2017 18:02:42 -0700 Subject: [PATCH 22/41] move positioning of mapOverlay divs to css file easier configuration. --- viewer/css/main.css | 25 +++++++++++++++++++ viewer/js/viewer/templates/mapOverlay.html | 28 +++++++++------------- 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/viewer/css/main.css b/viewer/css/main.css index abf36af1f..29ddbce38 100644 --- a/viewer/css/main.css +++ b/viewer/css/main.css @@ -97,6 +97,31 @@ body, html { overflow: hidden; background: url("../images/noisy_grid.png") #fff; } +.cmv-widget { + position:absolute; + z-index:40; +} +.cmv-widget-mapinfo { + bottom: 0; + left: 0; +} +.cmv-widget-basemaps { + right: 20px; + top: 20px; +} +.cmv-widget-growler { + right: 20px; + top: 60px; + width: 250px; +} +.cmv-widgets-left { + left: 19px; + top: 87px; +} +.cmv-widget-geocoder { + left: 64px; + top: 20px; +} .panetop { border-top: 1px solid #B5BCC7; } diff --git a/viewer/js/viewer/templates/mapOverlay.html b/viewer/js/viewer/templates/mapOverlay.html index 42dd41a40..80d25080b 100644 --- a/viewer/js/viewer/templates/mapOverlay.html +++ b/viewer/js/viewer/templates/mapOverlay.html @@ -1,22 +1,16 @@ -
-
-
+
+
-
-
-
+
+
-
-
-
+
+
-
-
-
-
-
+
+
+
-
-
-
+
+
\ No newline at end of file From 5d6ebd5e25a12032d6afcb7ba657424b9da09ac8 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Wed, 31 May 2017 18:03:28 -0700 Subject: [PATCH 23/41] detect touch devices before the config is loaded. --- viewer/js/viewer/_LayoutMixin.js | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/viewer/js/viewer/_LayoutMixin.js b/viewer/js/viewer/_LayoutMixin.js index 4940098d1..db587d8ec 100644 --- a/viewer/js/viewer/_LayoutMixin.js +++ b/viewer/js/viewer/_LayoutMixin.js @@ -63,6 +63,12 @@ define([ } }, collapseButtons: {}, + + loadConfig: function () { + this.detectTouchDevices(); + this.inherited(arguments); + }, + postConfig: function () { this.layoutDeferred = new Deferred(); return this.inherited(arguments); @@ -73,7 +79,7 @@ define([ this.addTopics(); this.addTitles(); - this.detectTouchDevices(); + this.setPhoneInfoWindow(); this.initPanes(); this.mapDeferred.then(lang.hitch(this, 'createPanes')); @@ -321,7 +327,6 @@ define([ this.positionSideBarToggle(id); }, - // simple feature detection. kinda like dojox/mobile without the overhead detectTouchDevices: function () { if (has('touch') && (has('ios') || has('android') || has('bb'))) { has.add('mobile', true); @@ -330,11 +335,13 @@ define([ } else { has.add('tablet', true); } + } + }, - // use the mobile popup for phones - if (has('phone') && !this.config.mapOptions.infoWindow) { - this.config.mapOptions.infoWindow = new PopupMobile(null, put('div')); - } + setPhoneInfoWindow: function () { + // use the mobile popup for phones + if (has('phone') && !this.config.mapOptions.infoWindow) { + this.config.mapOptions.infoWindow = new PopupMobile(null, put('div')); } } From 6d792b6ebba2d04ad7b5309c6daea8556fdf4716 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Wed, 31 May 2017 18:04:04 -0700 Subject: [PATCH 24/41] Add nls for Search widget. --- viewer/js/config/nls/es/main.js | 1 + viewer/js/config/nls/fr/main.js | 1 + viewer/js/config/nls/main.js | 1 + viewer/js/config/nls/pt-br/main.js | 1 + viewer/js/config/nls/pt-pt/main.js | 1 + 5 files changed, 5 insertions(+) diff --git a/viewer/js/config/nls/es/main.js b/viewer/js/config/nls/es/main.js index 47acf6117..fee18694a 100644 --- a/viewer/js/config/nls/es/main.js +++ b/viewer/js/config/nls/es/main.js @@ -44,6 +44,7 @@ define({ legend: 'Leyenda', locale: 'Lugar', print: 'Imprimir', + search: 'Buscar', streetview: 'Google Street View' } } diff --git a/viewer/js/config/nls/fr/main.js b/viewer/js/config/nls/fr/main.js index dbf7b877d..b95757dba 100644 --- a/viewer/js/config/nls/fr/main.js +++ b/viewer/js/config/nls/fr/main.js @@ -44,6 +44,7 @@ define({ legend: 'Légende', locale: 'Lieu', print: 'Impression', + search: 'Rechercher', streetview: 'Google StreetView' } } diff --git a/viewer/js/config/nls/main.js b/viewer/js/config/nls/main.js index 2a9a8a606..a1ca815cd 100644 --- a/viewer/js/config/nls/main.js +++ b/viewer/js/config/nls/main.js @@ -46,6 +46,7 @@ define({ legend: 'Legend', locale: 'Locale', print: 'Print', + search: 'Search', streetview: 'Google Street View' } } diff --git a/viewer/js/config/nls/pt-br/main.js b/viewer/js/config/nls/pt-br/main.js index 3bb82f665..818970576 100644 --- a/viewer/js/config/nls/pt-br/main.js +++ b/viewer/js/config/nls/pt-br/main.js @@ -44,6 +44,7 @@ define({ legend: 'Legendas', locale: 'Localidade', print: 'Imprimir', + search: 'Pesquisar', streetview: 'Google Street View' } } diff --git a/viewer/js/config/nls/pt-pt/main.js b/viewer/js/config/nls/pt-pt/main.js index 3bb82f665..818970576 100644 --- a/viewer/js/config/nls/pt-pt/main.js +++ b/viewer/js/config/nls/pt-pt/main.js @@ -44,6 +44,7 @@ define({ legend: 'Legendas', locale: 'Localidade', print: 'Imprimir', + search: 'Pesquisar', streetview: 'Google Street View' } } From 5269f5377d8c6c1b60a49e040f242102b04f9a95 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Wed, 31 May 2017 18:37:26 -0700 Subject: [PATCH 25/41] document the options for mobile sidebar demonstrate use of `has/sniff` to configure the widgets based on the device --- viewer/js/config/viewer.js | 41 ++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index e3511b6ff..1b97e572c 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -7,8 +7,9 @@ define([ 'esri/layers/ImageParameters', 'gis/plugins/Google', 'dojo/i18n!./nls/main', - 'dojo/topic' -], function (units, Extent, esriConfig, /*urlUtils,*/ GeometryService, ImageParameters, GoogleMapsLoader, i18n, topic) { + 'dojo/topic', + 'dojo/sniff' +], function (units, Extent, esriConfig, /*urlUtils,*/ GeometryService, ImageParameters, GoogleMapsLoader, i18n, topic, has) { // url to your proxy page, must be on same machine hosting you app. See proxy folder for readme. esriConfig.defaults.io.proxyUrl = 'proxy/proxy.ashx'; @@ -120,6 +121,18 @@ define([ pageTitle: i18n.viewer.titles.pageTitle }, + layout: { + /* possible options for sidebar layout: + true - always use mobile sidebar, false - never use mobile sidebar, + 'mobile' - use sidebar for phones and tablets, 'phone' - use sidebar for phones, + 'touch' - use sidebar for all touch devices, 'tablet' - use sidebar for tablets only (not sure why you'd do this?), + other feature detection supported by dojo/sniff and dojo/has- http://dojotoolkit.org/reference-guide/1.10/dojo/sniff.html + + default value is 'phone' + */ + //sidebar: 'phone' + }, + // user-defined layer types /* layerTypes: { @@ -306,15 +319,18 @@ define([ }, search: { include: true, - type: 'domNode', + type: has('phone') ? 'titlePane' : 'domNode', path: 'esri/dijit/Search', srcNodeRef: 'geocoderButton', + title: i18n.viewer.widgets.search, + iconClass: 'fa-search', + position: 0, options: { map: true, visible: true, enableInfoWindow: false, - enableButtonMode: true, - expanded: false + enableButtonMode: has('phone') ? false : true, + expanded: has('phone') ? true : false } }, basemaps: { @@ -384,7 +400,7 @@ define([ } }, overviewMap: { - include: true, + include: has('phone') ? false : true, id: 'overviewMap', type: 'map', path: 'esri/dijit/OverviewMap', @@ -564,7 +580,7 @@ define([ } }, editor: { - include: true, + include: has('phone') ? false : true, id: 'editor', type: 'titlePane', path: 'gis/dijit/Editor', @@ -617,20 +633,19 @@ define([ }, locale: { include: true, + type: has('phone') ? 'titlePane' : 'domNode', id: 'locale', - //type: 'titlePane', - //position: 0, - //open: true, - type: 'domNode', + position: 0, srcNodeRef: 'geocodeDijit', path: 'gis/dijit/Locale', title: i18n.viewer.widgets.locale, + iconClass: 'fa-flag', options: { - style: 'margin-left: 30px;' + style: has('phone') ? null : 'margin-left: 30px;' } }, help: { - include: true, + include: has('phone') ? false : true, id: 'help', type: 'floating', path: 'gis/dijit/Help', From c2e60859d9cb1024139f18740482a1b4bb52d1ad Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Thu, 1 Jun 2017 08:00:48 -0700 Subject: [PATCH 26/41] remove dynamic requires. --- viewer/js/viewer/_SidebarMixin.js | 31 +++++-------------------------- 1 file changed, 5 insertions(+), 26 deletions(-) diff --git a/viewer/js/viewer/_SidebarMixin.js b/viewer/js/viewer/_SidebarMixin.js index aaecb0ccc..70eb941ff 100644 --- a/viewer/js/viewer/_SidebarMixin.js +++ b/viewer/js/viewer/_SidebarMixin.js @@ -4,10 +4,9 @@ define([ 'dojo/dom', 'dojo/sniff', - 'dojo/Deferred', - 'put-selector', - 'module' + + './sidebar/Sidebar' ], function ( declare, @@ -15,10 +14,7 @@ define([ dom, has, - Deferred, - put, - module, Sidebar ) { @@ -26,36 +22,19 @@ define([ return declare(null, { postConfig: function () { + this.inherited(arguments); this.config.layout = this.config.layout || {}; this._checkForSidebarLayout(); if (this.config.layout.sidebar) { - this.inherited(arguments); - this.config.panes = this.mixinDeep(this.config.panes || {}, { left: { collapsible: false, style: 'display:none !important' } }); - - var deferred = new Deferred(); - var modulesPath = module.uri.substring(0, module.uri.lastIndexOf('/')) + '/sidebar'; - window.dojoConfig.packages.push({ - name: 'sidebar', - main: 'Sidebar', - location: modulesPath - }); - require(window.dojoConfig, [ - 'sidebar/Sidebar' - ], lang.hitch(this, function (sidebar) { - Sidebar = sidebar; - this.mapDeferred.then(lang.hitch(this, '_createSidebar')); - deferred.resolve(); - })); - return deferred; + this.mapDeferred.then(lang.hitch(this, '_createSidebar')); } - return this.inherited(arguments); }, _checkForSidebarLayout: function () { @@ -99,7 +78,7 @@ define([ }, _createSidebar: function () { - var mapContainer = dom.byId(this.config.layout.map || 'mapCenter'); + var mapContainer = dom.byId(this.map.id); //create controls div var mapControlsNode = put(this.map.root, 'div.sidebar-map'); //move the slider into the controls div From bf96ff84ec0d01d9ed858c6fc9f84866b545e470 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sat, 10 Jun 2017 15:57:55 -0700 Subject: [PATCH 27/41] return this.inherited --- viewer/js/viewer/_LayoutMixin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/viewer/js/viewer/_LayoutMixin.js b/viewer/js/viewer/_LayoutMixin.js index db587d8ec..8d857c58e 100644 --- a/viewer/js/viewer/_LayoutMixin.js +++ b/viewer/js/viewer/_LayoutMixin.js @@ -66,7 +66,7 @@ define([ loadConfig: function () { this.detectTouchDevices(); - this.inherited(arguments); + return this.inherited(arguments); }, postConfig: function () { From 836ab8896646e6043b9f9afcb5790fd4f3c56317 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sat, 10 Jun 2017 15:58:28 -0700 Subject: [PATCH 28/41] CSS refinements --- viewer/js/viewer/sidebar/css/Sidebar.css | 57 ++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/viewer/js/viewer/sidebar/css/Sidebar.css b/viewer/js/viewer/sidebar/css/Sidebar.css index dcf02e15e..c1ee89cea 100644 --- a/viewer/js/viewer/sidebar/css/Sidebar.css +++ b/viewer/js/viewer/sidebar/css/Sidebar.css @@ -114,6 +114,7 @@ } .cmv .sidebar-widget .sidebar-widget-content { + padding: 5px; position: relative; } @@ -136,6 +137,30 @@ transition: left 300ms; } +@media (max-width: 320px) { + .cmv .sidebar .arcgisSearch .searchGroup .searchInput { + width: 100px; + } +} + +@media (min-width: 321px) and (max-width: 400px) { + .cmv .sidebar .arcgisSearch .searchGroup .searchInput { + width: 140px; + } +} + +@media (min-width: 401px) and (max-width: 767px) { + .cmv .sidebar .arcgisSearch .searchGroup .searchInput { + width: 160px; + } +} + +@media (max-width: 767px) { + .cmv .sidebar-widget .sidebar-widget-content { + zoom: 1.25; + } +} + @media (min-width: 768px) and (max-width: 991px) { .cmv .sidebar { width: 300px; @@ -156,7 +181,7 @@ left: 360px; } .cmv .sidebar .arcgisSearch .searchGroup .searchInput { - width: 150px; + width: 140px; } } @@ -180,11 +205,11 @@ left: 375px !important; } .cmv .sidebar .arcgisSearch .searchGroup .searchInput { - width: 200px; + width: 190px; } } -@media (min-width: 1200px) { +@media (min-width: 1200px) and (max-width: 1800px) { .cmv .sidebar { width: 400px; } @@ -204,7 +229,31 @@ left: 425px !important; } .cmv .sidebar .arcgisSearch .searchGroup .searchInput { - width: 250px; + width: 240px; + } +} + +@media (min-width: 1800px) { + .cmv .sidebar { + width: 450px; + } + .cmv .map .sidebar-map { + left: 450px; + } + .cmv .map .cmv-widget-mapinfo { + left: 450px; + } + .cmv .map .cmv-widgets-left { + left: 464px; + } + .cmv .map .cmv-widget-geocoder { + left: 510px; + } + .cmv .map .scalebar_bottom-left { + left: 475px !important; + } + .cmv .sidebar .arcgisSearch .searchGroup .searchInput { + width: 290px; } } From 1f18a314ba27e0ee6ee917d7f943deb7a28645e6 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sat, 10 Jun 2017 16:05:05 -0700 Subject: [PATCH 29/41] revert to dynamic require so sidebar css doesn't imact non-sidebar configurations. build-friendly alternatives welcome --- viewer/js/viewer/_SidebarMixin.js | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/viewer/js/viewer/_SidebarMixin.js b/viewer/js/viewer/_SidebarMixin.js index 70eb941ff..db65fe722 100644 --- a/viewer/js/viewer/_SidebarMixin.js +++ b/viewer/js/viewer/_SidebarMixin.js @@ -3,16 +3,18 @@ define([ 'dojo/_base/lang', 'dojo/dom', 'dojo/sniff', + 'dojo/Deferred', + 'module', - 'put-selector', - - './sidebar/Sidebar' + 'put-selector' ], function ( declare, lang, dom, has, + Deferred, + module, put, @@ -22,19 +24,28 @@ define([ return declare(null, { postConfig: function () { - this.inherited(arguments); this.config.layout = this.config.layout || {}; this._checkForSidebarLayout(); if (this.config.layout.sidebar) { + this.inherited(arguments); this.config.panes = this.mixinDeep(this.config.panes || {}, { left: { collapsible: false, style: 'display:none !important' } }); - this.mapDeferred.then(lang.hitch(this, '_createSidebar')); + var deferred = new Deferred(); + require([ + module.uri.substring(0, module.uri.lastIndexOf('/')) + '/sidebar/Sidebar.js' + ], lang.hitch(this, function (sidebar) { + Sidebar = sidebar; + this.mapDeferred.then(lang.hitch(this, '_createSidebar')); + deferred.resolve(); + })); + return deferred; } + return this.inherited(arguments); }, _checkForSidebarLayout: function () { From 0ff16c1f73429c55151a7bb9a8feed5854643e19 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sat, 10 Jun 2017 16:05:40 -0700 Subject: [PATCH 30/41] change mixin order --- viewer/js/config/app.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/viewer/js/config/app.js b/viewer/js/config/app.js index 4727f61bd..87061e9bb 100644 --- a/viewer/js/config/app.js +++ b/viewer/js/config/app.js @@ -66,14 +66,15 @@ // for the most part they are interchangeable, except _ConfigMixin // and _ControllerBase // + + // Mixin for Mobile Sidebar + _SidebarMixin, + _LayoutMixin, _WidgetsMixin, // _WebMapMixin, _MapMixin, - // Mixin for Mobile Sidebar - _SidebarMixin, - // configMixin should be right before _ControllerBase so it is // called first to initialize the config object _ConfigMixin, From ece4714292b695d5b8f55e3b0160272ccbe02c09 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sat, 10 Jun 2017 16:13:34 -0700 Subject: [PATCH 31/41] update to Esri JS API upcoming version 3.21 --- viewer/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/viewer/index.html b/viewer/index.html index 6dbebc88c..687153790 100644 --- a/viewer/index.html +++ b/viewer/index.html @@ -11,7 +11,7 @@ Configurable Map Viewer - + @@ -50,7 +50,7 @@ - + From 0d491fd3cdd3cf294b863cbbb0dac52be2c5317a Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Tue, 13 Jun 2017 21:56:05 -0700 Subject: [PATCH 32/41] Don't load a titlePane widget until the pane is opened. Should this be the default or optional? --- viewer/js/config/viewer.js | 1 + viewer/js/viewer/_WidgetsMixin.js | 21 +++++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index e3511b6ff..5c8e6b20b 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -333,6 +333,7 @@ define([ title: i18n.viewer.widgets.identify, iconClass: 'fa-info-circle', open: false, + loadOnOpen: false, position: 3, options: 'config/identify' }, diff --git a/viewer/js/viewer/_WidgetsMixin.js b/viewer/js/viewer/_WidgetsMixin.js index 8ab99d897..5f075945f 100644 --- a/viewer/js/viewer/_WidgetsMixin.js +++ b/viewer/js/viewer/_WidgetsMixin.js @@ -2,6 +2,7 @@ define([ 'dojo/_base/declare', 'dojo/_base/array', 'dojo/_base/lang', + 'dojo/aspect', 'dojo/promise/all', 'dojo/Deferred', @@ -17,6 +18,7 @@ define([ declare, array, lang, + aspect, promiseAll, Deferred, @@ -158,20 +160,31 @@ define([ this._showWidgetLoader(pnl); } - // 2 ways to use require to accommodate widgets that may have an optional separate configuration file var deferred = new Deferred(); + if ((widgetConfig.type === 'titlePane') && (widgetConfig.loadOnOpen !== false) && !pnl.get('open')) { + widgetConfig.delayHandle = aspect.after(pnl, 'toggle', lang.hitch(this, '_loadWidget', widgetConfig, deferred)); + } else { + this._loadWidget(widgetConfig, deferred); + } + return deferred; + }, + + _loadWidget: function (widgetConfig, deferred) { + // 2 ways to use require to accommodate widgets that may have an optional separate configuration file if (typeof(widgetConfig.options) === 'string') { require([widgetConfig.options, widgetConfig.path], lang.hitch(this, function (options, WidgetClass) { - deferred.resolve(); this.createWidget(widgetConfig, options, WidgetClass); + deferred.resolve(); })); } else { require([widgetConfig.path], lang.hitch(this, function (WidgetClass) { - deferred.resolve(); this.createWidget(widgetConfig, widgetConfig.options, WidgetClass); + deferred.resolve(); })); } - return deferred; + if (widgetConfig.delayHandle) { + widgetConfig.delayHandle.remove(); + } }, createWidget: function (widgetConfig, options, WidgetClass) { From 2031079258e5e23c5d5c4810492830ddcaffeee9 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sun, 25 Jun 2017 09:36:38 +0900 Subject: [PATCH 33/41] move logic for Help link to FloatingWidgetDialog. this allows support for lazy-load of floating widgets. also allows re-usability for other widgets.. add support for iconClass for Floating widgets. --- viewer/js/config/viewer.js | 7 +++++++ viewer/js/gis/dijit/FloatingWidgetDialog.js | 21 +++++++++++++++++-- .../css/FloatingWidgetDialog.css | 3 +++ viewer/js/gis/dijit/Help.js | 11 +--------- viewer/js/gis/dijit/Help/css/Help.css | 16 +++++++------- viewer/js/gis/dijit/Help/nls/es/resource.js | 1 - viewer/js/gis/dijit/Help/nls/fr/resource.js | 1 - .../js/gis/dijit/Help/nls/pt-br/resource.js | 1 - .../js/gis/dijit/Help/nls/pt-pt/resource.js | 1 - viewer/js/gis/dijit/Help/nls/resource.js | 1 - viewer/js/viewer/_WidgetsMixin.js | 3 ++- 11 files changed, 40 insertions(+), 26 deletions(-) create mode 100644 viewer/js/gis/dijit/FloatingWidgetDialog/css/FloatingWidgetDialog.css diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index 323248716..f305d0a6d 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -651,6 +651,13 @@ define([ type: 'floating', path: 'gis/dijit/Help', title: i18n.viewer.widgets.help, + iconClass: 'fa-info-circle', + paneOptions: { + draggable: false, + html: 'link'.replace('link', i18n.viewer.widgets.help), + domTarget: 'helpDijit', + style: 'height:345px;width:450px;' + }, options: {} } diff --git a/viewer/js/gis/dijit/FloatingWidgetDialog.js b/viewer/js/gis/dijit/FloatingWidgetDialog.js index 42a0170fa..ee25613ca 100644 --- a/viewer/js/gis/dijit/FloatingWidgetDialog.js +++ b/viewer/js/gis/dijit/FloatingWidgetDialog.js @@ -1,13 +1,30 @@ define([ 'dojo/_base/declare', - 'dijit/Dialog' -], function (declare, Dialog) { + 'dijit/Dialog', + 'dojo/_base/lang', + 'dojo/on', + 'dojo/dom-construct', + + 'xstyle/css!./FloatingWidgetDialog/css/FloatingWidgetDialog.css' +], function (declare, Dialog, lang, on, domConstruct) { return declare([Dialog], { declaredClass: 'gis.dijit.FloatingWidget', title: 'Floating Widget', draggable: true, 'class': 'floatingWidget', + postCreate: function () { + if (this.iconClass) { + this.iconNode = domConstruct.create('span', { + 'class': 'titlePaneIcon fa fa-fw ' + this.iconClass + }, this.titleNode, 'before'); + } + if (this.html && this.domTarget) { + var link = domConstruct.place(this.html, this.domTarget); + this.own(on(link, 'click', lang.hitch(this, 'show'))); + } + this.inherited(arguments); + }, close: function () { this.hide(); }, diff --git a/viewer/js/gis/dijit/FloatingWidgetDialog/css/FloatingWidgetDialog.css b/viewer/js/gis/dijit/FloatingWidgetDialog/css/FloatingWidgetDialog.css new file mode 100644 index 000000000..0947a7266 --- /dev/null +++ b/viewer/js/gis/dijit/FloatingWidgetDialog/css/FloatingWidgetDialog.css @@ -0,0 +1,3 @@ +.dijitDialogTitleBar .titlePaneIcon { + margin: 0 4px 0 0; +} \ No newline at end of file diff --git a/viewer/js/gis/dijit/Help.js b/viewer/js/gis/dijit/Help.js index 461a374d1..5375d3b03 100644 --- a/viewer/js/gis/dijit/Help.js +++ b/viewer/js/gis/dijit/Help.js @@ -4,8 +4,6 @@ define([ 'dijit/_TemplatedMixin', 'dijit/_WidgetsInTemplateMixin', 'gis/dijit/_FloatingWidgetMixin', - 'dojo/dom-construct', - 'dojo/on', 'dojo/_base/lang', 'dojo/aspect', 'dojo/text!./Help/templates/HelpDialog.html', @@ -14,26 +12,19 @@ define([ 'dijit/layout/TabContainer', 'dijit/layout/ContentPane', 'xstyle/css!./Help/css/Help.css' -], function (declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, _FloatingWidgetMixin, domConstruct, on, lang, aspect, template, i18n) { +], function (declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, _FloatingWidgetMixin, lang, aspect, template, i18n) { return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, _FloatingWidgetMixin], { widgetsInTemplate: true, templateString: template, i18n: i18n, - html: 'link'.replace('link', i18n.link), - domTarget: 'helpDijit', - draggable: false, baseClass: 'helpDijit', postCreate: function () { this.inherited(arguments); - this.parentWidget.draggable = this.draggable; if (this.parentWidget.toggleable) { this.own(aspect.after(this.parentWidget, 'toggle', lang.hitch(this, function () { this.containerNode.resize(); }))); - } else { - var help = domConstruct.place(this.html, this.domTarget); - on(help, 'click', lang.hitch(this.parentWidget, 'show')); } }, onOpen: function () { diff --git a/viewer/js/gis/dijit/Help/css/Help.css b/viewer/js/gis/dijit/Help/css/Help.css index 5900f2ba1..d153d3176 100644 --- a/viewer/js/gis/dijit/Help/css/Help.css +++ b/viewer/js/gis/dijit/Help/css/Help.css @@ -1,21 +1,21 @@ -.helpDijit .listdbootstrapFix{ +.helpDijit .listdbootstrapFix { padding: 0 0 0 25px; } .helpDijit .helpContainer { - padding: 0px; + padding: 0; } + .floatingWidget .helpDijit .helpContainer { padding: 5px; } + .helpDijit .helpNode { - width: 98%; - height: 325px; -} -.floatingWidget .helpDijit .helpNode { - width: 450px; + height:280px; + width: 100%; } + .helpDijit .helpTabContainer { - width: 100%; height: 100%; + width: 100%; } \ No newline at end of file diff --git a/viewer/js/gis/dijit/Help/nls/es/resource.js b/viewer/js/gis/dijit/Help/nls/es/resource.js index 6c4cea412..3f80ea63d 100644 --- a/viewer/js/gis/dijit/Help/nls/es/resource.js +++ b/viewer/js/gis/dijit/Help/nls/es/resource.js @@ -1,5 +1,4 @@ define ({ - link: 'Ayuda', navigation: { title: 'Navegación', description: 'Mapa de navegación a través del ratón y el teclado:', diff --git a/viewer/js/gis/dijit/Help/nls/fr/resource.js b/viewer/js/gis/dijit/Help/nls/fr/resource.js index 6bda3e07f..719cc48f9 100644 --- a/viewer/js/gis/dijit/Help/nls/fr/resource.js +++ b/viewer/js/gis/dijit/Help/nls/fr/resource.js @@ -1,5 +1,4 @@ define ({ - link: 'Aide', navigation: { title: 'Navigation', description: 'Navigation dans la carte en utilisant la souris et le clavier:', diff --git a/viewer/js/gis/dijit/Help/nls/pt-br/resource.js b/viewer/js/gis/dijit/Help/nls/pt-br/resource.js index 2793d85a8..8dc3218cd 100644 --- a/viewer/js/gis/dijit/Help/nls/pt-br/resource.js +++ b/viewer/js/gis/dijit/Help/nls/pt-br/resource.js @@ -1,5 +1,4 @@ define({ - link: 'Ajuda', navigation: { title: 'Navegação', description: 'Navegação no mapa usando o rato e o teclado', diff --git a/viewer/js/gis/dijit/Help/nls/pt-pt/resource.js b/viewer/js/gis/dijit/Help/nls/pt-pt/resource.js index 2793d85a8..8dc3218cd 100644 --- a/viewer/js/gis/dijit/Help/nls/pt-pt/resource.js +++ b/viewer/js/gis/dijit/Help/nls/pt-pt/resource.js @@ -1,5 +1,4 @@ define({ - link: 'Ajuda', navigation: { title: 'Navegação', description: 'Navegação no mapa usando o rato e o teclado', diff --git a/viewer/js/gis/dijit/Help/nls/resource.js b/viewer/js/gis/dijit/Help/nls/resource.js index 137c491ff..f7816fc9c 100644 --- a/viewer/js/gis/dijit/Help/nls/resource.js +++ b/viewer/js/gis/dijit/Help/nls/resource.js @@ -1,6 +1,5 @@ define({ root: { - link: 'Help', navigation: { title: 'Navigation', description: 'Map navigation using mouse and keyboard:', diff --git a/viewer/js/viewer/_WidgetsMixin.js b/viewer/js/viewer/_WidgetsMixin.js index 5f075945f..fcb642765 100644 --- a/viewer/js/viewer/_WidgetsMixin.js +++ b/viewer/js/viewer/_WidgetsMixin.js @@ -295,7 +295,8 @@ define([ _createFloatingWidget: function (parentId, widgetConfig) { var options = lang.mixin({ - title: widgetConfig.title + title: widgetConfig.title, + iconClass: widgetConfig.iconClass }, widgetConfig.paneOptions || {}); if (parentId) { options.id = parentId; From 5e10bfaccf1d59c8e0253339571947e177439a6a Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sun, 25 Jun 2017 10:06:02 +0900 Subject: [PATCH 34/41] move titlePaneIcon class from cmv-theme-overrides.css to FloatingTitlePane.css rearrange some styles in cmv-theme-overrides.css improved button css in cmv-theme-overrides.css for flat theme. --- viewer/css/cmv-theme-overrides.css | 130 +++++++++++------- .../css/FloatingTitlePane.css | 14 +- 2 files changed, 94 insertions(+), 50 deletions(-) diff --git a/viewer/css/cmv-theme-overrides.css b/viewer/css/cmv-theme-overrides.css index 55219bc4a..6913a9f3e 100644 --- a/viewer/css/cmv-theme-overrides.css +++ b/viewer/css/cmv-theme-overrides.css @@ -3,13 +3,13 @@ } .cmv .dijitTitlePane { - margin-bottom: 2px; background-color: #FFF; + margin-bottom: 2px; } .cmv .dijitTitlePaneTitle { - color: #666; background-color: #F5F5F5; + color: #666; } .cmv .dijitTitlePaneTitleOpen { @@ -25,13 +25,6 @@ outline: none !important; } -/* icons for the sidebar */ -.cmv .dijitTitlePane .dijitTitlePaneTitle .titlePaneIcon { - margin: 0 0 0 8px; - padding-top: 2px; -} -/* end custom icons */ - /* esri popup window overrides */ .cmv .esriPopup .sizer { @@ -41,32 +34,38 @@ .cmv .esriPopup .esriPopupWrapper { background-color: #FFFFFF; } + .cmv .esriPopup .attachmentsSection div { font-weight: bold; } + .cmv .esriPopup .contentPane table.attrTable { - width: 100%; border-collapse: collapse; + width: 100%; } + .cmv .esriPopup .contentPane table.attrTable td { padding: 2px; } + .cmv .esriPopup .contentPane table.attrTable td.attrName { - text-align: right; - font-weight: bold; color: #333333; - width: 40%; + font-weight: bold; padding-right: 5px; + text-align: right; + width: 40%; } + .cmv .esriPopup .contentPane table.attrTable td.attrValue { width: 60%; } + .cmv .esriPopup .contentPane table.attrTable tr { - vertical-align: top; border-bottom: 1px solid rgb(221, 221, 221); + vertical-align: top; } .cmv .esriPopup .contentPane table.attrTable tr:nth-child(odd) { - background-color: none; + background-color: transparent; } .cmv .esriPopup .contentPane table.attrTable tr:nth-child(even) { background-color: rgb(238, 238, 238); @@ -79,24 +78,23 @@ .cmv .esriPopupMobile { z-index: 999; } -.cmv .esriMobileNavigationBar { - background-color: #666666; - background: url("../images/linen.jpg") repeat-x scroll left top transparent; - color: #FFFFFF; -} + +.cmv .esriMobileNavigationBar, .cmv .esriPopupMobile .titlePane { - background-color: #666666; background: url("../images/linen.jpg") repeat-x scroll left top transparent; + background-color: #666666; color: #FFFFFF; } + .cmv .esriPopupMobile .pointer.bottom{ - background:url("../images/pointertop.png"); -webkit-transform: rotate(180deg); -moz-transform: rotate(180deg); -o-transform: rotate(180deg); -ms-transform: rotate(180deg); transform: rotate(180deg); } + +.cmv .esriPopupMobile .pointer.bottom, .cmv .esriPopupMobile .pointer.top { background:url("../images/pointertop.png"); } @@ -117,11 +115,12 @@ background-repeat: repeat-x; border: 1px solid #BBB; border-bottom: 1px solid #A8A8A8; - padding: 0px 12px; color: #000; letter-spacing: 0; + padding: 0 12px; text-transform: none; } + .cmv .simpleDirections .esriStopsGetDirections:before { content: '\f277'; font-family: 'FontAwesome'; @@ -156,9 +155,9 @@ background-image: -ms-linear-gradient(bottom, #fff 0%, #e6e6e6 100%); background-image: linear-gradient(bottom, #fff 0%, #e6e6e6 100%); background-repeat: repeat-x; - box-shadow: inset 0 2px 4px rgba(0,0,0,0.4), 0 1px 1px rgba(0,0,0,0.2); - border-top-color: #444; border-color: #666; + border-top-color: #444; + box-shadow: inset 0 2px 4px rgba(0,0,0,0.4), 0 1px 1px rgba(0,0,0,0.2); -webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,0.4), 0 1px 1px rgba(0,0,0,0.2); } @@ -185,15 +184,16 @@ } .flat .dijitTabContainerTop-tabs .dijitTabChecked:before { - height: 3px; background-color: #666; - top: -1px; + height: 3px; left: -1px; right: -1px; + top: -1px; } .flat .dijitTitlePaneTitle { border: 1px solid #DDD; + border-bottom: none; -webkit-border-radius: 4px; border-radius: 4px; padding: 8px 15px; @@ -209,20 +209,56 @@ border-top: none; } +.flat .dijitButton .dijitButtonNode .dijitIcon.fa, +.flat .dijitDropDownButton .dijitButtonNode .dijitIcon.fa, +.flat .dijitComboButton .dijitButtonNode .dijitIcon.fa { + margin-top: 4px; +} + +.flat .dijitButton .dijitButtonNode, +.flat .dijitDropDownButton .dijitButtonNode, +.flat .dijitComboButton .dijitButtonNode, +.flat .dijitToggleButton .dijitButtonNode, +.flat .dijitComboBox .dijitButtonNode, +.flat .dijitSpinnerButtonContainer.dijitButtonNode, +.flat .dijitSelect .dijitButtonNode { + background-color: #E6E6E6; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #fff), color-stop(1, #e6e6e6)); + background-image: -webkit-linear-gradient(top, #fff 0%, #e6e6e6 100%); + background-image: -moz-linear-gradient(top, #fff 0%, #e6e6e6 100%); + background-image: -o-linear-gradient(top, #fff 0%, #e6e6e6 100%); + background-image: -ms-linear-gradient(top, #fff 0%, #e6e6e6 100%); + background-image: linear-gradient(top, #fff 0%, #e6e6e6 100%); + background-repeat: repeat-x; + border-bottom-color: #A8A8A8; + border-color: #BBB; + padding: 4px 12px; +} + +.flat .dijitComboBox .dijitArrowButton, +.flat .dijitSelect .dijitArrowButton { + padding: 4px; +} + +.flat .dijitSpinner .dijitSpinnerButtonContainer { + padding: 0; +} + .flat .dijitButtonHover .dijitButtonNode, .flat .dijitDropDownButtonHover .dijitButtonNode, .flat .dijitComboButton .dijitButtonNodeHover, .flat .dijitComboButton .dijitDownArrowButtonHover, .flat .dijitToggleButtonHover .dijitButtonNode, .flat .dijitDropDownButtonActive .dijitButtonNode { - background-position: 0 -15px; - text-decoration: none; - transition: background-position 0.1s linear; - -moz-transition: background-position 0.1s linear; - -ms-transition: background-position 0.1s linear; - -o-transition: background-position 0.1s linear; - -webkit-transition: background-position 0.1s linear; + background-position: 0 -15px; + text-decoration: none; + transition: background-position 0.1s linear; + -moz-transition: background-position 0.1s linear; + -ms-transition: background-position 0.1s linear; + -o-transition: background-position 0.1s linear; + -webkit-transition: background-position 0.1s linear; } + .flat .dijitButtonActive .dijitButtonNode, .flat .dijitComboButton .dijitButtonNodeActive, .flat .dijitToggleButtonActive .dijitButtonNode, @@ -235,11 +271,12 @@ background-image: -ms-linear-gradient(bottom, #fff 0%, #e6e6e6 100%); background-image: linear-gradient(bottom, #fff 0%, #e6e6e6 100%); background-repeat: repeat-x; - box-shadow: inset 0 2px 4px rgba(0,0,0,0.4), 0 1px 1px rgba(0,0,0,0.2); - border-top-color: #444; border-color: #666; + border-top-color: #444; -webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,0.4), 0 1px 1px rgba(0,0,0,0.2); + box-shadow: inset 0 2px 4px rgba(0,0,0,0.4), 0 1px 1px rgba(0,0,0,0.2); } + .flat .dijitButtonDisabled .dijitButtonNode, .flat .dijitDropDownButtonDisabled .dijitButtonNode, .flat .dijitComboButtonDisabled .dijitButtonNode, @@ -247,24 +284,25 @@ .flat .dijitComboBoxDisabled .dijitButtonNode, .flat .dijitSpinnerDisabled .dijitButtonNode, .flat .dijitSelectDisabled .dijitButtonNode { - background-image: none; - box-shadow: none; - cursor: not-allowed; - filter: alpha(opacity=65); - opacity: 0.65; - -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=65); - -webkit-box-shadow: none; + background-image: none; + -webkit-box-shadow:none; + box-shadow: none; + cursor: not-allowed; + -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=65); + filter: alpha(opacity=65); + opacity: 0.65; } .flat .success .dijitButtonNode { background: #409843; - color: #FFF; border-color: #39883c; + color: #FFF; } + .flat .danger .dijitButtonNode { background: #e32d29; - color: #FFF; border-color: #d4201b; + color: #FFF; } .flat .dijitTextBoxHover, @@ -283,4 +321,4 @@ background-color: #999; } -/* end flat theme */ +/* end flat theme */ \ No newline at end of file diff --git a/viewer/js/gis/dijit/FloatingTitlePane/css/FloatingTitlePane.css b/viewer/js/gis/dijit/FloatingTitlePane/css/FloatingTitlePane.css index 149b45b6c..ed17fc8d1 100644 --- a/viewer/js/gis/dijit/FloatingTitlePane/css/FloatingTitlePane.css +++ b/viewer/js/gis/dijit/FloatingTitlePane/css/FloatingTitlePane.css @@ -1,10 +1,16 @@ -.floatingWidgetDock:before { - float: right; +.dijitTitlePane .dijitTitlePaneTitle .titlePaneIcon { + margin: 0 0 0 8px; + padding-top: 2px; +} + +.dijitTitlePane .dijitTitlePaneTitle .floatingWidgetDock:before { content: "\f112"; + float: right; font-family: FontAwesome; } -.floatingWidgetPopout:before { - float: right; + +.dijitTitlePane .dijitTitlePaneTitle .floatingWidgetPopout:before { content: "\f064"; + float: right; font-family: FontAwesome; } \ No newline at end of file From 5d0052158a07ab41219a76fb9759aed4421e74a8 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sun, 25 Jun 2017 10:10:34 +0900 Subject: [PATCH 35/41] add support for lazy-loading widgets in floating pane and mobile sidebar. switch configuration option from `loadOnOpen: false/true` to `preload: true/false`. --- viewer/js/config/viewer.js | 2 +- viewer/js/viewer/_SidebarMixin.js | 14 +---- viewer/js/viewer/_WidgetsMixin.js | 13 ++-- viewer/js/viewer/sidebar/Sidebar.js | 83 ++++++++---------------- viewer/js/viewer/sidebar/SidebarTab.js | 87 ++++++++++++++++++++++++++ 5 files changed, 125 insertions(+), 74 deletions(-) create mode 100644 viewer/js/viewer/sidebar/SidebarTab.js diff --git a/viewer/js/config/viewer.js b/viewer/js/config/viewer.js index f305d0a6d..f91d67098 100644 --- a/viewer/js/config/viewer.js +++ b/viewer/js/config/viewer.js @@ -349,7 +349,7 @@ define([ title: i18n.viewer.widgets.identify, iconClass: 'fa-info-circle', open: false, - loadOnOpen: false, + preload: true, position: 3, options: 'config/identify' }, diff --git a/viewer/js/viewer/_SidebarMixin.js b/viewer/js/viewer/_SidebarMixin.js index db65fe722..056371458 100644 --- a/viewer/js/viewer/_SidebarMixin.js +++ b/viewer/js/viewer/_SidebarMixin.js @@ -37,7 +37,7 @@ define([ }); var deferred = new Deferred(); require([ - module.uri.substring(0, module.uri.lastIndexOf('/')) + '/sidebar/Sidebar.js' + 'viewer/sidebar/Sidebar' ], lang.hitch(this, function (sidebar) { Sidebar = sidebar; this.mapDeferred.then(lang.hitch(this, '_createSidebar')); @@ -112,17 +112,7 @@ define([ iconClass: widgetConfig.iconClass }; - var tab = this.sidebar.createTab(tabOptions); - tab.contentNode = put(tab.containerNode, 'div.sidebar-widget div.sidebar-widget-content'); - - var node = put(tab.contentNode, 'div'); - widgetConfig.type = 'domNode'; - widgetConfig.srcNodeRef = node; - this.createWidgets([ - { - options: widgetConfig - } - ]); + return this.sidebar.createTab(tabOptions); } }); diff --git a/viewer/js/viewer/_WidgetsMixin.js b/viewer/js/viewer/_WidgetsMixin.js index fcb642765..01408f82a 100644 --- a/viewer/js/viewer/_WidgetsMixin.js +++ b/viewer/js/viewer/_WidgetsMixin.js @@ -147,22 +147,26 @@ define([ } // build a titlePane or floating widget as the parent + widgetConfig.watched = widgetConfig.watched || 'open'; if ((widgetConfig.type === 'titlePane' || widgetConfig.type === 'contentPane' || widgetConfig.type === 'floating')) { parentId = widgetConfig.widgetKey + '_parent'; if (widgetConfig.type === 'titlePane') { pnl = this._createTitlePaneWidget(parentId, widgetConfig); } else if (widgetConfig.type === 'contentPane') { pnl = this._createContentPaneWidget(parentId, widgetConfig); + widgetConfig.preload = true; } else if (widgetConfig.type === 'floating') { pnl = this._createFloatingWidget(parentId, widgetConfig); } widgetConfig.parentWidget = pnl; + widgetConfig.preload = (widgetConfig.preload) || pnl.get(widgetConfig.watched) || (typeof(pnl.watch) !== 'function'); this._showWidgetLoader(pnl); } var deferred = new Deferred(); - if ((widgetConfig.type === 'titlePane') && (widgetConfig.loadOnOpen !== false) && !pnl.get('open')) { - widgetConfig.delayHandle = aspect.after(pnl, 'toggle', lang.hitch(this, '_loadWidget', widgetConfig, deferred)); + widgetConfig.preload = (typeof(widgetConfig.preload) === 'undefined') ? true : widgetConfig.preload; + if (!widgetConfig.preload) { + widgetConfig.watchHandle = pnl.watch(widgetConfig.watched, lang.hitch(this, '_loadWidget', widgetConfig, deferred)); } else { this._loadWidget(widgetConfig, deferred); } @@ -182,8 +186,9 @@ define([ deferred.resolve(); })); } - if (widgetConfig.delayHandle) { - widgetConfig.delayHandle.remove(); + if (widgetConfig.watchHandle) { + widgetConfig.watchHandle.unwatch(); + widgetConfig.watchHandle.remove(); } }, diff --git a/viewer/js/viewer/sidebar/Sidebar.js b/viewer/js/viewer/sidebar/Sidebar.js index 7df98b78d..ca0f37115 100644 --- a/viewer/js/viewer/sidebar/Sidebar.js +++ b/viewer/js/viewer/sidebar/Sidebar.js @@ -15,6 +15,8 @@ define([ 'put-selector/put', + 'viewer/sidebar/SidebarTab', + 'dojo/text!./templates/Sidebar.html', 'xstyle/css!./css/Sidebar.css', @@ -38,17 +40,14 @@ define([ put, + SidebarTab, + template ) { return declare([_WidgetBase, _TemplatedMixin], { templateString: template, baseClass: 'sidebar', - defaultTabParams: { - title: 'Title', - iconClass: 'fa-bars' - }, - viewPadding: { top: 0, left: 0, @@ -76,7 +75,6 @@ define([ // resize tab and any widgets within the tab when it is opened on(this.domNode, 'transitionend, oTransitionEnd, webkitTransitionEnd, animationend, webkitAnimationEnd', lang.hitch(this, '_resizeActiveTab')); - // resize tab and any widgets within the tab when the browser is resized on(window, 'resize', lang.hitch(this, function () { window.setTimeout(lang.hitch(this, '_resizeActiveTab'), 300); // 300ms to wait for the animation to complete @@ -85,66 +83,37 @@ define([ }, createTab: function (options) { - options = lang.mixin(lang.clone(this.defaultTabParams), options || {}); - var tab = { - id: options.id, - buttonNode: null, - containerNode: null, - titleNode: null, - closeBtnNode: null, - contentNode: null - }; - //create and place dom elements for the tab button and pane - tab.buttonNode = put(this.tabsButtonNode, 'li a[role=tab] i.fa.' + options.iconClass + '<<'); - tab.containerNode = put(this.tabsContainerNode, 'div.' + this.baseClass + '-pane'); - tab.titleNode = put(tab.containerNode, 'div.' + this.baseClass + '-pane-title $', options.title); - - if (this.showCloseIcon) { - tab.closeBtnNode = put(tab.titleNode, 'i.fa.fa-chevron-left.' + this.baseClass + '-closeIcon'); - // listen for the tab close button click - on(tab.closeBtnNode, 'click', lang.hitch(this, 'tabClickHandler', tab)); + options = options || {}; + options.open = options.open || false; + options.baseClass = this.baseClass; + options.showCloseIcon = this.showCloseIcon; + options.tabsContainerNode = this.tabsContainerNode; + options.tabsButtonNode = this.tabsButtonNode; + + var tab = new SidebarTab(options); + tab.watch('open', lang.hitch(this, 'checkTabs', tab)); + if (options.open) { + tab.openTab(); } - // listen for the tab button click - on(tab.buttonNode, 'click', lang.hitch(this, 'tabClickHandler', tab)); - - //keep a reference to this tab this.tabs.push(tab); - - //return the tabs pane node return tab; }, - openTab: function (tab) { + checkTabs: function (tab) { array.forEach(this.tabs, function (childTab) { - put(childTab.buttonNode, '!active'); - put(childTab.containerNode, '!active'); - put(childTab.contentNode, '!active'); + if (childTab.get('id') !== tab.get('id')) { + childTab.closeTab(true); + } }); - put(tab.buttonNode, '.active'); - put(tab.containerNode, '.active'); - put(tab.contentNode, '.active'); - put(this.tabsButtonNode, '.active'); - put(this.domNode, '!collapsed'); - put(this.mapContainer, '!sidebar-collapsed'); - }, - - closeTab: function () { - array.forEach(this.tabs, function (tab) { - put(tab.buttonNode, '!active'); - put(tab.containerNode, '!active'); - put(tab.contentNode, '!active'); - }, this); - put(this.tabsButtonNode, '!active'); - put(this.domNode, '.collapsed'); - put(this.mapContainer, '.sidebar-collapsed'); - }, - - tabClickHandler: function (tab) { - if (domClass.contains(tab.buttonNode, 'active')) { - this.closeTab(tab); + if (tab.get('open')) { + domClass.add(this.tabsButtonNode, 'active'); + domClass.remove(this.domNode, 'collapsed'); + domClass.remove(this.mapContainer, 'sidebar-collapsed'); } else { - this.openTab(tab); + domClass.remove(this.tabsButtonNode, 'active'); + domClass.add(this.domNode, 'collapsed'); + domClass.add(this.mapContainer, 'sidebar-collapsed'); } }, diff --git a/viewer/js/viewer/sidebar/SidebarTab.js b/viewer/js/viewer/sidebar/SidebarTab.js new file mode 100644 index 000000000..db4945f77 --- /dev/null +++ b/viewer/js/viewer/sidebar/SidebarTab.js @@ -0,0 +1,87 @@ +define([ + 'dojo/_base/declare', + 'dijit/_WidgetBase', + + 'dojo/_base/lang', + 'dojo/on', + 'dojo/dom-class', + + 'put-selector/put' + +], function ( + declare, + _WidgetBase, + + lang, + on, + domClass, + + put + +) { + return declare([_WidgetBase], { + id: null, + title: 'Title', + iconClass: 'fa-bars', + open: false, + baseClass: null, + tabsButtonNode: null, + tabsContainerNode: null, + buttonNode: null, + contentNode: null, + titleNode: null, + closeBtnNode: null, + containerNode: null, + + postCreate: function () { + this.inherited(arguments); + + //create and place dom element for the tab button + this.buttonNode = put(this.tabsButtonNode, 'li a[role=tab] i.fa.' + this.iconClass + '<<'); + + //create and place dom elements for the tab pane + this.contentNode = put(this.tabsContainerNode, 'div.' + this.baseClass + '-pane'); + this.titleNode = put(this.contentNode, 'div.' + this.baseClass + '-pane-title $', this.title); + this.containerNode = put(this.contentNode, 'div.sidebar-widget div.sidebar-widget-content'); + if (this.showCloseIcon) { + this.closeBtnNode = put(this.titleNode, 'i.fa.fa-chevron-left.' + this.baseClass + '-closeIcon'); + // listen for the tab close button click + on(this.closeBtnNode, 'click', lang.hitch(this, 'tabClickHandler')); + } + + // listen for the tab button click + on(this.buttonNode, 'click', lang.hitch(this, 'tabClickHandler')); + + }, + + openTab: function (silent) { + domClass.add(this.buttonNode, 'active'); + domClass.add(this.containerNode, 'active'); + domClass.add(this.contentNode, 'active'); + if (silent) { + this.open = true; + return; + } + this.set('open', true); + }, + + closeTab: function (silent) { + domClass.remove(this.buttonNode, 'active'); + domClass.remove(this.containerNode, 'active'); + domClass.remove(this.contentNode, 'active'); + if (silent) { + this.open = false; + return; + } + this.set('open', false); + }, + + tabClickHandler: function () { + if (domClass.contains(this.buttonNode, 'active')) { + this.closeTab(); + } else { + this.openTab(); + } + } + }); +}); \ No newline at end of file From ba77f00995b68f549e6768275693583d93132cfe Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Mon, 26 Jun 2017 11:49:29 +0900 Subject: [PATCH 36/41] remove accidental `bottom-border: none` --- viewer/css/cmv-theme-overrides.css | 1 - 1 file changed, 1 deletion(-) diff --git a/viewer/css/cmv-theme-overrides.css b/viewer/css/cmv-theme-overrides.css index 6913a9f3e..00401a31e 100644 --- a/viewer/css/cmv-theme-overrides.css +++ b/viewer/css/cmv-theme-overrides.css @@ -193,7 +193,6 @@ .flat .dijitTitlePaneTitle { border: 1px solid #DDD; - border-bottom: none; -webkit-border-radius: 4px; border-radius: 4px; padding: 8px 15px; From 456b2f9389ffdf1817ff89539fbef49df65f5a13 Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Mon, 26 Jun 2017 10:54:20 -0500 Subject: [PATCH 37/41] Trigger streetview 'layoutChange' since parent widget may already be open due to delayed startup --- viewer/js/gis/dijit/StreetView.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/viewer/js/gis/dijit/StreetView.js b/viewer/js/gis/dijit/StreetView.js index a9dc90a0f..f6387d478 100644 --- a/viewer/js/gis/dijit/StreetView.js +++ b/viewer/js/gis/dijit/StreetView.js @@ -76,6 +76,10 @@ define([ } this.own(aspect.after(this.parentWidget, 'resize', lang.hitch(this, 'resize'))); this.own(topic.subscribe(this.parentWidget.id + '/resize/resize', lang.hitch(this, 'resize'))); + + // trigger layout change since parentWidget might + // already be open + this.onLayoutChange(this.parentWidget.open); } if (!window.proj4) { From bb3f3aa121f9f44bfe3376cea654ad4c461f9475 Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Mon, 26 Jun 2017 11:03:56 -0500 Subject: [PATCH 38/41] Remove `lang.clone` config from widget loader --- viewer/js/viewer/_WidgetsMixin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/viewer/js/viewer/_WidgetsMixin.js b/viewer/js/viewer/_WidgetsMixin.js index 01408f82a..872f75af9 100644 --- a/viewer/js/viewer/_WidgetsMixin.js +++ b/viewer/js/viewer/_WidgetsMixin.js @@ -77,7 +77,7 @@ define([ widgetTypes = widgetTypes || this.widgetTypes; for (var key in this.config.widgets) { if (this.config.widgets.hasOwnProperty(key)) { - var widget = lang.clone(this.config.widgets[key]); + var widget = this.config.widgets[key]; widget.widgetKey = widget.widgetKey || widget.id || key; if (widget.include && (!this.widgets[widget.widgetKey]) && (array.indexOf(widgetTypes, widget.type) >= 0)) { widget.position = (typeof(widget.position) !== 'undefined') ? widget.position : 10000; From 5ea446e2e41b4b064f885a5e2f5c97f6be93a669 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sun, 2 Jul 2017 09:02:37 +0900 Subject: [PATCH 39/41] bump the version number for release. --- README.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4e1417eb2..5ccfd054d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # CMV The Configurable Map Viewer -[![Read The Docs](https://img.shields.io/badge/docs-2.0.0--beta.1-brightgreen.svg?style=flat)](https://docs.cmv.io/) [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/cmv/cmv-app?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://travis-ci.org/cmv/cmv-app.svg?branch=master)](https://travis-ci.org/cmv/cmv-app) [![Greenkeeper badge](https://badges.greenkeeper.io/cmv/cmv-app.svg)](https://greenkeeper.io/) +[![Read The Docs](https://img.shields.io/badge/docs-2.0.0--beta.2-brightgreen.svg?style=flat)](https://docs.cmv.io/) [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/cmv/cmv-app?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://travis-ci.org/cmv/cmv-app.svg?branch=master)](https://travis-ci.org/cmv/cmv-app) [![Greenkeeper badge](https://badges.greenkeeper.io/cmv/cmv-app.svg)](https://greenkeeper.io/) ## Introduction [CMV](https://cmv.io/) is a community-supported open source mapping framework. CMV works with the [Esri JavaScript API](https://developers.arcgis.com/javascript/jsapi/3/), [ArcGIS Server](https://www.esri.com/software/arcgis/arcgisserver), [ArcGIS Online](https://arcgis.com/) and more. @@ -47,7 +47,7 @@ A [resource proxy](https://github.com/Esri/resource-proxy) may be required to ac ## Documentation: Use the [documentation](https://docs.cmv.io/) for getting started and guidance on configuring your application. The initial documentation is sparse. Please help make it better by contributing over at the [cmv documentation repo](https://github.com/cmv/cmv-docs). -[![Read The Docs](https://img.shields.io/badge/docs-2.0.0--beta.1-brightgreen.svg?style=flat)](https://docs.cmv.io/) +[![Read The Docs](https://img.shields.io/badge/docs-2.0.0--beta.2-brightgreen.svg?style=flat)](https://docs.cmv.io/) ## Community We have a [gitter.im chat room](https://gitter.im/cmv/cmv-app). Come on by if you have questions. The community is very active and helpful. diff --git a/package.json b/package.json index 26ad361f4..d373f7dcd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ConfigurableMapViewerCMV", - "version": "2.0.0-beta.1", + "version": "2.0.0-beta.2", "author": "cmv.io - https://github.com/cmv/", "license": "MIT", "year": "2017", From bf6e24852db1a3c8f9f86f2f3c76f951b4568e33 Mon Sep 17 00:00:00 2001 From: Tim McGee Date: Sun, 2 Jul 2017 22:55:52 +0900 Subject: [PATCH 40/41] update version of node for travis ci. update travis secure api key to known working key. --- .travis.yml | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 88a5a983b..1d8421df7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,13 @@ language: node_js node_js: -- '5' +- 'node' sudo: false before_install: npm install -g grunt-cli before_script: grunt build --verbose deploy: provider: releases api_key: - secure: RH6f8GbwwkXZvoxOS88NhOhEAfFHL52wQ9cadmzPTCnqNNVeC5GhAvwoNvBTobZhB+Jt0W9oVQt2WTnAomxC9cqh07fSqLBk8I8UpuhRkmL+AZPwnquDxD9Bi6yNAgwd5IQfMqP251Qlzfwe7ffL42yAsjGfJOoliZRvfQyKQho= + secure: PbeHwM34muUp/D+g9gbpBj/ABYtKRmPkgRpvSMl8zxFw/slFEoepA25komkh4QO1VGV5xGtUiIz8F6Rg+uhgWiid0F+GAxDjVc9NAUAeK9ONzKpo9H5f7JJrESBnEp06R6CVR/hVPN5v2UlKUJd2MoRYHKTM/GlnCY8/L+0j0bU= file: dist/viewer.zip on: tags: true diff --git a/package.json b/package.json index d373f7dcd..6a9a15cb3 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,6 @@ "body-parser": "~1.17.0", "proxypage": "*" }, - "engine": "node >= 4", + "engine": "node >= 6", "dojoBuild": "package.js" } From ddae218ae85dd482d58dc44764f2295e18ce7cc6 Mon Sep 17 00:00:00 2001 From: roemhildtg Date: Mon, 3 Jul 2017 09:47:21 -0500 Subject: [PATCH 41/41] move layout change call inside check for toggleable --- viewer/js/gis/dijit/StreetView.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/viewer/js/gis/dijit/StreetView.js b/viewer/js/gis/dijit/StreetView.js index f6387d478..64650cdfc 100644 --- a/viewer/js/gis/dijit/StreetView.js +++ b/viewer/js/gis/dijit/StreetView.js @@ -73,13 +73,13 @@ define([ this.own(aspect.after(this.parentWidget, 'toggle', lang.hitch(this, function () { this.onLayoutChange(this.parentWidget.open); }))); + + // trigger layout change since parentWidget might + // already be open + this.onLayoutChange(this.parentWidget.open); } this.own(aspect.after(this.parentWidget, 'resize', lang.hitch(this, 'resize'))); this.own(topic.subscribe(this.parentWidget.id + '/resize/resize', lang.hitch(this, 'resize'))); - - // trigger layout change since parentWidget might - // already be open - this.onLayoutChange(this.parentWidget.open); } if (!window.proj4) {