|
POST
|
Adding a CSS selector like this appears to work: <style type="text/css">
div.esri-editor calcite-accordion-item[data-testid="settings"] {
display: none;
}
</style>
... View more
12-21-2023
09:26 AM
|
1
|
0
|
1053
|
|
POST
|
It appears the fourth item listed under the "Creating a Basemap" section of the Basemap module documentation is what you're looking for.
... View more
12-21-2023
09:09 AM
|
1
|
0
|
930
|
|
POST
|
If you're using Oracle, it has a 1000 item limit for the IN operator. There are various ways around this, and I recommend the answer suggested here.
... View more
12-21-2023
09:04 AM
|
0
|
0
|
711
|
|
POST
|
Looks like @LaurenBoyd has a Christmas present that's going to make a lot of people happy this year. According to this page, the popup will display features in layer order starting in 4.29 (expected release in February 2024). "The Popup and Features widgets now display features from multiple layers in the order they are displayed in the map. This means that the features of the topmost layer in the map will appear first, followed by the features of the next layer, and so on. In previous versions, the features were displayed in the order they were returned from the server."
... View more
12-20-2023
03:34 PM
|
1
|
0
|
2549
|
|
POST
|
The short answer is no, you can't override those with page-level CSS like you could previously. The good news is that it's still possible to hide these elements, using the approach mentioned here. The rest (which I apologize for) just adds some depth to the overall topic. Changes to the Popup in 4.28 were fairly radical due to the Calcite integration that took place in that release. As a result, many of the elements are now in a shadow DOM where they can't be touched by page-level CSS selectors. This was definitely the biggest problem I wrestled with in the upgrade to 4.28. To illustrate, popups in our framework (which supports over 100 unique applications) look something like this in 4.27: Opinions may vary as to whether that's aesthetically pleasing or not, but it has looked generally the same since the early days of 3.x over 10 years ago, and it matches the theme of the rest of the UI. Like most windows in a GUI, it has a title bar at the top, and this layout favors the content, making it the most important feature of the popup. Tools - which are of lesser importance than the content - are at the bottom, which makes perfect sense. Enter 4.28, and that all changes to something like this: We now have a pagination bar above the title bar, which is a layout contrary to the accepted standard since the days of Windows 3.1. Furthermore, the appearance of this bar cannot be changed with page-level CSS. It also takes up much more space than is necessary in comparison to 4.27 (where it was embedded in the action bar). As can be seen, less "real" content fits in the popup as a result. Additionally, depending on where the popup is on the screen, this pagination bar might appear either at the top of the popup or the bottom, giving the user an inconsistent experience. The appearance of the title bar cannot be changed with page-level CSS, like it could for the last decade. (Fortunately, the docking button was easy to hide with a simple configuration parameter.) Tools of lesser importance are now in a more prominent location directly beneath the title bar. All this makes the user's eyes wander through a bunch of unwanted clutter before getting to the main content. In addition, the appearance of this action bar cannot be changed with page-level CSS either. So not only did it no longer fit the look-and-feel of our framework, it just isn't laid out well either. Should we then overhaul the entire framework's UI just to match this new-and-improved look and layout? How many hours/weeks/months would that take? Even if we didn't, what about the numerous hours we'd be spending just updating screenshots within our documentation? Fortunately, I was able to reproduce enough of the pre-4.28 appearance to be acceptable, but not without a lot of hacking. For example, this post mentioned previous shows how to programmatically adjust the styling of elements in a shadow DOM, but it has to be done every time the popup opens. Nonetheless, it works, but I had to add over 100 lines of some of the ugliest code I've written: var contentFeatureElement = popup.container.querySelector(".esri-features__content-feature");
var headerElement = contentFeatureElement?.shadowRoot.querySelector("calcite-panel")?.shadowRoot?.querySelector("div.header-container");
if (headerElement) {
//Title bar
headerElement.style.backgroundImage = "linear-gradient(#19628C, #114562)";
headerElement.style.backgroundColor = "#19628C";
//The 'x' (close) button and dock buttons at the right-hand side of the title bar
var element, elements = headerElement.querySelectorAll(".header-actions calcite-action");
for (var x = 0; x < elements.length; x++) {
element = elements[x].shadowRoot?.querySelector("button");
if (element) {
element.style.backgroundImage = "linear-gradient(#19628C, #114562)";
element.style.backgroundColor = "#19628C";
element.style.color = "#FFFFFF";
}
}
//The action bar (immediately beneath the title bar)
var calciteActionBar = contentFeatureElement.querySelector("calcite-action-bar");
if (calciteActionBar) {
calciteActionBar.style.backgroundColor = "#EEF7FD";
calciteActionBar.style.borderTop = "1px solid #19628C";
calciteActionBar.style.borderBottom = "1px solid #19628C";
//The individual buttons in the action bar
elements = calciteActionBar.querySelectorAll("calcite-action");
for (var x = 0; x < elements.length; x++) {
element = elements[x].shadowRoot?.querySelector("button");
if (element) {
element.style.backgroundColor = "#EEF7FD";
element.style.outline = "none !important";
}
}
//The button for the "More" menu to the right of the other action buttons (if it exists)
element = calciteActionBar.querySelector("calcite-action-group")?.shadowRoot?.querySelector("calcite-action")?.shadowRoot?.querySelector("button");
if (element)
element.style.backgroundColor = "#EEF7FD";
}
//The section below is for the pagination bar, which only appears when the popup has multiple features; can appear at the top (header) or the bottom (footer)
calciteActionBar = popup.container.querySelector(".esri-features__pagination-action-bar");
if (calciteActionBar) {
calciteActionBar.style.backgroundColor = "#EEF7FD";
//The < (Previous) and > (Next) buttons at the left-hand side of the bar
elements = calciteActionBar.querySelectorAll("calcite-action");
for (var x = 0; x < elements.length; x++) {
element = elements[x].shadowRoot?.querySelector("button");
if (element)
element.style.backgroundColor = "#EEF7FD";
}
//The "Select feature" button at the right-hand side of the bar
element = calciteActionBar.nextElementSibling.shadowRoot?.querySelector("button");
if (element)
element.style.backgroundColor = "#EEF7FD";
}
//Check if the popup is in feature selection mode (i.e. when there are multiple features)
var listItemGroup = popup.container.querySelector("calcite-list-item-group");
if (listItemGroup) {
//The table in which the features are listed
element = listItemGroup.parentNode.shadowRoot?.querySelector("table");
if (element)
element.style.border = "1px solid #BECEDE";
//The title bar of the table
element = listItemGroup.shadowRoot?.querySelector("tr");
if (element) {
element.style.backgroundColor = "#BECEDE";
element.style.color = "#000066";
}
//Individual rows in the table
elements = listItemGroup.querySelectorAll("calcite-list-item");
for (var x = 0; x < elements.length; x++) {
element = elements[x].shadowRoot?.querySelector("tr");
if (element)
element.style.backgroundColor = ((x % 2 === 0) ? "#DFECF7" : "#EEF7FD");
}
var calcitePanel = popup.container.querySelectorAll("calcite-flow-item")[1]?.shadowRoot?.querySelector("calcite-panel");
if (calcitePanel) {
//The title bar
element = calcitePanel.shadowRoot?.querySelector("div.header-container");
if (element) {
element.style.backgroundImage = "linear-gradient(#19628C, #114562)";
element.style.backgroundColor = "#19628C";
element.style.color = "#FFFFFF";
//The title sub-text
element = element.querySelector(".header-content .description");
if (element)
element.style.color = "inherit";
}
//The back button in the title bar
element = calcitePanel.querySelector("calcite-action")?.shadowRoot?.querySelector("button");
if (element) {
element.style.backgroundImage = "linear-gradient(#19628C, #114562)";
element.style.backgroundColor = "#19628C";
element.style.color = "#FFFFFF";
}
}
}
} In addition, slight modifications were made to our locally-hosted copy of the API to (1) force the action bar to appear below the content, and (2) force the pagination bar to always appear at the bottom whenever it's visible. So we now have something like this instead: As I mentioned earlier, the pagination controls take up way more room than they need, but it is what it is...
... View more
12-19-2023
12:07 PM
|
5
|
2
|
4694
|
|
POST
|
Have you used the "setLocale" method of the esri/intl module? I've found that it changes the language of that option as expected. For example: intl.setLocale("es"); I've also found this changes the text of the "Zoom to" utility on the popup, as mentioned in your other thread.
... View more
12-18-2023
09:25 AM
|
0
|
0
|
598
|
|
POST
|
Everything said here is accurate, but the nuances of the OID field name can be avoided by using query.objectIds instead of query.where.
... View more
12-13-2023
09:24 AM
|
3
|
2
|
2931
|
|
POST
|
This isn't the prettiest thing, but it works; I would recommend adding it directly after creating your MapView. reactiveUtils.when(() => view.popup?.actions, ()=>{
view.popup.watch("selectedFeatureIndex, visible, location", function(newValue, oldValue, propertyName, target) {
if ((target.visible) && (target.selectedFeatureIndex === 0) && (target.selectedFeature.geometry?.type == "point") && (!target.selectedFeature.geometry.equals(target.location)))
target.location = target.selectedFeature.geometry.clone();
});
}); (Note that reactiveUtils is esri/core/reactiveUtils)
... View more
12-12-2023
03:01 PM
|
1
|
0
|
1193
|
|
POST
|
No, the problem here is that those properties have been added in the wrong location. Instead, see lines 74, 88, and 125 below: <html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<title>Editor widget with configurations | Sample | ArcGIS Maps SDK for JavaScript 4.28</title>
<link rel="stylesheet" href="https://js.arcgis.com/4.28/esri/themes/light/main.css" />
<script src="https://js.arcgis.com/4.28/"></script>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<script>
require(["esri/WebMap", "esri/views/MapView", "esri/widgets/Editor"], function (
WebMap,
MapView,
Editor
) {
let editConfigCrimeLayer, editConfigPoliceLayer;
// Create a map from the referenced webmap item id
let webmap = new WebMap({
portalItem: {
id: "154ba34201774bb29f7c3b68adf52b6a"
}
});
let view = new MapView({
container: "viewDiv",
map: webmap
});
view.when(() => {
// Create a custom group to separate the different areas of crime.
// This function takes a 'grouping' object which contains a feature template and a feature layer.
function customGroup(grouping) {
// If the layer is 'Police routes', do not group.
let groupHeading = "Police Routes";
if (grouping.layer.title.toLowerCase() === "crime map") {
switch (grouping.template.name) {
case "Criminal Homicide":
case "Rape":
case "Robbery":
case "Aggravated Assault":
groupHeading = "Violent Crime";
break;
case "Arson":
case "Burglary":
case "Larceny":
case "Motor Vehicle Theft":
groupHeading = "Property Crime";
break;
default:
groupHeading = "Quality of Life";
}
}
return groupHeading;
}
// Loop through the webmap's layers and set an edit configuration
view.map.layers.forEach((layer) => {
if (layer.title === "Police routes") {
editConfigPoliceLayer = {
layer: layer,
geometryUpdatesEnabled: false,
formTemplate: { //autocastable to FormTemplate
// Set it so that only one field displays within the form
elements: [{ // autocastable to FieldElement
type: "field",
fieldName: "PatrolType",
label: "Patrol Type"
}]
}
};
} else {
// Specify a few of the fields to edit within the form
editConfigCrimeLayer = {
layer: layer,
geometryUpdatesEnabled: false,
formTemplate: { // autocastable to FormTemplate
elements: [{ // autocastable to FieldElement
type: "field",
fieldName: "fulladdr",
label: "Full Address"
},
{
type: "field",
fieldName: "neighborhood",
label: "Neighborhood"
},
{
type: "field",
fieldName: "ucrdesc",
label: "UCR Description"
},
{
type: "field",
fieldName: "crimecategory",
label: "Category"
},
{
type: "field",
fieldName: "casestatus",
label: "Status"
}
]
}
};
}
});
// Create the Editor
const editor = new Editor({
view: view,
// Pass in the configurations created above
layerInfos: [editConfigCrimeLayer, editConfigPoliceLayer],
// Override the default template behavior of the Editor widget
supportingWidgetDefaults: {
featureTemplates: {
groupBy: customGroup
}
}
});
// Add widget to the view
view.ui.add(editor, "top-right");
});
});
</script>
</head>
<body>
<div id="viewDiv"></div>
<div id="editorDiv"></div>
</body>
</html>
... View more
12-06-2023
09:45 AM
|
0
|
1
|
943
|
|
POST
|
It doesn't appear there's a documented way to make the View update when a geometry's coordinates have changed, apart from cloning the geometry or the graphic. Probably the best alternate way to achieve this is to use the undocumented "notifyGeometryChanged" method of the Graphic class. For example: graphic.geometry.latitude = newLat;
graphic.geometry.longitude = newLon;
graphic.notifyGeometryChanged(); If you go in this direction, you'd need to change your "pointsBySerialNumber" map to store references to the graphic objects instead of the point objects.
... View more
12-05-2023
04:11 PM
|
0
|
0
|
567
|
|
POST
|
In that case, you want to remove the maxAllowableOffset parameter: if (params.requestOptions.query.maxAllowableOffset) {
delete params.requestOptions.query.maxAllowableOffset;
} The 3.x API Search tool did a better job of calculating that value than its 4.x counterpart.
... View more
12-05-2023
12:32 PM
|
2
|
1
|
3623
|
|
POST
|
Since you're using optional chaining on line 4, you might do the same on line 9: if (params.requestOptions.query?.quantizationParameters)
... View more
12-05-2023
11:25 AM
|
0
|
3
|
3628
|
|
POST
|
I see; that statement is probably out of date, and should read something like "Only supported with ArcGIS Online hosted services or ArcGIS Enterprise 10.6.1 and later services." @KristianEkenes can you confirm?
... View more
12-05-2023
10:33 AM
|
0
|
5
|
3632
|
|
POST
|
As far as I know, the same approach mentioned above would work. Can you add a link to the ESRI documentation you mentioned?
... View more
12-05-2023
09:29 AM
|
0
|
7
|
3639
|
|
POST
|
The print service doesn't actually accept a custom file name for the file it generates. Instead, the Print widget works by using the link element's download property to tell the browser to save the output file with a different name. You can reproduce this just using the print module with something like the following: print.execute(url, printParameters).then(function(dataFile) {
fetch(dataFile.url).then(function(response) {
response.blob().then(function(blob) {
var a = document.createElement("a");
a.style.display = "none";
a.href = window.URL.createObjectURL(blob);
a.target = "_blank";
a.download = "MyFile" + dataFile.url.substring(dataFile.url.lastIndexOf("."));
document.body.appendChild(a);
a.click();
a.remove();
a = null;
});
});
});
... View more
12-04-2023
11:24 AM
|
1
|
0
|
1483
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 03-19-2024 10:37 AM | |
| 1 | 03-31-2026 02:34 PM | |
| 1 | 12-09-2025 09:35 AM | |
| 2 | 12-09-2025 09:06 AM | |
| 1 | 11-26-2025 12:29 PM |