<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<title>Load portal items via drag & drop | Sample | ArcGIS Maps SDK for JavaScript</title>
<link rel="stylesheet" href="https://js.arcgis.com/5.0/esri/themes/light/main.css" />
<!-- Load the ArcGIS Maps SDK for JavaScript from CDN -->
<script type="module" src="https://js.arcgis.com/5.0/"></script>
const [WebMap, MapView, Layer, PortalItem, intl, promiseUtils] = await $arcgis.import([
"@arcgis/core/WebMap.js",
"@arcgis/core/views/MapView.js",
"@arcgis/core/layers/Layer.js",
"@arcgis/core/portal/PortalItem.js",
"@arcgis/core/core/promiseUtils.js",
/************************************************************
* Creates a template to display Portal Item Information.
* Any values enclosed in "{}" will be parsed with properties
* from an object using the utility method esri/intl::substitute
************************************************************/
'<div data-itemid="{id}" class="card block" draggable="true">' +
'<figure class="card-image-wrap"><img class="card-image" src="{thumbnailUrl}" alt="Card Thumbnail">' +
'<figcaption class="card-image-caption">{title}</figcaption>' +
'<div class="card-content">' +
"<li>Published Date:</li>" +
// Array of Portal Items for Layers!
"f535a6242eca4f6bad8405be9e41aba4", // brewery locations
"48c86debf28a401c8858d714cf85e859", // accidental deaths
/************************************************************
* Creates a new WebMap instance. A WebMap must reference
* a PortalItem ID that represents a WebMap saved to
* arcgis.com or an on-premise portal.
* To load a WebMap from an on-premise portal, set the portal
* url with config.portalUrl.
************************************************************/
const webmap = new WebMap({
// autocasts as new PortalItem()
id: "2e5f696b97e7424fb5d6ffe001da36b0",
/************************************************************
* Set the WebMap instance to the map property in a MapView.
************************************************************/
const view = new MapView({
map: webmap, // The WebMap instance created above
/************************************************************
* Wait for the MapView to finish loading and create an array
************************************************************/
const portalItems = layerItems.map((itemid) => {
/************************************************************
* We want to load the PortalItem right away so that we can
* read the data, such as "id", "owner", "title", and "created".
* This does not load the Layer itself, but returns a Promise.
************************************************************/
/************************************************************
* Use promiseUtils.eachAlways to wait for all of the
* PortalItem Promises to complete loading.
************************************************************/
promiseUtils.eachAlways(portalItems).then((items) => {
/************************************************************
* Create a DocumentFragment to hold our list elements
* until we are ready to add them to the page.
************************************************************/
const docFrag = document.createDocumentFragment();
const item = result.value;
/************************************************************
* Use esri/intl::substitute will create a new string
* using properties from the PortalItem.
************************************************************/
const card = intl.substitute(template, item);
/************************************************************
* Create a "div" element to hold the new string from the
* template and get the new node from that element to append
* it to the DocumentFragment.
************************************************************/
const elem = document.createElement("div");
// This is a technique to turn a DOM string to a DOM element.
const target = elem.firstChild;
docFrag.appendChild(target);
/************************************************************
* Listen for the "dragstart" event on the list item.
************************************************************/
target.addEventListener("dragstart", (event) => {
/************************************************************
* Get the data attribute from the element and pass it along
* as the data being transferred in the drag event.
************************************************************/
const id = event.currentTarget.getAttribute("data-itemid");
event.dataTransfer.setData("text", id);
/************************************************************
* Append the list item to the page.
************************************************************/
document.querySelector(".cards-list").appendChild(docFrag);
/************************************************************
* Listen for "drop" and "dragover" events on the container
************************************************************/
view.container.addEventListener("dragover", (event) => {
/************************************************************
* On "dragover", you need to specify the dropEffect to drop
* items to an element while dragging.
************************************************************/
event.dataTransfer.dropEffect = "copy";
view.container.addEventListener("drop", (event) => {
/************************************************************
* Element has been dropped into container. Get the "id"
* that was transferred and find it in the item list.
************************************************************/
const id = event.dataTransfer.getData("text");
const resultItem = items.find((x) => {
return x.value.id === id;
const item = resultItem.value;
/************************************************************
* If the item is a Layer item, create a Layer using
************************************************************/
if (item && item.isLayer) {
/************************************************************
* Add the layer to the map and zoom to its extent.
************************************************************/
view.extent = item.extent;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
0 0 0 1px rgba(0, 0, 0, 0.1),
0 0 16px 0 rgba(0, 0, 0, 0.05);
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-flex: 0 0 auto;
padding: 0.35rem 1.25rem 0.35rem 1.25rem;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
-webkit-box-flex: 1 1 auto;
<div id="itemDiv" class="esri-widget">
<label class="description"><b>Instructions:</b><br /></label>
<label class="description">Drag portal items to the Map<br /></label>
<label class="description"></label>
<div class="cards-list"></div>