Hi,
I don't have a lot of experience working with esri + ArcGIS JavaScript API.
I've been trying to display a map that I could edit the shapes I draw.
So I went to the sample codes and put together the draw toolbar sample and edit toolbar sample but I cant seem to make it work.
All the buttons are displayed but they are not active, if I click on any button the animation triggers but the only interactivity with the map is zooming out and in and dragging around.
When debugging the code I realized the Dojo buttons (dijit/form/Button) I have are not being activated because they are not being scanned by the registration loop and I don't know why. It only gets Layout Elements: "ContentPane" and "BorderContainer".
Any help is welcome.
Thanks in advance.
Here is the code: (you can check how it works pasting on sandbox ArcGIS API for JavaScript Sandbox )
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width,user-scalable=no">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
<title>Maps Toolbar</title>
<link rel="stylesheet" href="https://js.arcgis.com/3.15/dijit/themes/nihilo/nihilo.css">
<link rel="stylesheet" href="https://js.arcgis.com/3.15/esri/css/esri.css">
<!-- CSS files take care of the frames and tiles (when the maps has tiles) position in the screen.
To take out the "esri" logo just edit the esri css file and remove the code for the "logo" pseudo class -->
<style>
html, body, #mainWindow {
font-family: sans-serif;
height: 100%;
width: 100%;
}
html, body {
margin: 0;
padding: 0;
}
#header {
height: 125px;
overflow: auto;
padding: 0.5em;
}
#mainWindow {
visibility: hidden;
}
</style>
<script src="https://js.arcgis.com/3.15/"></script>
<script>
var map, toolbar, symbol, geomTask, editToolbar;
function getShapeCoordinates(graphic) { //Different shapes store coordinates in different ways
//Convert the shape information to json and get the coordinates info
var json = graphic.geometry.toJson(); //or graphic.toJson();
console.log(graphic.geometry);
if (graphic.geometry.type == 'multipoint') {
for (var pt = 0; pt < json.points.length; pt++) {
console.log("Point " + pt + ": " + json.points[pt]);
}
}
else if (graphic.geometry.type == 'polyline') {
for (var pt = 0; pt < json.paths.length; pt++) {
console.log("Points " + pt + ": " + json.paths[pt]);
}
}
else if (graphic.geometry.type == 'polygon') {
for (var pt = 0; pt < json.rings[0].length; pt++) {
console.log(" pt: " + pt + " - Point:" + json.rings[0][pt]);
}
}
}
require([ //this has to be at the same sequence as the function under it
"esri/map", "esri/IdentityManager", "esri/config", "esri/urlUtils", "esri/basemaps",
"esri/toolbars/draw",
"esri/toolbars/edit",
"esri/geometry/Point",
"esri/geometry/Polyline",
"esri/geometry/Polygon",
"esri/graphic",
"esri/symbols/SimpleMarkerSymbol",
"esri/symbols/SimpleLineSymbol",
"esri/symbols/SimpleFillSymbol",
"esri/symbols/TextSymbol",
"dojo/_base/event",
"dojo/parser",
"dojo/dom",
"dojo/dom-style",
"dijit/registry",
"dijit/Menu",
"dijit/layout/BorderContainer", "dijit/layout/ContentPane",
"dijit/form/Button", "dijit/WidgetSet", "dojo/domReady!"
], function( //it has to be in the same sequence of the require above
Map, esriId, esriConfig, urlUtils, esriBaseMaps,
Draw, Edit, Point, Polyline, Polygon, Graphic,
SimpleMarkerSymbol, SimpleLineSymbol, SimpleFillSymbol, TextSymbol,
event, parser, dom, domStyle, registry, Menu, BorderContainer, ContentPane, Button, _WidgetSet
) {
parser.parse();
map = new Map("map", {
basemap: "topo", //if changed to "topo" the coordinates to centralize the map are used
center: [176.264, -38.160],
zoom: 5 //if the scion map is being used deep levels of the zoom wont work because the scion map doesnt have the tile
//the map is centred at.
});
map.on("load", createToolbar);
function activateTool() {
alert("loaded");
var tool = this.label.toUpperCase().replace(/ /g, "_");
toolbar.activate(Draw[tool]); ;
map.hideZoomSlider();
}
// loop through all dijits, connect onClick event
// listeners for buttons to activate drawing tools
registry.forEach(function (d) {
// d is a reference to a dijit
// could be a layout container or a button
if (d.declaredClass === "dijit.form.Button") { //buttons to draw shapes are not working because form buttons are not being
console.log("it doesnt come here"); //activated by this function because this loop isnt reaching the butttons
d.on("click", activateTool); //for unknown reasons
}
else {
console.log("d :" + d + " d.declaredClass : " + d.declaredClass + " =?= dijit.form.Button");
}
});
function activateToolbar(graphic) { //activating the toolbars
domStyle.set(registry.byId("draw").domNode, "visibility", "none");
domStyle.set(registry.byId("edit").domNode, "visibility", "visible");
var tool = 0;
if (registry.byId("tool_move").checked) {
tool = tool | Edit.MOVE;
}
if (registry.byId("tool_vertices").checked) {
tool = tool | Edit.EDIT_VERTICES;
}
if (registry.byId("tool_scale").checked) {
tool = tool | Edit.SCALE;
}
if (registry.byId("tool_rotate").checked) {
tool = tool | Edit.ROTATE;
}
// enable text editing if a graphic uses a text symbol
if (graphic.symbol.declaredClass === "esri.symbol.TextSymbol") {
tool = tool | Edit.EDIT_TEXT;
}
//specify toolbar options
var options = {
allowAddVertices: registry.byId("vtx_ca").checked,
allowDeleteVertices: registry.byId("vtx_cd").checked,
uniformScaling: registry.byId("uniform_scaling").checked
};
editToolbar.activate(tool, graphic, options);
domStyle.set(registry.byId("edit").domNode, "visibility", "none");
domStyle.set(registry.byId("draw").domNode, "visibility", "visible");
}
function createToolbar(themap) { //creating the toolbars layout
toolbar = new Draw(map);
toolbar.on("draw-end", addToMap);
editToolbar = new Edit(map);
//Activate the toolbar when you click on a graphic
map.graphics.on("click", function (evt) {
event.stop(evt);
activateToolbar(evt.graphic);
});
//deactivate the toolbar when you click outside a graphic
map.on("click", function (evt) {
editToolbar.deactivate();
});
}
function addToMap(evt) { //adding shapes to the map
var symbol;
toolbar.deactivate();
map.showZoomSlider();
switch (evt.geometry.type) {
case "point":
case "multipoint":
symbol = new SimpleMarkerSymbol();
break;
case "polyline":
symbol = new SimpleLineSymbol();
break;
default:
symbol = new SimpleFillSymbol();
break;
}
var graphic = new Graphic(evt.geometry, symbol);
map.graphics.add(graphic);
dojo.connect(map.graphics, "onGraphicAdd", getShapeCoordinates(graphic));
}
domStyle.set(registry.byId("mainWindow").domNode, "visibility", "visible");
}
);
</script>
</head>
<body class="nihilo">
<div id="mainWindow" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline'">
<div id="header" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'top'">
<span>Draw:<br /></span>
<button data-dojo-type="dijit/form/Button" id="b1">Point</button>
<button data-dojo-type="dijit/form/Button" id="b2">Multi Point</button>
<button data-dojo-type="dijit/form/Button" id="b3">Line</button>
<button data-dojo-type="dijit/form/Button" id="b4">Polyline</button>
<button data-dojo-type="dijit/form/Button" id="b5">Polygon</button>
<button data-dojo-type="dijit/form/Button" id="b6">Freehand Polyline</button>
<button data-dojo-type="dijit/form/Button" id="b7">Freehand Polygon</button>
<button data-dojo-type="dijit/form/Button" id="b8">Arrow</button>
<button data-dojo-type="dijit/form/Button" id="b9">Triangle</button>
<button data-dojo-type="dijit/form/Button" id="b10">Circle</button>
<button data-dojo-type="dijit/form/Button" id="b11">Ellipse</button>
<span>Specify options then click a graphic to edit the shape. Click outside the graphic to quit editing.</span><br />
<div id="tool_move" data-dojo-type="dijit/form/ToggleButton" data-dojo-props="checked:'true', iconClass:'dijitCheckBoxIcon'">Move</div>
<div id="tool_vertices" data-dojo-type="dijit/form/ToggleButton" data-dojo-props="checked:'true', iconClass:'dijitCheckBoxIcon'">Edit Vertices</div>
<div id="tool_scale" data-dojo-type="dijit/form/ToggleButton" data-dojo-props="checked:'true', iconClass:'dijitCheckBoxIcon'">Scale</div>
<div id="tool_rotate" data-dojo-type="dijit/form/ToggleButton" data-dojo-props="checked:'true', iconClass:'dijitCheckBoxIcon'">Rotate</div>
<button data-dojo-type="dijit/form/DropDownButton" id="options" data-dojo-props="value:'options'">
<span>Options</span>
<div data-dojo-type="dijit/Menu" id="optionsMenu">
<div id="vtx_ca" data-dojo-type="dijit/CheckedMenuItem" data-dojo-props="checked:'true'">Allow Add Vertices</div>
<div id="vtx_cd" data-dojo-type="dijit/CheckedMenuItem" data-dojo-props="checked:'true'">Allow Delete Vertices</div>
<div id="uniform_scaling" data-dojo-type="dijit/CheckedMenuItem" data-dojo-props="checked:'true'">Uniform Scaling when Resizing</div>
</div>
</button>
</div>
<div id="map" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'"></div>
</div>
</body>
</html>
Solved! Go to Solution.
Bruno,
Sorry I threw in the dojo/on in my posted code:
require([ //this has to be at the same sequence as the function under it "esri/map", "esri/IdentityManager", "esri/config", "esri/urlUtils", "esri/basemaps", "esri/toolbars/draw", "esri/toolbars/edit", "esri/geometry/Point", "esri/geometry/Polyline", "esri/geometry/Polygon", "esri/graphic", "esri/symbols/SimpleMarkerSymbol", "esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol", "esri/symbols/TextSymbol", "dojo/_base/event", "dojo/parser", "dojo/dom", "dojo/on", "dojo/dom-style", "dijit/registry", "dijit/Menu", "dijit/layout/BorderContainer", "dijit/layout/ContentPane", "dijit/form/Button", "dijit/form/ToggleButton", "dijit/form/DropDownButton", "dijit/CheckedMenuItem", "dojo/domReady!" ], function ( //it has to be in the same sequence of the require above Map, esriId, esriConfig, urlUtils, esriBaseMaps, Draw, Edit, Point, Polyline, Polygon, Graphic, SimpleMarkerSymbol, SimpleLineSymbol, SimpleFillSymbol, TextSymbol, event, parser, dom, on, domStyle, registry, Menu, BorderContainer, ContentPane, Button ) {
Bruno,
You are not adding all the requires you are using.
"esri/map", "esri/IdentityManager", "esri/config", "esri/urlUtils", "esri/basemaps", "esri/toolbars/draw", "esri/toolbars/edit", "esri/geometry/Point", "esri/geometry/Polyline", "esri/geometry/Polygon", "esri/graphic", "esri/symbols/SimpleMarkerSymbol", "esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol", "esri/symbols/TextSymbol", "dojo/_base/event", "dojo/parser", "dojo/dom", "dojo/on", "dojo/dom-style", "dijit/registry", "dijit/Menu", "dijit/layout/BorderContainer", "dijit/layout/ContentPane", "dijit/form/Button", "dijit/form/ToggleButton", "dijit/form/DropDownButton", "dijit/CheckedMenuItem", "dojo/domReady!"
You were missing the ToggleButton, DropDownButton and CheckedMenuItem.
I confirmed this works in jsfiddle - adding the missing requires.
Now I got this: TypeError: registry.forEach is not a function
Did you only add the missing modules?
Yes, that's how it looks
Bruno,
Sorry I threw in the dojo/on in my posted code:
require([ //this has to be at the same sequence as the function under it "esri/map", "esri/IdentityManager", "esri/config", "esri/urlUtils", "esri/basemaps", "esri/toolbars/draw", "esri/toolbars/edit", "esri/geometry/Point", "esri/geometry/Polyline", "esri/geometry/Polygon", "esri/graphic", "esri/symbols/SimpleMarkerSymbol", "esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol", "esri/symbols/TextSymbol", "dojo/_base/event", "dojo/parser", "dojo/dom", "dojo/on", "dojo/dom-style", "dijit/registry", "dijit/Menu", "dijit/layout/BorderContainer", "dijit/layout/ContentPane", "dijit/form/Button", "dijit/form/ToggleButton", "dijit/form/DropDownButton", "dijit/CheckedMenuItem", "dojo/domReady!" ], function ( //it has to be in the same sequence of the require above Map, esriId, esriConfig, urlUtils, esriBaseMaps, Draw, Edit, Point, Polyline, Polygon, Graphic, SimpleMarkerSymbol, SimpleLineSymbol, SimpleFillSymbol, TextSymbol, event, parser, dom, on, domStyle, registry, Menu, BorderContainer, ContentPane, Button ) {
Wow, it works perfectly!
Thank you very much!
Bruno,
Clicking the mark as assumed answered is for situations where you have answer your own question or really did not get a answer but a workaround that works for you. When you have a reply that answers your question you should mark the thread that answered your question as the "Correct Answer". To do this you have to open the thread (you can not see the correct answer link from inside your inbox) and then you will see the green star with correct answer link. Just click that link on the thread that answered your question.
How to use dojo tools on the 4.17 version?