You will learn: how to add layers to a map from a custom widget.
The map widget in ArcGIS Experience Builder automatically loads layers based on what web map it is configured to load. Depending on your workflow, you may want a custom widget to dynamically add a layer to the map based on user interaction with the widget.
In this tutorial, you will add a button to the widget to add a feature layer to the map.
Be sure to download, install, and configure ArcGIS Experience Builder Developer Edition.
Download the Starter Widget template here.
In the ArcGIS Experience Builder folder, extract the zip into the following path: /client/your-extensions/widgets.
In the terminal where the npm start
is running in the client folder, stop the script by pressing ctrl + c
.
In your file browser, go to the folder where ArcGIS Experience Builder was extracted.
In the ArcGIS Experience Builder folder, expand the following path: /client/your-extensions/widgets.
In the widgets folder, rename the starter-widget folder to add-layers
.
In the newly-renamed add-layers folder, open the manifest.json file in the code editor.
In the code editor, modify the name
property to add-layers
.
{
// *** UPDATE ***
// "name": "starter-widget",
"name": "add-layers",
"type": "widget",
"version": "1.2.0",
After the version
property in manifest.json, add a jimu-arcgis
dependency. Declaring this allows the usage of ArcGIS API for JavaScript modules within the widget.
{
"name": "add-layers",
"type": "widget",
"version": "1.2.0",
// *** ADD ***
"dependency": "jimu-arcgis",
A settings panel can be implemented to allow Experience authors to customize the widget. The settings panel appears in the right-hand sidebar when a widget is selected in ArcGIS Experience Builder. To create the panel, implement the BaseWidgetSetting
class.
In the widget root folder, create a config.json
file that contains an empty object.
{}
setting.tsx
file./** @jsx jsx */
import { React, jsx } from "jimu-core";
import { BaseWidgetSetting, AllWidgetSettingProps } from "jimu-for-builder";
BaseWidgetSetting
.export default class Setting extends BaseWidgetSetting<AllWidgetSettingProps<any>, any> {
render() {
return <div className="widget-setting-demo">This is your starter widget setting area!</div>;
}
}
ctrl + c
) (if applicable) and start the npm start
script in the client folder.In ArcGIS Experience Builder, there can be more than one Map Widget on the page at a time. Because of this, a custom widget must have a section of its Settings Panel that allows the author to choose which map widget to use.
In the setting/setting.tsx file, include the JimuMapViewSelector
module from the jimu
library.
import { JimuMapViewSelector } from "jimu-ui/advanced/setting-components";
Before the render
function, define the onMapWidgetSelected
function.
// *** ADD ***
onMapWidgetSelected = (useMapWidgetIds: string[]) => {
this.props.onSettingChange({
id: this.props.id,
useMapWidgetIds: useMapWidgetIds
});
};
render() {
return <div className="widget-setting-demo">This is your starter widget setting area!</div>;
}
In the render
function, in the return()
statement, add a tag representing the JimuMapViewSelector
.
render() {
return <div className="widget-setting-demo">
<JimuMapViewSelector
useMapWidgetIds={this.props.useMapWidgetIds}
onSelect={this.onMapWidgetSelected}
/>
</div>;
}
In the previous step, the settings panel was enhanced to allow the Map widget to be selected. The map object can be accessed using the JimuMapViewComponent
.
In the widget.tsx file, add the JimuMapViewComponent
and the JimuMapView
type from the jimu
library.
import { JimuMapViewComponent, JimuMapView } from "jimu-arcgis";
Before the render
function, set up the default state.
export default class Widget extends BaseWidget<AllWidgetProps<any>, any> {
// *** ADD ***//
state = {
jimuMapView: null
};
render() {
Add a function to update the state every time the JimuMapView data source changes.
state = {
jimuMapView: null
};
// *** ADD ***//
activeViewChangeHandler = (jmv: JimuMapView) => {
if (jmv) {
this.setState({
jimuMapView: jmv
});
}
};
In the render
function, add the JimuMapViewComponent
to the JSX markup.
render() {
return (
<div className="widget-starter jimu-widget">
{/* *** ADD *** */}
{this.props.hasOwnProperty("useMapWidgetIds") &&
this.props.useMapWidgetIds &&
this.props.useMapWidgetIds.length === 1 && (
<JimuMapViewComponent
useMapWidgetIds={this.props.useMapWidgetIds}
onActiveViewChange={this.activeViewChangeHandler}
/>
)
}
</div>
);
}
Add a button to the UI of the widget that when clicked will add the layer to the map.
In the code editor, add form
and input
tag elements in the existing div
in the render
function.
render() {
return (
<div className="widget-starter jimu-widget">
{this.props.hasOwnProperty("useMapWidgetIds") &&
this.props.useMapWidgetIds &&
this.props.useMapWidgetIds.length === 1 && (
<JimuMapViewComponent
useMapWidgetIds={this.props.useMapWidgetIds}
onActiveViewChange={this.activeViewChangeHandler}
/>
)
}
<!-- Add: -->
<form onSubmit={this.formSubmit}>
<div>
<button>Add Layer</button>
</div>
</form>
</div>
);
}
Above the render
function, create a new function called formSubmit
. This function will get called when the user clicks the Add Layer button.
formSubmit = evt => {
evt.preventDefault();
// More here soon
}
When the button is clicked, add the layer to the map.
At the top of Widget.tsx, import the FeatureLayer
class.
import FeatureLayer = require('esri/layers/FeatureLayer');
In the formSubmit
function, update the code to create the Trailheads (points) feature layer and add it to the map.
formSubmit = evt => {
evt.preventDefault();
// *** ADD ***
// create a new FeatureLayer
const layer = new FeatureLayer({
url: 'https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads_Styled/FeatureServer/0'
});
// Add the layer to the map (accessed through the Experience Builder JimuMapView data source)
this.state.jimuMapView.view.map.add(layer);
}
Once the code changes have been made, you can test your widget by running ArcGIS Experience Builder and viewing your Experience.
In a web browser, go to Experience Builder. e.g. https://localhost:3001
In ArcGIS Experience Builder, click Create New to create a new experience page.
Click the Create button on the Blank scrolling template.
eb1be6543e304b4d81ed55439c412c2c
. Click the search result to select it and then click Done. (Note this web map has no operational layers intentionally.)Click the Insert widget button, and drag the new add-layers widget onto the experience.
In the widget settings panel, choose Map 1 from the map selection dropdown.
In the ArcGIS Experience Builder toolbar, click Save then Preview and the Experience will open in a new browser tab with your custom widget and a map.
In the ArcGIS Experience Builder preview, click the button to add the layer to the map. Compare your widget with our completed widget.
Add a list of layers to the Experience and allow the user to toggle the visibility of each layer.
Allow the user to copy/paste a layer URL into a text box and clicking the button will add that layer to the map. (Challenge solution)