Hello Team,
We are using Arcgis JavaScript API 4.23 sketch and layer list widget.
The issue is when any geometry is selected from sketch widget, LayerList widget additional button (custom) like to delete and cluster is hidden. We need to reopen the Layer list widgets to view the button's.
Could you help us why LayerList widget is impacted when we use/select sketch widget geometry to draw?
Is there any way to stop that behavior other than re-open LayerList widget?
Enclosed html page sample is created in the ArcGIS JavaScript sandbox.
Steps to reproduce issue:-
1. Expand Legend and click group 1.
2. Expand TOC (right side) and expand predefined group layer
3. click on sketch widget(in bottom) point geometry.
4. observe layerlist widget cluster, del icon gone
<html>
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="initial-scale=1, maximum-scale=1,user-scalable=no"
/>
<title>
LayerList widget with actions | Sample | ArcGIS API for JavaScript 4.23
</title>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
overflow: hidden;
}
</style>
<link
rel="stylesheet"
href="https://js.arcgis.com/4.19/esri/themes/light/main.css"
/>
<script src="https://js.arcgis.com/4.19/"></script>
<script>
var demographicGroupLayer = null;
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/GroupLayer",
"esri/layers/FeatureLayer",
"esri/widgets/LayerList",
'esri/widgets/Legend',
'esri/widgets/Expand',
"esri/layers/GraphicsLayer",
"esri/widgets/Sketch"
], (Map, MapView, GroupLayer, FeatureLayer, LayerList, Legend, Expand,
GraphicsLayer, Sketch) => {
// Create layer showing sample data of the United States.
// Create GroupLayer with the two MapImageLayers created above
// as children layers.
// Create a map and add the group layer to it
const map = new Map({
basemap: "gray-vector",
layers: []
});
// Add the map to a MapView
const view = new MapView({
center: [-98.5795, 39.8282],
zoom: 4,
container: "viewDiv",
map: map
});
const graphicsLayer = new GraphicsLayer();
graphicsLayer.listMode = "hide";
const legend = new Legend({
view: view,
container: 'legendDiv',
});
const infoDiv = document.getElementById('infoDiv');
view.ui.add(
new Expand({
view: view,
content: infoDiv,
expandTooltip: 'Expand Legend',
collapseTooltip: 'Collapse Legend',
expandIconClass: 'esri-icon-layer-list',
expanded: false,
}),
'top-left'
);
function updateAllLayer() {
map.allLayers.items.forEach((l) => {
if (l.type === 'feature') {
updateTOC(l.id);
}
});
}
function handleSpace(className) {
const spaceFiller = '_qb_count_';
className = className.toString().trim();
className = className.replace(/\s/g, spaceFiller);
return className;
}
view.when(() => {
const sketch = new Sketch({
layer: graphicsLayer,
view: view,
// graphic will be selected as soon as it is created
creationMode: "update"
});
view.ui.add(sketch, "bottom-right");
demographicGroupLayer = new GroupLayer({
title: 'Predefined',
visible: true,
listMode: 'show',
visibilityMode: 'independent',
layers: []
});
map.add(demographicGroupLayer);
// Create the LayerList widget with the associated actions
// and add it to the top-right corner of the view.
const layerList = new LayerList({
view: view,
// executes for each ListItem in the LayerList
listItemCreatedFunction: function (event) {
const item = event.item;
if (item && item.layer && item.layer.type !== 'group') {
const layerId = handleSpace(item.layer.id);
item.panel = {
content: null,
className: 'esri_layer_action_toc_' + layerId,
open: false,
};
} else if (item && item.layer && item.layer.type === 'group') {
const layerId = handleSpace(item.layer.id);
item.panel = {
content: null,
className: 'esri_layer_action_group_count_' + layerId,
open: false,
};
}
},
container: document.createElement(
'div',
document.getElementById('viewDiv')
),
});
// Add widget to the top right corner of the view
const tocExpandWidget = new Expand({
view: view,
expandTooltip: 'Expand TOC',
collapseTooltip: 'Collapse TOC',
content: layerList.container,
expandIconClass: 'esri-icon-layer-list',
group: 'top-right',
});
view.ui.add(tocExpandWidget, { position: 'top-right' });
tocExpandWidget.watch('expanded', function (evt) {
if (evt) {
updateAllLayer();
}
});
});
const secondGrpButton = document.getElementById('SecondBtn');
secondGrpButton.addEventListener('click', () => {
createGrp2();
});
const FirstGrpButton = document.getElementById('FirstBtn');
FirstGrpButton.addEventListener('click', () => {
createGrp1();
});
function getClusterSettings() {
return {
type: 'cluster',
clusterRadius: '100px',
// {cluster_count} is an aggregate field containing
// the number of features comprised by the cluster
popupTemplate: {
title: 'Cluster summary',
content: 'This cluster represents {cluster_count}.',
fieldInfos: [
{
fieldName: 'cluster_count',
format: {
places: 0,
digitSeparator: true,
},
},
],
},
clusterMinSize: '24px',
clusterMaxSize: '60px',
labelingInfo: [
{
deconflictionStrategy: 'none',
labelExpressionInfo: {
expression: "Text($feature.cluster_count, '#,###')",
},
symbol: {
type: 'text',
color: '#FF0000',
font: {
weight: 'bold',
family: 'Noto Sans',
size: '12px',
},
},
labelPlacement: 'center-center',
},
],
};
}
function createGrp2() {
if (!demographicGroupLayer.findLayerById('Test2_Accidental Deaths')) {
const layers2 = new FeatureLayer({
url: 'https://services.arcgis.com/V6ZHFr6zdgNZuVG0/ArcGIS/rest/services/Accidental_Deaths/FeatureServer/0',
title: 'Accidental Deaths',
id: 'Test2_Accidental Deaths',
});
demographicGroupLayer.add(layers2);
}
if (!demographicGroupLayer.findLayerById('SF Hurricanes')) {
const layers4 = new FeatureLayer({
url: 'https://sampleserver6.arcgisonline.com/arcgis/rest/services/Hurricanes/MapServer/0',
title: 'SF Hurricanes',
id: 'SF Hurricanes',
});
demographicGroupLayer.add(layers4);
}
// setTimeout(() => {
// updateAllLayer();
// }, 5000);
}
function createGrp1() {
if (!demographicGroupLayer.findLayerById('world city')) {
const layers1 = new FeatureLayer({
url: 'https://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer/0',
title: 'city',
id: 'city',
});
demographicGroupLayer.add(layers1);
}
setTimeout(() => {
updateAllLayer();
}, 5000);
// }
}
function mapIndexOfLayer(prefixClass, containerId,layerList) {
const className = prefixClass + containerId.toString().trim();
if (layerList.length === 0) {
return -1;
}
for (let i = 0; i < layerList.length; i++) {
if (className === layerList[i].className) {
return i;
}
}
return -1;
}
function updateTOC(containerId) {
const layerListContainer = document.getElementsByClassName(
'esri_layer_action_toc_' + handleSpace(containerId)
);
const index = mapIndexOfLayer(
'esri_layer_action_toc_',
handleSpace(containerId),
layerListContainer
);
if (index !== -1) {
if (
layerListContainer &&
layerListContainer[index] &&
layerListContainer[index].parentElement &&
layerListContainer[index].parentElement.children.length === 1
) {
const selectedLayer = map.allLayers.filter(function (layer) {
return layer.id === containerId;
});
if (
selectedLayer &&
selectedLayer.get('0') &&
selectedLayer.get('0')['source']
) {
const countDiv = document.createElement('div');
countDiv.id = containerId + '#cluster';
const count = selectedLayer.get('0')['source'].length
? selectedLayer.get('0')['source'].length
: 0;
countDiv.classList.add('layer_list_toc_count');
countDiv.innerHTML = 'cluster';
countDiv.title = 'cluster';
countDiv.style.marginRight = '10px';
countDiv.style.backgroundColor = 'yellow';
countDiv.onclick = function (evt) {
const layerId = evt.target.id.split('#');
console.dir(layerId[0]);
const layers2 = map.findLayerById(layerId[0]);
var fr2 = layers2.featureReduction;
layers2.featureReduction =
fr2 && fr2.type === 'cluster' ? null : getClusterSettings();
};
layerListContainer[index].parentElement.appendChild(countDiv);
const delDiv = document.createElement('div');
delDiv.id = containerId;
delDiv.innerHTML = 'del';
delDiv.style.backgroundColor = 'red';
delDiv.style.color = 'black';
delDiv.classList.add('layer_list_toc_legend');
delDiv.onclick = function (evt) {
if (demographicGroupLayer.findLayerById(evt.target.id)) {
demographicGroupLayer.remove(map.findLayerById(evt.target.id));
}
};
layerListContainer[index].parentElement.appendChild(delDiv);
}
}
}
}
});
</script>
</head>
<body>
<div id="viewDiv"></div>
<div id="infoDiv" class="esri-widget">
<button id="FirstBtn" class="esri-button">Group1</button>
<br />
<button id="SecondBtn" class="esri-button">Group2</button>
<br />
<div id="legendDiv"></div>
</div>
</body>
</html>