|
POST
|
I have built an application using ArcGIS Javascript 4.X technology that resides on our servers and accesses data in ArcGIS Online. That data is shared to the Enterprise only and I'm using Field Worker licenses to provide access. We anticipate less than 20 licenses needed and already have that so having enough licensing is not an issue for this application. And it's nice to be able to (easily) track who's editing data. If you are looking to just have an interface that allows a user to edit data across the enterprise, then you should probably look at using the OAuth2 way of building an application and accessing information (https://developers.arcgis.com/documentation/mapping-apis-and-services/security/application-credentials/ ). For each user you would use the OAuth2 method to generate a short-lived token that could then be used in the REST call to add/update/delete data. You would still have to manage who could access this application, or maybe just limit access by using an internal server for the app. Some ideas: https://developers.arcgis.com/javascript/latest/sample-code/identity-oauth-basic/ https://developers.arcgis.com/net/forms/sample-code/authenticate-with-oauth/ https://developers.arcgis.com/javascript/3/jssamples/portal_oauth_inline.html https://developers.arcgis.com/net/uwp/sample-code/authenticate-with-oauth/ https://community.esri.com/t5/arcgis-api-for-javascript-questions/access-private-map-in-website-without-login-using/m-p/188384
... View more
05-19-2022
10:19 AM
|
0
|
1
|
1319
|
|
POST
|
I'm not sure what you are trying to do, exactly, but whether it's a user that triggers the featurelayer.applyEdits or an application process, the tool or function (applyEdits) would still be the same (or maybe calling the addFeatures/updateFeatures directly on the REST service - https://developers.arcgis.com/rest/services-reference/enterprise/update-features.htm ). If you are looking for ideas on how to call an edit function from a process, please provide more information on what that process looks like.
... View more
05-16-2022
08:20 AM
|
0
|
1
|
921
|
|
POST
|
You have the Dojo 'On' and 'Dom' calls in your require backwards. In your 'on click' function you call a non-existent graphics layer as you called it 'gl' at the root. And for a 3X library you should be using 'clear()' instead of 'removeAll()' which is from the 4x library. I would recommend you move all of this to the 4x library as it is easily done there as well. This works: <!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
<title>Create circles</title>
<link rel="stylesheet" href="https://js.arcgis.com/3.40/esri/css/esri.css">
<style>
html, body, #map {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
#controls {
background: #fff;
box-shadow: 0 6px 6px -6px #999;
color: #444;
font-family: sans-serif;
height: auto;
left: 1em;
padding: 1em;
position: absolute;
top: 1em;
width: auto;
z-index: 40;
}
#controls div {
padding: 0 0 1em 0;
}
</style>
<script src="https://js.arcgis.com/3.40/"></script>
<script>
var map;
require([
"esri/map", "esri/geometry/Circle", "esri/symbols/SimpleFillSymbol",
"esri/graphic", "esri/layers/GraphicsLayer",
"dojo/dom", "dojo/on", "dojo/dom-attr", "dojo/domReady!"
], function (
Map, Circle, SimpleFillSymbol,
Graphic, GraphicsLayer, dom, on, domAttr
) {
//Setup button click handlers
on(dom.byId("clearGraphics"), "click", function () {
if (map) {
// map.graphics.removeAll();
gl.clear(); //removeAll();
}
});
map = new Map("map", {
basemap: "topo-vector",
center: [-120.741, 56.39],
slider: false,
zoom: 5
});
var symbol = new SimpleFillSymbol().setColor(null).outline.setColor("blue");
var gl = new GraphicsLayer({ id: "circles" });
var geodesic = dom.byId("geodesic");
map.addLayer(gl);
map.on("click", function (e) {
var radius = map.extent.getWidth() / 10;
var circle = new Circle({
center: e.mapPoint,
geodesic: domAttr.get(geodesic, "checked"),
radius: radius
});
var graphic = new Graphic(circle, symbol);
gl.add(graphic);
});
});
</script>
</head>
<body>
<div id="map"></div>
<div id="controls">
<div>Click the map.</div>
<input type="checkbox" id="geodesic">
<label for="geodesic">Geodesic?</label><br />
<button type="button" id="clearGraphics">Clear Graphics</button>
</div>
</body>
</html>
... View more
05-13-2022
08:02 AM
|
1
|
1
|
2254
|
|
POST
|
SyNguyen, Not sure if you are trying to use this sample directly or not, but at 4.23 Esri has modified the Editor widget to be driven by Calcite theming instead of the CSS they had before. That makes the 'esri-editor__back-button esri-interactive' classes that this sample relied on non-existent. I have opened a ticket with this with Esri but so far nothing's been done about it. Since I have an application that relies on this as well, I am hoping that Esri can come up with a solution that can pull out the section of the Editor Widget to tie this button change to, otherwise I'm going to have to stay on pre 4.23 versions (and never get the benefit of a Date popup calendar) or write my own. If you are trying to use a previous version and still having difficulty then let me know and I can try to help.
... View more
04-20-2022
11:11 AM
|
0
|
0
|
2307
|
|
POST
|
The following Sample Code for using the Editor Widget is broken at 4.23. https://developers.arcgis.com/javascript/latest/sample-code/sandbox/?sample=popup-editaction The code looks for a class called "esri-editor__back-button esri-interactive" which used to exist on a DIV that encompassed the back button, but now that DIV (and associated class with the long name) doesn't exist. The sample used this to identify the button DOM node and then add an event listener to it to fully close the Editor widget, but that no longer occurs.
... View more
04-05-2022
05:09 PM
|
2
|
0
|
542
|
|
IDEA
|
Great! Looking forward to it. The only other thing I'm missing is the 'Save' on the layer itself. I think the layer is saved automatically now so you don't have to worry about it but it was somewhat soothing to right click on the layer and see if it that was enabled or disabled, and if it was enabled to click on it to make sure it was saved. Maybe you could just add a dummy one to click on now and then (just kidding). Keep up the great work!
... View more
03-31-2022
01:45 PM
|
0
|
0
|
2256
|
|
IDEA
|
We are still (as an agency) working with the 'legacy' map viewer. I was recently in the newer version, even though it's now just called 'Map Viewer' and noted that it doesn't have a 'Calculate' function on the field's themselves. Not sure if it's in there but it is sure helpful. The other thing that has been missing from even the legacy map viewer is the ability to delete many records at once, unless I've been missing that as well.
... View more
03-31-2022
12:51 PM
|
0
|
9
|
2282
|
|
POST
|
I'm guessing the Editor widget hasn't completed loading yet. Look at this response I just gave about attaching to the ListView 3 ellipse button. If you look at the last entry, in the code example I attach to the widget in the same fashion, but I had to put it in a 'when' event check to make sure it was fully loaded before checking for the classname. https://community.esri.com/t5/arcgis-api-for-javascript-questions/listitem-ellipsis-expanded-event/td-p/1157249
... View more
03-31-2022
07:54 AM
|
0
|
1
|
2372
|
|
POST
|
I guess you could attach to the 3 ellipse button itself. This is from an example that Esri was showing how to attach to the back button of the Editor widget, but it seems to work here as well. // Use the LayerList's 3 ellipse button to do something different
layerList.when(function (results) {
console.log("isFulfilled");
let arrComp = document.getElementsByClassName('esri-layer-list__item-actions-menu-item');
if (arrComp.length > 0) {
// Add a tooltip for the 3 ellipse button
arrComp[0].setAttribute("title", "Something to happen here");
// Add a listerner to listen for when the editor's back button is clicked
arrComp[0].addEventListener('click', function (evt) {
// Prevent the default behavior for the back button and
// instead remove the editor and reopen the popup
evt.preventDefault();
alert("pressed the 3 ellipse button");
});
}
}, function (error) {
console.log("Error in layerList.when")
});
... View more
03-29-2022
04:47 PM
|
0
|
0
|
1424
|
|
POST
|
That should be all that you would need to do. Are you using a 4.x version of the Javascript API? Maybe try "topo-vector", or "streets-relief-vector" to see if you can see any of the vector basemaps.
... View more
03-29-2022
03:12 PM
|
0
|
1
|
1356
|
|
POST
|
Ranga, Everytime the table's 'selection-change' event is fired it provides a list of rows added or removed from the selection. So after you set up the FeatureTable, set up a watch on that event such as: // Get the FeatureLayer's layerView and listen for the table's selection-change event
// Here I'm maintaining a list of features for use elsewhere
let lstFeatures = [];
aFTable.on("selection-change", function (changes) {
var idxItem = 1;
// If the selection is removed, remove the feature from the array
changes.removed.forEach(function (item) {
const data = lstFeatures.find(function (data) {
return data.feature === item.feature;
});
if (data) {
lstFeatures.splice(lstFeatures.indexOf(data), 1);
}
});
// If the selection is added, push all added selections to array
changes.added.forEach(function (item) {
const feature = item.feature;
lstFeatures.push({
feature: feature
});
});
zoomToSelectedFeature(aLayer, lstFeatures, aView);
});
... View more
03-29-2022
08:21 AM
|
1
|
0
|
3607
|
|
POST
|
The 3 ellipse button performs the 'action' of the ListItem. If you look at the code, there is a function created called 'defineActions'. This is then used in the LayerList creation by specifying the property 'listItemCreatedFunction' as this function called 'defineActions'. This process will pull in the objects created through the 'defineActions' function. If you look at the 'defineActions' function, it first determines if this is the layer that should have these actions defined by looking at the ListItem Title property: if (item.title === "US Demographics") { Then it sets up what will happen when you click on the 3 ellipse button for this ListItem using the 'actionSections' property: item.actionsSections = [
[
{
title: "Go to full extent",
className: "esri-icon-zoom-out-fixed",
id: "full-extent"
},
{
title: "Layer information",
className: "esri-icon-description",
id: "information"
}
],
[
{
title: "Increase opacity",
className: "esri-icon-up",
id: "increase-opacity"
},
{
title: "Decrease opacity",
className: "esri-icon-down",
id: "decrease-opacity"
}
]
];
} And also, even though it goes beyond your '3 ellipse' question, the function then adds the opacity slider to each sub item by searching to see if it is a child of a ListItem and has a parent: if(item.children.length > 1 && item.parent){
const slider = new Slider({
min: 0,
max: 1,
precision: 2,
values: [ 1 ],
visibleElements: {
labels: true,
rangeLabels: true
}
});
item.panel = {
content: slider,
className: "esri-icon-sliders-horizontal",
title: "Change layer opacity"
}
slider.on("thumb-drag", (event) => {
const { value } = event;
item.layer.opacity = value;
})
} That is what is used to setup the functions under the 3 ellipse button, as well as what happens with the opacity slider underneath. Later on in the code, after the view has had a chance to finish rendering (under 'view.when(() => {'), and after the LayerList (layerList) has been created, there is the definition of what to do when the "trigger-action" event is fired. This is what determines what will happen when an item from the 3 ellipse button drop down gets selected because the 'id' used in the actionsSections corresponds to the 'id' used in the trigger-action event bubble. layerList.on("trigger-action", (event) => {
// The layer visible in the view at the time of the trigger.
const visibleLayer = USALayer.visible ? USALayer : censusLayer;
// Capture the action id.
const id = event.action.id;
if (id === "full-extent") {
// if the full-extent action is triggered then navigate
// to the full extent of the visible layer
view.goTo(visibleLayer.fullExtent)
.catch((error) => {
if (error.name != "AbortError"){
console.error(error);
}
});
} else if (id === "information") {
// if the information action is triggered, then
// open the item details page of the service layer
window.open(visibleLayer.url);
} else if (id === "increase-opacity") {
// if the increase-opacity action is triggered, then
// increase the opacity of the GroupLayer by 0.25
if (demographicGroupLayer.opacity < 1) {
demographicGroupLayer.opacity += 0.25;
}
} else if (id === "decrease-opacity") {
// if the decrease-opacity action is triggered, then
// decrease the opacity of the GroupLayer by 0.25
if (demographicGroupLayer.opacity > 0) {
demographicGroupLayer.opacity -= 0.25;
}
}
}); Hopefully this is answers your question.
... View more
03-24-2022
09:27 AM
|
0
|
1
|
1431
|
|
POST
|
I think the layerlist example with associated actions shows you how to do this. This is the URL for it: https://developers.arcgis.com/javascript/latest/sample-code/widgets-layerlist-actions/ I'm not sure if you are asking about something else but this handles customizing the 3 ellipse button on the LayerList itself.
... View more
03-24-2022
07:30 AM
|
0
|
1
|
1441
|
|
POST
|
If you click somewhere and there is not a 'graphic' object the code stops because you are trying to 'getEffectivePopupTemplate()' from a 'null' object. I put in the check for null and it seems to work. view.when(() => {
view.popup.watch("selectedFeature", (graphic) => {
if (graphic != null) {
const graphicTemplate = graphic.getEffectivePopupTemplate();
if (view.popup.viewModel.selectedFeature.attributes.restricted == "True")
{
graphicTemplate.actions.items[0].visible = false;
console.log('hidden');
} else {
graphicTemplate.actions.items[0].visible = true;
console.log('showing');
}
}
})
});
... View more
03-11-2022
09:07 AM
|
1
|
1
|
1010
|
|
POST
|
Adding this as it might help. I had about 5 Python scripts working under Task Scheduler for over a year and then, nothing. They were being run from MS batch files that identified the location of Python and the script file with nothing else in them, and if I ran that batch file they would work. The Task Scheduler tasks were starting, and then stopping after 5 seconds or thereabouts, but no errors or strange logs anywhere. I had logging in my Python files that weren't being hit, so something was stopping it early on. Finally decided to dummy down my Python file until they did work through the Task Scheduler and found that the library 'pyodbc' that I used to call SQL Server was not loading. Still trying to figure out why that library isn't being opened in Task Scheduler but I at least I found something that was causing the problem. I will update if I find out more.
... View more
02-23-2022
09:22 AM
|
1
|
0
|
6763
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 11-01-2022 02:02 PM | |
| 1 | 02-28-2024 01:40 PM | |
| 2 | 02-27-2024 01:13 PM | |
| 1 | 10-18-2022 11:31 AM | |
| 1 | 06-23-2023 09:13 AM |
| Online Status |
Offline
|
| Date Last Visited |
05-28-2025
09:15 AM
|