basemap in appsetting
hi, i am using your fantastic appsetting widget in my app. it is great, thank you! i tried to add basemap as a parameter to the widget but couldn't. i would appreciate it if you could give me a hint. thanks
What have you tried @mtabdar ? Can you post the code?
I have this slightly documented in the readme, it should work. You have to modify the basemap widget a bit to get it to publish/subscribe to the right topics and update the basemap.
Storing a setting: - When the basemap changes
//writes the object value to the appSettings[key] and stores it in localStorage
Topic.publish('AppSettings/setValue', 'basemap', value);
Retrieving a value when the widget is loaded: - On postCreate method:
//waits for the settings to be loaded and prints the appSettings object
Topic.subscribe('AppSettings/onSettingsLoad', Lang.hitch(this, function (appSettings) {
//appSettings is a clone of the entire data structure, if your setting is saved
//it will be directly accessible via appSettings.mySetting
//if your using the checkbox, then the following is relevant
if(appSettings.basemap && //make sure it exists
(appSettings.basemap.save || //the user had the checkbox checked
appSettings.basemap.urlLoad) //the user has loaded a url with this setting in it
) {
console.log(appSettings.mySetting);
}
}));
config (viewer.js widgets)
appSettings: {
//.....
options: {
appSettings: {
basemap: {
checkbox: true,
label: 'Save current basemap'
}
}
}
}
hi @roemhildtg thanks for the hint. i am still stuck. i added both publish/subscribe to my basemap.js in postcreate the error is:"Topic not defined" adding "dijit/appsettings" to define section of basemap.js doesn't work either. could you tell me what's wrong?
You need to define Topic. Add dojo/topic to your define block and add Topic to your function. Make sure the modules line up in the same order as their variables
hi, thanks for the reply and sorry for the delay, i was trying different approaches for solving my problem, with no success. this is my basemap.js and i put topic.publish and topic.subscribe in postcreate block. browser gives no errors but basemap object properties is not included in my url. and no "value:object" in console log. i would appreciate any help basemap.js:
define([
'dojo/_base/declare',
'dijit/_WidgetBase',
'dijit/_TemplatedMixin',
'dijit/_WidgetsInTemplateMixin',
'dojo/_base/lang',
'dojo/_base/array',
'dojo/topic',
'dijit/DropDownMenu',
'dijit/MenuItem',
'esri/basemaps',
'esri/dijit/BasemapGallery',
'dojo/text!./Basemaps/templates/Basemaps.html',
'dojo/i18n!./Basemaps/nls/resource',
'dijit/form/DropDownButton',
'xstyle/css!./Basemaps/css/Basemaps.css'
], function (
declare,
_WidgetBase,
_TemplatedMixin,
_WidgetsInTemplateMixin,
lang,
array,
topic,
DropDownMenu,
MenuItem,
esriBasemaps,
BasemapGallery,
template,
i18n
) {
return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
templateString: template,
widgetsInTemplate: true,
i18n: i18n,
title: i18n.title,
baseClass: 'basemapWidget',
basemaps: {},
currentBasemap: null,
mapStartBasemap: null,
basemapsToShow: null,
galleryOptions: {
basemapIds: null,
basemaps: null,
basemapsGroup: null,
bingMapsKey: null,
portalUrl: null,
referenceIds: null,
showArcGISBasemaps: false
},
postCreate: function () {
this.inherited(arguments);
this.initializeBasemaps();
this.createBasemapGallery();
topic.subscribe('basemaps/updateBasemap', lang.hitch(this, 'updateBasemap'));
//***********************Appsetting Part ***************************
topic.publish('AppSettings/setValue', 'basemaps', basemap);
topic.subscribe('AppSettings/onSettingsLoad', Lang.hitch(this, function (appSettings) {
if(appSettings.basemap && //make sure it exists
(appSettings.basemap.save || //the user had the checkbox checked
appSettings.basemap.urlLoad) //the user has loaded a url with this setting in it
) {
console.log(appSettings.mySetting);
}
}));
},
initializeBasemaps: function () {
if (this.galleryOptions.basemaps) {
// if the basemaps to show is not explicitly set, get them from the gallery's basemap array
this.basemapsToShow = this.basemapsToShow || array.map(this.galleryOptions.basemaps, function (basemap) {
return basemap.id;
});
} else {
// no basemaps? use the Esri basemaps
if (!this.basemaps || Object.keys(this.basemaps).length < 1) {
this.basemaps = lang.clone(esriBasemaps);
this.galleryOptions.showArcGISBasemaps = false;
}
// if the basemaps to show is not explicitly set, get them from the basemap object
this.basemapsToShow = this.basemapsToShow || Object.keys(this.basemaps);
var basemaps = [];
array.forEach(this.basemapsToShow, lang.hitch(this, function (key) {
var map = this.basemaps[key];
// determine if it is a custom basemap or an esri basemap
if (map.basemap && map.basemap.declaredClass === 'esri.dijit.Basemap') {
var basemap = map.basemap;
basemap.title = map.title || basemap.title;
basemap.id = key;
basemaps.push(basemap);
} else {
if (!esriBasemaps[key]) {
map.basemap.title = map.title || map.basemap.title;
esriBasemaps[key] = map.basemap;
}
map.title = map.title || esriBasemaps[key].title;
this.galleryOptions.showArcGISBasemaps = false;
}
}));
this.galleryOptions.basemaps = basemaps;
}
// if the starting basemap is not explicitly set, get it from the map
this.mapStartBasemap = this.mapStartBasemap || this.map.getBasemap();
// check to make sure the starting basemap is found in the basemaps object
if (array.indexOf(this.basemapsToShow, this.mapStartBasemap) < 0) {
this.mapStartBasemap = this.basemapsToShow[0];
}
},
createBasemapGallery: function () {
var opts = lang.mixin({
map: this.map
}, this.galleryOptions);
this.gallery = new BasemapGallery(opts);
this.gallery.startup();
if (this.galleryOptions.showArcGISBasemaps) {
this.gallery.on('load', lang.hitch(this, 'buildMenu'));
} else {
this.buildMenu();
}
},
buildMenu: function () {
this.menu = new DropDownMenu({
style: 'display: none;'
});
array.forEach(this.basemapsToShow, function (basemap) {
if (this.basemaps.hasOwnProperty(basemap)) {
var menuItem = new MenuItem({
id: basemap,
label: this.basemaps[basemap].title,
iconClass: (basemap === this.mapStartBasemap) ? 'selectedIcon' : 'emptyIcon',
onClick: lang.hitch(this, 'updateBasemap', basemap)
});
this.menu.addChild(menuItem);
}
}, this);
this.dropDownButton.set('dropDown', this.menu);
this.setStartingBasemap();
},
setStartingBasemap: function () {
if (this.mapStartBasemap && (this.gallery.get(this.mapStartBasemap) || esriBasemaps[this.mapStartBasemap])) {
this.updateBasemap(this.mapStartBasemap);
}
},
updateBasemap: function (basemap) {
if (basemap !== this.currentBasemap && (array.indexOf(this.basemapsToShow, basemap) !== -1)) {
if (this.gallery.get(basemap)) {
this.gallery.select(basemap);
} else if (esriBasemaps[basemap]) {
this.gallery._removeBasemapLayers();
this.gallery._removeReferenceLayer();
this.map.setBasemap(basemap);
} else {
topic.publish('viewer/error', 'Invalid basemap selected.');
return;
}
this.currentBasemap = basemap;
var ch = this.menu.getChildren();
array.forEach(ch, function (c) {
if (c.id === basemap) {
c.set('iconClass', 'selectedIcon');
} else {
c.set('iconClass', 'emptyIcon');
}
});
}
}
});
});
You need to publish AppSettings/setValue when the basemap changes. This would be in the updateBasemap function. (not in the postCreate function)
updateBasemap: function(basemap){
topic.publish('AppSettings/setValue', 'basemaps', basemap);
//.....
Hello, I noticed to make a custom basemap get saved in the appSettings.js I had to make this change

and then put this in the Basemap.js (from above comment)

and this is the viewer.js options portion of the appsettings config
