Skip to content

Instantly share code, notes, and snippets.

@DGuidi
Last active June 6, 2022 05:24
Show Gist options
  • Save DGuidi/d11b0dc317da7eaec8d038bd74d7673c to your computer and use it in GitHub Desktop.
Save DGuidi/d11b0dc317da7eaec8d038bd74d7673c to your computer and use it in GitHub Desktop.
an updated version of the code found in Digital Geography blog post - https://digital-geography.com/how-to-create-a-custom-web-appbuilder-widget-for-your-portal-with-ors/ - about how to create a simple ArcGIS Widget for a sample ArcGIS Widget
<div style="width: 100%; height: 100%">
<div class="settings-section">
<table class="setting-table input-table" cellspacing="0">
<tbody>
<tr>
<td>
<label>${nls.apiKey}</label>
</td>
<td>
<input
type="text"
placeholder="ORS api key"
data-dojo-type="dijit/form/TextBox"
id="orsdemoConfigApiKey"
/>
</td>
</tr>
</tbody>
</table>
</div>
</div>
define([
"dojo/_base/declare",
"jimu/BaseWidgetSetting",
"dijit/_WidgetsInTemplateMixin",
"dijit/registry",
], function (declare, BaseWidgetSetting, _WidgetsInTemplateMixin, registry) {
return declare([BaseWidgetSetting, _WidgetsInTemplateMixin], {
baseClass: "jimu-widget-orsdemo-setting",
startup: function () {
this.inherited(arguments);
this.setConfig(this.config);
},
setConfig: function (config) {
this.config = config;
registry.byId("orsdemoConfigApiKey").set("value", config.apiKey);
},
getConfig: function () {
return this.config;
},
});
});
<div style="width: 100%">
<div data-dojo-attach-point="mapIdNode"></div>
<div style="width: 100%">
<table class="input-table" style="width: 100%" cellspacing="0">
<tbody>
<tr>
<td>
<label for="StartPoint">${nls.startPoint}</label>
</td>
<td>
<input
type="text"
name="StartPoint"
placeholder="Berlin"
data-dojo-type="dijit/form/ValidationTextBox"
trim="true"
required="true"
id="StartPoint"
/>
</td>
</tr>
<tr>
<td>
<label for="StopPoint">${nls.stopPoint}</label>
</td>
<td>
<input
type="text"
name="StopPoint"
placeholder="Paris"
data-dojo-type="dijit/form/ValidationTextBox"
trim="true"
required="true"
id="StopPoint"
/>
</td>
</tr>
<tr>
<td>
<button
type="button"
data-dojo-type="dijit/form/Button"
id="RouteButton"
disabled="true"
>
${nls.routeButton}
</button>
</td>
</tr>
</tbody>
</table>
</div>
<br />
</div>
define([
"dojo/_base/declare",
"jimu/BaseWidget",
"dijit/_WidgetsInTemplateMixin",
"dojo/parser",
"dojo/keys",
"dijit/registry",
"dijit/form/ValidationTextBox",
"dijit/form/NumberTextBox",
"dijit/form/Button",
"dojo/request/xhr",
"esri/dijit/util/busyIndicator",
"esri/SpatialReference",
"esri/geometry/Point",
"esri/symbols/SimpleMarkerSymbol",
"esri/symbols/SimpleLineSymbol",
"esri/geometry/Polyline",
"esri/graphic",
"esri/layers/GraphicsLayer",
"esri/tasks/QueryTask",
"dojo/domReady!",
], function (
declare,
BaseWidget,
_WidgetsInTemplateMixin,
parser,
keys,
registry,
_dvtb,
_dntb,
_dbtn,
xhr,
busyIndicator,
SpatialReference,
Point,
SimpleMarkerSymbol,
SimpleLineSymbol,
Polyline,
Graphic,
GraphicsLayer,
_querytask,
_dr
) {
//To create a widget, you need to derive from BaseWidget.
return declare([BaseWidget, _WidgetsInTemplateMixin], {
//please note that this property is be set by the framework when widget is loaded.
//templateString: template,
baseClass: "jimu-widget-orsdemo",
postCreate: function () {
this.inherited(arguments);
console.log("postCreate");
},
startup: function () {
this.inherited(arguments);
console.log("startup");
const map = this.map;
this.mapIdNode.innerHTML = "map id: " + map.id;
const coordinates = [undefined, undefined];
const glS = new GraphicsLayer({ id: "START" });
const glE = new GraphicsLayer({ id: "STOP" });
const route = new GraphicsLayer({ id: "ROUTE" });
map.addLayer(glS);
map.addLayer(glE);
map.addLayer(route);
const invalidateInput = (id) => {
registry.byId("RouteButton").set("disabled", true);
if (id == "StartPoint") {
coordinates[0] = undefined;
map.getLayer("START").clear();
} else {
coordinates[1] = undefined;
map.getLayer("STOP").clear();
}
map.getLayer("ROUTE").clear();
};
const validateAdd = (id) => {
const val = registry.byId(id).get("value");
if (!val) {
invalidateInput(id);
return;
}
xhr("https://api.openrouteservice.org/geocode/search", {
query: {
api_key: this.config.apiKey,
text: val,
},
handleAs: "json",
}).then(
(data) => {
try {
registry
.byId(id)
.set("value", data["features"][0]["properties"]["label"]);
if (id == "StartPoint") {
const coords = data["features"][0]["geometry"]["coordinates"];
addPoint(coords, "start");
} else {
const coords = data["features"][0]["geometry"]["coordinates"];
addPoint(coords, "end");
}
} catch (e) {
console.log("no address for " + val + " found!");
invalidateInput(id);
}
},
function (err) {
console.log("calling the API failed: <br>" + err);
invalidateInput(id);
}
);
};
const addPoint = (coords, type) => {
const p = new Point(coords[0], coords[1]);
map.getLayer("ROUTE").clear();
if (type == "start") {
map.getLayer("START").clear();
const s = new SimpleMarkerSymbol().setSize(10).setColor("green");
const g = new Graphic(p, s);
coordinates[0] = p;
glS.add(g);
} else {
map.getLayer("STOP").clear();
const s = new SimpleMarkerSymbol().setSize(10).setColor("red");
const g = new Graphic(p, s);
coordinates[1] = p;
glE.add(g);
}
registry
.byId("RouteButton")
.set("disabled", !(coordinates[0] && coordinates[1]));
};
const startIn = registry.byId("StartPoint");
startIn.on("blur", () => {
validateAdd("StartPoint");
});
startIn.on("keypress", (evt) => {
if (evt.keyCode == keys.ENTER) {
validateAdd("StartPoint");
}
});
const stopIn = registry.byId("StopPoint");
stopIn.on("blur", () => {
validateAdd("StopPoint");
});
stopIn.on("keypress", function (evt) {
if (evt.keyCode == keys.ENTER) {
validateAdd("StopPoint");
}
});
const getRoute = () => {
xhr("https://api.openrouteservice.org/v2/directions/driving-car", {
query: {
api_key: this.config.apiKey,
start:
coordinates[0].x.toString() + "," + coordinates[0].y.toString(),
end:
coordinates[1].x.toString() + "," + coordinates[1].y.toString(),
},
handleAs: "json",
}).then(
function (data) {
map.getLayer("ROUTE").clear();
const polyline = new Polyline();
polyline.addPath(data["features"][0]["geometry"]["coordinates"]);
const symbol = new SimpleLineSymbol().setWidth(2).setColor("blue");
const polylineGraphic = new Graphic(polyline, symbol);
route.add(polylineGraphic);
map.setExtent(polyline.getExtent(), true);
},
function (err) {
console.log("calling the API failed: <br>" + err);
}
);
};
const routeButton = registry.byId("RouteButton");
routeButton.on("click", getRoute);
},
onOpen: function () {
console.log("onOpen");
},
onClose: function () {
console.log("onClose");
registry.byId("StartPoint").set("value", "");
registry.byId("StopPoint").set("value", "");
registry.byId("RouteButton").set("disabled", true);
this.map.getLayer("ROUTE").clear();
this.map.getLayer("START").clear();
this.map.getLayer("STOP").clear();
},
onMinimize: function () {
console.log("onMinimize");
},
onMaximize: function () {
console.log("onMaximize");
},
onSignIn: function (credential) {
/* jshint unused:false*/
console.log("onSignIn");
},
onSignOut: function () {
console.log("onSignOut");
},
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment