Using the old way of the Editor Widget wir used a filter function to exclude specific layers from the "front-page" of the EditorWidget while keeping the ability to still edit features of these layers.
This is how we successfully did that:
[...]
this._activeEditor = new Editor({
view: mapView,
container: this.canvasId,
layerInfos
});
this._activeEditor.when(() => {
this.setFeatureTemplatesFilterAsync();
});
}
private async setFeatureTemplatesFilterAsync() {
const excludedTitles = await this._schema.getLayerNamesFromKeysAsync([LshLayerKeysEnum.CavePolygons, LshLayerKeysEnum.RoutingPositions]) ?? [];
this._activeEditor!.viewModel.featureTemplatesViewModel.filterFunction = (item) => {
return !excludedTitles.some(title => item?.label?.startsWith(title));
};
}
Now after changing to new web component I am asking myseld how to set the filterFunction or how to access the viewModel.
This is how it currently looks without setting the filterFunction.
<arcgis-editor
reference-element="my-map"
[layerInfos]="layerInfos()">
</arcgis-editor>
Solved! Go to Solution.
I found a way to access it, but since the Editor-Type is still deprecated I guess this is not a good long-term way.
Any suggestions here?
const editorElement = document.querySelector('arcgis-editor') as (HTMLElement & {
componentOnReady?: () => Promise<void>;
widget?: Editor;
}) | null;
if (!editorElement) {
return;
}
if (typeof editorElement.componentOnReady === 'function') {
await editorElement.componentOnReady();
}
const editorWidget = editorElement.widget;
if (!editorWidget?.viewModel?.featureTemplatesViewModel) {
return;
}
editorWidget.viewModel.featureTemplatesViewModel.filterFunction = item => {
return !excludedTitles.some(title => item?.label?.startsWith(title));
};
Edit: This Template Solution does not work, because, when creating one of these excluded Features via Relation of another non-excluded Feature, they are not selectable.
So the dirty DOM Solution is the one to choose.
As an dirty alternative we also found another (more future reliable way) by DOM manipulation:
/**
* Observes the ArcGIS Editor shadow DOM for runtime UI updates.
* The ArcGIS Editor dynamically rebuilds its internal DOM structure.
* Therefore hidden create entries would reappear after rerendering
* without a MutationObserver.
* This observer listens for DOM changes and reapplies the
* create-entry hiding logic whenever the editor updates itself.
*/
private observeEditorDom() {
// Get the ArcGIS editor web component
const editor = document.querySelector(
'arcgis-editor'
) as HTMLElement | null;
// Abort if the shadow DOM is not available yet
if (!editor?.shadowRoot) {
return;
}
const root = editor.shadowRoot;
// Reapply hiding logic whenever the editor rerenders
const observer = new MutationObserver(() => {
this.hideConfiguredCreateEntriesAsync(root);
});
// Observe the complete editor subtree for changes
observer.observe(root, {
childList: true,
subtree: true
});
// Initial execution after observer registration
this.hideConfiguredCreateEntriesAsync(root);
}
/**
* Hides configured layer create entries from the ArcGIS Editor UI.
* Important:
* - Only the visible UI entries are hidden
* - Layers/templates remain fully functional internally
* - Related feature creation therefore still works
* The method only targets the "Create Features" section.
* Related feature dialogs are ignored automatically because they
* use a different DOM structure.
* @Param root Shadow root of the ArcGIS Editor component
*/
private async hideConfiguredCreateEntriesAsync(root: ShadowRoot) {
// Get currently active flow item inside the editor
const selectedFlowItem = root.querySelector(
'calcite-flow-item[selected]'
) as HTMLElement | null;
// Only the Create Features Section contains this container.
// Related feature dialogs do not contain it.
const createTemplatesContainer = selectedFlowItem?.querySelector(
'.esri-editor__feature-templates-container'
);
// Abort if current view is not the create-features screen
if (!selectedFlowItem || !createTemplatesContainer) {
return;
}
// Resolve layer names dynamically via schema configuration
const hiddenEntryNames =
...) ?? [];
// Collect all create-entry groups rendered by ArcGIS
const groups = Array.from(
createTemplatesContainer.querySelectorAll(
'.esri-item-list__group'
)
).filter(
(element): element is HTMLElement =>
element instanceof HTMLElement
);
// Iterate through all rendered create groups
for (const group of groups) {
// Extract the visible heading text
const groupHeading = group.querySelector(
'.esri-widget__heading'
);
const groupHeadingText = groupHeading
?.textContent
?.trim();
// Skip invalid entries
if (!groupHeadingText) {
continue;
}
// Check whether current group should be hidden
const shouldHide = hiddenEntryNames.some(
hiddenName => groupHeadingText === hiddenName
);
// Skip unrelated or already hidden groups
if (!shouldHide || group.dataset['createEntryHidden'] === 'true') {
continue;
}
// Hide the complete create entry group
group.style.display = 'none';
// Mark as processed to avoid duplicate work
group.dataset['createEntryHidden'] = 'true';
}
}
I found a way to access it, but since the Editor-Type is still deprecated I guess this is not a good long-term way.
Any suggestions here?
const editorElement = document.querySelector('arcgis-editor') as (HTMLElement & {
componentOnReady?: () => Promise<void>;
widget?: Editor;
}) | null;
if (!editorElement) {
return;
}
if (typeof editorElement.componentOnReady === 'function') {
await editorElement.componentOnReady();
}
const editorWidget = editorElement.widget;
if (!editorWidget?.viewModel?.featureTemplatesViewModel) {
return;
}
editorWidget.viewModel.featureTemplatesViewModel.filterFunction = item => {
return !excludedTitles.some(title => item?.label?.startsWith(title));
};
Edit: This Template Solution does not work, because, when creating one of these excluded Features via Relation of another non-excluded Feature, they are not selectable.
So the dirty DOM Solution is the one to choose.
As an dirty alternative we also found another (more future reliable way) by DOM manipulation:
/**
* Observes the ArcGIS Editor shadow DOM for runtime UI updates.
* The ArcGIS Editor dynamically rebuilds its internal DOM structure.
* Therefore hidden create entries would reappear after rerendering
* without a MutationObserver.
* This observer listens for DOM changes and reapplies the
* create-entry hiding logic whenever the editor updates itself.
*/
private observeEditorDom() {
// Get the ArcGIS editor web component
const editor = document.querySelector(
'arcgis-editor'
) as HTMLElement | null;
// Abort if the shadow DOM is not available yet
if (!editor?.shadowRoot) {
return;
}
const root = editor.shadowRoot;
// Reapply hiding logic whenever the editor rerenders
const observer = new MutationObserver(() => {
this.hideConfiguredCreateEntriesAsync(root);
});
// Observe the complete editor subtree for changes
observer.observe(root, {
childList: true,
subtree: true
});
// Initial execution after observer registration
this.hideConfiguredCreateEntriesAsync(root);
}
/**
* Hides configured layer create entries from the ArcGIS Editor UI.
* Important:
* - Only the visible UI entries are hidden
* - Layers/templates remain fully functional internally
* - Related feature creation therefore still works
* The method only targets the "Create Features" section.
* Related feature dialogs are ignored automatically because they
* use a different DOM structure.
* @Param root Shadow root of the ArcGIS Editor component
*/
private async hideConfiguredCreateEntriesAsync(root: ShadowRoot) {
// Get currently active flow item inside the editor
const selectedFlowItem = root.querySelector(
'calcite-flow-item[selected]'
) as HTMLElement | null;
// Only the Create Features Section contains this container.
// Related feature dialogs do not contain it.
const createTemplatesContainer = selectedFlowItem?.querySelector(
'.esri-editor__feature-templates-container'
);
// Abort if current view is not the create-features screen
if (!selectedFlowItem || !createTemplatesContainer) {
return;
}
// Resolve layer names dynamically via schema configuration
const hiddenEntryNames =
...) ?? [];
// Collect all create-entry groups rendered by ArcGIS
const groups = Array.from(
createTemplatesContainer.querySelectorAll(
'.esri-item-list__group'
)
).filter(
(element): element is HTMLElement =>
element instanceof HTMLElement
);
// Iterate through all rendered create groups
for (const group of groups) {
// Extract the visible heading text
const groupHeading = group.querySelector(
'.esri-widget__heading'
);
const groupHeadingText = groupHeading
?.textContent
?.trim();
// Skip invalid entries
if (!groupHeadingText) {
continue;
}
// Check whether current group should be hidden
const shouldHide = hiddenEntryNames.some(
hiddenName => groupHeadingText === hiddenName
);
// Skip unrelated or already hidden groups
if (!shouldHide || group.dataset['createEntryHidden'] === 'true') {
continue;
}
// Hide the complete create entry group
group.style.display = 'none';
// Mark as processed to avoid duplicate work
group.dataset['createEntryHidden'] = 'true';
}
}
I not heard that another colleague had already contact to some Devs from ESRI and they are on it to add a top level option to achieve this. Til then we simply use the dirty workaround.