Experience Builder Tips and Tricks

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Latest Activity

(60 Posts)
JeffreyThompson2
MVP Regular Contributor

Last summer, I wrote a philosophical piece about how I use Experience Builder in which I discussed several apps I have built, one of which was an everything app. I explicitly said, "trying to build an everything app in Experience Builder is a very bad idea." Meanwhile, in the Custom Widgets Group, I've been releasing Custom Widgets developed for this everything app while dropping lessons learned in this group. Now, all the pieces are out there and maybe building an everything app isn't such a bad idea anymore. Experience Builder has been pretty much my full-time job for almost two years now and I am putting together almost everything I have learned into one post. 🎶Do you want to build any everything app?🎶

Maybe I should define what I mean by any everything app. Working in city government we want to have a central data repository where our employees can easily look up geographic information and do some light analysis. It needs to be flexible enough to handle data from many different departments without overwhelming the map visually or technologically. Advanced users should be able to make some complex queries, but it needs to be simple enough for users who are not technologically savvy. It must be everything to everyone. Is that Everclear? Does that sound like something you need or want to build? Then take a look at the Atlas Instant App. It's really good. But, maybe it's not quite what you need and it's also very new. I don't know if it made it into Enterprise 11.4, but it's not in 11.3. So, here's how to make one in Experience Builder...

To make this work, you are going to need Developer Edition 1.14 or 1.16, hopefully higher versions will also work, or Enterprise Edition 11.3 or higher, again hopefully. (You may have noticed that 1.15 is conspicuously absent. That is because that version contains a bug that is incompatible with my Add/Remove Layers Widget. Also as the release version chart has not been updated, I cannot confirm compatibility with Enterprise 11.4.) If you're not on one of the compatible versions, well, you don't need to be a developer to use Developer Edition

You will also need a handful of Custom Widgets:

*Before uploading the Add/Remove Layers Widget to your Enterprise, it is highly recommended to pre-load your layers and groups into the layers.ts file of the Widget.

**If your flavor of Experience Builder allows you to turn off Popups from the Map Layers Widget, you might not want to use that option instead.

We'll be building in Enterprise 11.3, so first I will register the Custom Widgets with my Enterprise Portal. Then, I will go to the Web Map Viewer and make seemingly blank map. I am making hybrid layers for my parcel and road layers. This will get me some advanced labeling features and I will also be able to use the secret Map Image Layers to set-up the Query Widget later on. I am using the Feature Layer With Map Image Layer Labeling flavor of hybridization, but I'm skipping the code enhancement in this build. At this point, I have all my Custom Widgets available in my Enterprise Portal and a Webmap that only visibly contains labels for a few layers. Now, it's time to boot up Experience Builder.

I will start by picking my favorite Template, Blank Fullscreen. We will be making a single-page application and, while this layout should be alright on a tablet in landscape mode, I will be making zero attempt at making this look good on a phone.

Oh, the tyranny of the blank page... How shall we start? Well, if you know my stuff, you know I'm probably going to use a Sidebar, actually this layout uses five Sidebars, each one in a slightly different way. The first one is to support our Hidden Widget Trick. I drag in a Sidebar and set it to Full Size. In the Collapsible side of the Sidebar, I drag in my Custom Font Widget. Back in the Settings Panel of the Sidebar Widget, I'm going to click on the Widget's title to change the name to something more descriptive. We're adding a lot of Sidebars and this will get confusing without some labels. Next, I'll set the Size to 0, turn off Resizable and the Collapse Button, and set the Default State to Collapsed. The Custom Font Widget is now hidden forever, but it's font changing powers will live on.

JeffreyThompson2_0-1738610882925.png

Next, we are going to add a "Header" and, since we are not planning to add another Page to this layout, we aren't going to use a Header. Instead of a real Header, we will use a previously unreleased trick by @MichaelGaigg: Sidebars make good Headers. I drag in a Sidebar and set it to Full Size. In the Settings Panel, I'll rename the Sidebar, set the Dock Side to the Top, Size to 80px, turn off Resizable and the Collapse Button, and set the Top Panel Fill to a dark blue. Our Sidebar is now a Header.

JeffreyThompson2_0-1738612184197.png

You know what we really need right now, ANOTHER SIDEBAR!!!!!!!!!! I'll drag this one in, but I won't go Full Size...for now. In fact, I'll make it smaller. I'll drag a Map Widget in the always open side of the Sidebar and set it to Full Size. I add the Webmap I set up earlier. I turn the Zoom, Home, Compass, Measure, Fullscreen, and Extent Navigate Tools on and the other Tools off. (If on a version with the Measure Widget, use that instead of the Measure Tool. If you don't understand the difference, click here.)  I will also turn off Enable Pop-up. The Map Widget is done, we'll circle back to the other side of the Sidebar later. For now, just rename this Sidebar to Map Sidebar.

More Sidebar.jpg

The next Sidebar will hold the Identify Widget, which will handle auto-opening and closing it and will be named Identify Sidebar. I drag in a Sidebar, shrink it a bit, rename it, and switch the Dock Side to the Right. Before going any further, I'm going to drag in the Identify Widget to the Collapsible side of the Map Sidebar. It's not going to stay there, but it's a convenient spot for now. The Identify Widget needs the widget_id number of the Sidebar Widget it controls, but there is no way to see this information in ArcGIS Enterprise, so the easiest way to find this information is to add the Identify Widget immediately after the Sidebar and subtract one from the Identify Widget's number. If you've been following along, the Identify Sidebar should be widget_id number 6. I'll also set connect the Identify Widget to the Map Widget. Next, I drag the Map Sidebar as a whole into the Always Open Side of the Identify Sidebar. Don't worry about how this all looks now, we'll fix it once we have the final Sidebar, which we will add next.

Drag in another Sidebar and name it Table Sidebar. Set the Dock Side to Down. Click back on the Identify Sidebar and drag it to the Always Open Side of the Table Sidebar. Now, we'll start fixing the appearance of our app. Set the Table Sidebar to Full Size. Then do the same for the Identify Sidebar and again on the Map Sidebar. Using the Outline in the Page Settings Panel will be helpful for this bit. If you've done this correctly, you now have five Sidebars around a Map Widget and none of them have The Sidebar Problem™.

sidebars in sidebars.jpg

Ok, we are done adding Sidebars. But before we are done saying Sidebar every fifth word, let's style some Sidebars. We'll start with the Map Sidebar. This Sidebar is intended to contain data related to the map as a whole like the Map Layers and Legend Widgets and a few other Widgets with large vertical outputs. It will be Expanded when the app loads and rarely if ever closed, so the defaults of Overlay off and Default State Expanded are good. I want to make the Size a bit larger though, so I set it to 400px. I also want to make the Collapse Button more visible, so I will make it larger and color it. I set the Icon to the Solid Triangle and increase its size to 20. I set the Background Default color to blue and the Background Hover color to red in accordance with my branding guidelines. I set the Width to 20, the Height to 80, and the Offset X to 20 and now I am satisfied with the way this Sidebar looks. To the Identify Sidebar...

We will also set the Size of the Identify Sidebar to 400px, but as this will be primarily controlled by the Identify Widget, it will be less jarring with Overlay on, and as it will be blank on load, Default State Collapsed makes more sense with this Sidebar. Now that the Right Panel is overlaying the map, it needs a background Fill color, the standard Light color (it's a very light silvery-grey) works well here. For the Collapse Button, we will do everything the same as we did for the Map Sidebar, but the Offset X goes in the negative direction.

Let's go back to the Table Sidebar. Add a Table Widget to the Collapsible Side of the Table Sidebar. Set it to Full Size and done. The Table Widget is configured. Back to the Table Sidebar Settings, I'll turn the Overlay on and the Default State to Collapsed. This drawer can be manually operated by the user after they use the Add To Table Action. Ideally, there would be a configurable Action that would auto-open this drawer, but that doesn't exist yet. The Collapse Button needs to be even larger as it's location and orientation make it less obvious on the screen and we are relying on the end-user to be able to find it. So, I set the Icon size and Height 25, the Width to 120, and the Offset Y to -25 with the same colors as the other Collapse Buttons. We are done with the Table Sidebar. So, click the Collapse Button on the Map to get it out of the way for the next steps.

The Collapsible Side of the Identify Sidebar should be empty right now. Put a Grid Widget in it and make it Full Size. Next, grab the Identify Widget and drag it across into the Grid. Now, drag the Identify Controller Widget right on top of the Identify Widget. The Grid Widget should automatically make Tabs out of these Widgets. Connect the Identify Controller Widget to the Map Widget and it's good to go. In the Grid Widget Settings turn off Allow Resize and Allow Expansion. Maybe rename these Widgets to make the Tab titles a little more clear. If you've been following along, things should look like this now.

JeffreyThompson2_0-1738682661175.png

We are done working on the Identify Sidebar, so you can hit the Collapse Button on that as well.

Now, let's turn our attention to that empty Collapsible Side of the Map Sidebar. Put a Column Widget in it, set it to Full Size and the Gap to 0px. In the Column, add a Views Navigation Widget and pick a Quick Style. I'd recommend one of the top three as they show the View titles. Then add a Section Widget beneath it. It's a little backwards, but that's the easiest way to get the Section Widget to stack neatly under the View Navigation Widget in a Column. In the Section Widget Settings Panel, go to the Style Tab and set the Width and Height to Stretch, if necessary. And what should go inside the Section Widget? Another Column Widget, of course. I swear this isn't going to get out of hand like that Sidebar business earlier. Set the new Column Widget to Full Size and the Gap to 0px, as before.

So what should go inside this Column in a Section in a Column in a Sidebar in a Sidebar in a Sidebar in a Sidebar in a Sidebar? It's time for the Add/Remove Layers Widget. This is going to be the big time suck in building this application. Ideally, you took the time to pre-load all the layers and groups into the Widget before you uploaded it to your Enterprise. Sure, it is technically possible to use this Widget with just the Settings Panel, but adding or changing more than a handful of things in the Settings Panel is really going to suck. Honestly, changing things in the layers.ts file is going to suck too, but it will suck a little less. If you have everything pre-loaded as you like it, all you need to do is drop in the Widget and connect it to the Map Widget. If not, well here comes several hours to days of misery, depending on how many layers you need to put in. Setting up this Widget is not the most strait-forward thing either, so make sure to read the help text on the Widget's page.

If you are reading this, you presumably survived the last step. I commend you. Have a medal. 🏅  Now back to work, you slacker! We're not done, yet. The next thing to go in the Column in a Section in a Column in a Sidebar in a Sidebar in a Sidebar in a Sidebar in a Sidebar that swallowed the spider that swallowed the fly is a Map Layers Widget. Drop it in and connect it to the Map Widget. Turn on the Options as you see fit, I've got them all on except I'm sticking with the eyeballs for visibility and I'm not turning on the sub-option to show the legend by default. Enable Customize Layers and hide your hidden map layers. In the Style Tab, set the Height to Stretch.

This is a good time to go into Preview Mode and test. The Add/Remove Layers Widget should add and remove layers. You should be able to use the Add To Table Action in the Map Layers Widget and see the data in the Table Sidebar. Clicking on the map should open the Identify Sidebar and show results. The Identify Controller should be able to turn on and off Identify on a per layer level. There should be no Sidebar Problem™. Good luck.

...I'm going to assume that all worked fine. Don't know what to tell you if it didn't.  🙃

Add a New View to the Section Widget. Drop in a Basemap Gallery Widget. Set it to Full Size and connect it to the Map Widget. Repeat, but drop in a Legend Widget this time.

Do it again with a Select Widget, but now there are a few more settings to worry about. Turn on Allow Selection of Data Generated At Runtime. You can turn Attribute Selection on or off. It does not matter Attribute Selection will be on either way because the Select Widget operates very differently when data is loaded at runtime and the runtime layers are way more powerful. Go into the Customize Layer options and remove the Webmap loaded layers and open up the Interactive Selection dropdown and turn on all the Select By options.

Add a New View. Then, drop in a Query Widget and make it Full Size. How exactly you configure this is just between you and your data, but I've got a Spatial Query for parcel data based on one of the videos in this series and a couple attribute queries set up on OR clauses (using OR clauses means that users only need to search in one field) for road and parcel data using the hidden layers from the Webmap. I know these layers are the ones my users are most likely to want to search through. I am using the Query Widget to make it easy to search questions I know my users are likely to ask, while the Select Widget and the Set Filter option in the Map Layers Widget allows the users to make arbitrary and more esoteric queries. In this way, I can satisfy both my low-end and high-end users. My pre-built queries look something like this.

JeffreyThompson2_0-1738765915981.png

I've also gone to the Action Tab and set up a Record Selection Changes > Map > Zoom To Action.

That's all I plan on putting in this Section Widget, if you want to add something with a lengthy output like the Near Me Widget or perhaps you want a List Widget, I would recommend adding them as a View in this space. Since I'm done adding content here, I'm going back to the Section Widget Settings Panel to rename my Views to reflect the Widgets they contain. I will also put them in a order I find more logical. I can rename my Views by clicking the three dots to the right of the current titles and I can re-order by dragging and dropping. Let's check-in on how this is all looking in Preview Mode.

JeffreyThompson2_0-1738768364329.png

Hey, the "Header" is blank. Are we going to do anything with that? Yep, we're doing that next. We'll start by adding our Custom Search Widget. It's just a lightly modified version of the official ESRI Widget.  Drop the Custom Search Widget into the Header and then use the Horizontal and Vertical Center options. You'll need to go back to the Identify Widget Settings Panel and to see it's id number (7 in my layout) and add it to the box in the Custom Search Widget Settings Panel. (Wow, ESRI, that's so much easier when the data isn't hidden.) This modified Search Widget is designed to trigger the Identify Widget we added earlier and is only designed for use with a Locator Source (it might work with a point-type Layer Source). The rest of the options under the Content Tab are up to you except Result Panel, which must remain on, but I highly recommend turning on Recent Searches and Auto Select The First Result. Another restriction with this Search Widget is that it must be used with a Map Widget and have a Record Selection Changes > Map > Zoom To Action set up, so I set up such an Action.

At this point, go to Preview Mode and test. Does it trigger the Identify Widget? Do you find all the data you expect? I needed to set a Custom Zoom Scale to 2000 to find my parcel data. Smaller numbers = closer zoom.

Now, I add a Widget Controller to my Header. Snap to Right and Vertically Center. I'm using a Floating Widget Panel Arrangement with the Icon Size set to Large. (I'd go extra-large if I could.)  I turned off Indicator, as I don't really like how it looks and we'll handle it's function by turning on Advanced. After turning on Advanced, I set the Default Icon color to blue and the Selected and Hover color to red. The same blue and red I used for the Collapse Buttons on the Sidebars.

What goes in this Widget Controller? That's again in the up to you category. But I see these buttons as a menu, things that the user may not use everyday, but are useful to have access to. Widgets that don't have a large output and Widgets that encourage map interaction are also good candidates to go in here. My must haves up here are the Add Data, Bookmark, Custom Draw and Print Widgets. If you're on a version of Experience Builder with the Measure Widget, I'd put it here, too. Let's configure these.

In the Add Data Widget, go to the Action Tab and add a Data Added > Map > Add To Map Action. For the Bookmark Widget, I'm going with the simplest of the Simple Templates (the second one). Connect it to the Map Widget and turn on Allow To Add Bookmarks In Widget. This Bookmark Widget is here to help support our flexibility goal. It's up to the user to decide how they want to use it. If you want to add some points of interest as Bookmarks, go ahead, I'm not pre-loading any Bookmarks in my version.

Connect the Draw Widget to the Map and change the title. No one needs to know, it's a custom widget. Why the Custom Draw and not the OOTB Draw? Well, here in Enterprise 11.3, there is no text support, so that's a big factor, but I'm sticking with this @RobertScheitlin__GISP masterpiece in Developer Edition 1.16 because of the freehand draw options and the ability for users to edit their sketches after drawing. The latest versions OOTB Draw Widget has text support with more text options than the Custom Draw Widget, so if text is your primary need and you can, maybe pick the default option instead.

In the Print Widget, I connect it to the Map Widget and add a Print Service. The main problem with this Widget now is it's scrunched up in box that's too small and looks awful. Fortunately, that's a really easy fix. Just drag that little black right angle in the lower left of the Widget until it's the right size. 

Other stuff that I've got in the real version of this application in this Widget Controller:

  • A text box with helpful links
  • A text box with help text
  • This What3Words Widget
  • This NearMap Widget by ESRI Australia that I strongly endorse. Note: NearMap is working on an official Experience Builder product that will include Oriented Imagery support. They are Beta testing now. Talk to your NearMap representative, if you want to take part. But, it better be good to catch up with this Widget that's been out for years now. 
  • This Rain Radar Widget by the same ESRI Australia team that I weakly endorse.

Let's add one more functional Widget before we finish the design. In the lower-left of the Map Widget, I drop in a Coordinates Widget and connect it to the Map Widget. By default, this Widget has a lot of blank space around it, if we don't do something about that we are going to get a variation on The Sidebar Problem™. In the Style Tab, set the Width and Height to Auto to prevent this issue. I also hit Snap To Left. I've seen some weird issues trying to set the default Output Coordinate System option. I haven't tested to see if they have been resolved in more recent versions, so if you want something other than Web Mercator in your Coordinates Widget, it might have to be as a secondary option.

Ok, last thing, I promise. We need a title and some iconography to a make it all look good. I throw an Image Widget in the Header and pick an image. I set the Width to Auto and the Height to 90% and use the Vertical Center option. Then, I use that target box thing to give it a 1% margin from the left of the screen.

JeffreyThompson2_0-1738783564850.png

Next to the Image Widget goes a Text Widget for a title. I'm using Vertical Center again with Width and Height on Auto. I want a title and a subtitle with my subtitle about half the font size of my title, white text to stand out on the dark background and I'll use Right Justification because I'm cool. And yeah, it's done.

JeffreyThompson2_1-1738784242919.png

Look, I won't say it's perfect, but it is an everything app you can build right now, with no-code in less time than it took me to write up how to build it. So maybe you want to build it or maybe just do the Atlas Instant App?

more
5 0 253
JasonBOCQUET
Frequent Contributor

Hello everyone, thanks to @JeffreyThompson2 for all the posts in this group. Today it's my turn to add my contribution, which, although it may seem basic to some, will surely help many users to better manage the interaction between several data sources in ArcGIS Experience Builder.

That tips is avaiable for Online Users and Enterprise User (i'm on ArcGis Enterprise 11.1) by using an ArcGIS Experience Builder Developer Edition (more detail here : https://developers.arcgis.com/experience-builder/guide/install-guide/)

ArcGIS Experience Builder is perfect for creating applications that combine maps, charts, tables, lists and more. Layout and production of a user application is really very simple. You'd be tempted to throw your entire database into it, and with just a couple of clicks you'd be able to interact in all directions, resulting in an ergonomic and efficient application. But despite its power, Expérience Builder does have its limitations, particularly when it comes to managing multiple data sources simultaneously.

When I started with version 1.10 of Experience Builder, the Filter widget could only manage a single data source, which made it difficult to cross-analyze several themes.

In my business, I need to cross-reference five types of data:

  • Buildings
  • Current offers (e.g.: 1000 m² available out of 15,000 m²)
  • Past transactions (e.g.: 5000 m² leased, 15,000 m² sold)
  • Completed assignments (customer history)
  • Property owners

 

If I can enter all this information for a given building, I've won.

In a conventional information system (IS), each theme is a table linked by identifiers (IDs).

JasonBOCQUET_0-1738254953237.png

Here's a simple example of what cleanly processed tables look like in a database. Primary and foreign keys to link everything together.

A simple query on the “Buildings” table would update all the others.

But in Experience Builder version 1.10, it was impossible to apply a filter on multiple data source. Filtering buildings didn't update the other data.

My only solution was to set up selection actions between all the data and explain to my users that they had to manually select the buildings after filtering to update the other elements contained in other widgets (offers & transactions being listed in Table widgets for example) ... a method that wasn't very user-friendly.

A second method, if all our data were geographical (which is not necessarily the case), would have been to make all the Feature Layers linked to the buildings invisible and, via a selection on the map, to make everything “dynamic” via the selection, but the principle remains the same.

Then, version 1.14 introduced group filters, enabling multiple sources to be filtered at the same time. Progress, but with a limit: if I filter buildings by surface area (>5000 m²), how can I apply the same filter to other tables/layers if, for example, the “Missions” table doesn't contain this information?

The solution: add the fields required for filtering to each table. This works, but it forces you to store useless data in tables that weren't designed to hold it, just to get around the system's limitations.

So first tip: be sufficiently friendly with your Data Manager, and he'll accept that you ask him for a column to count strawberries in a table that details the quality of bananas. (in a real world you just joined the strawberries ID on the banana table and use a join function to see all data about these delicious strawberries).

Even if, from an IS point of view, this method is clearly contrary to the creation of a solid model, at least you'll be bringing a good dose of dynamism into your application.

 

Continuing my research, I discovered another cool feature: relationship classes.

In ArcGIS Pro, the “Create Relationship Class” tool enables you to link two sources via a common ID. By exporting the main layer with its relationships to Portal/ArcGIS Online, you can retrieve all linked data directly in a tooltip via Arcade.

 

 

var transactions = FeatureSetByRelationshipName($feature,"SDE.TRANSACTIONS_UTILISATEURS")

 

All the Arcade functions you'll need to call another data source connected to your main Feature Layer need to use the FeatureSetByRelationshipName function to works.

 

JasonBOCQUET_1-1738255644171.png

In my Arcade exemple i called the user's transactions table and write some code below to see the information about these transactions when i clicked on one of my buildings on the map.

 

 

var info = ''
for (var f in transactions){
    info += `<div style='text-align: left;'><span style='font-size: 16px; font-family: Calibri, sans-serif; color: rgb(1, 42, 132);'>
        <b>Date : </b>${iif(f.TRA_TRIMESTRE == '#VALUE!','', f.TRA_TRIMESTRE)} ${DefaultValue(Text(f.TRA_DATE,'Y'), 'Pas de date de transaction recensée')}<br>
        <b>Preneur : </b>${iif(isEmpty(f.TRA_ACQUEREUR), "Pas de preneur recensé", f.TRA_ACQUEREUR)}<br>
        <b>Surface : </b>${iif(IsEmpty(f.TRA_SURFACE),"Pas de surface rencensée", Text(Round(f.TRA_SURFACE,0),'#,###')+" m²")}<br>
        <b>Valeur au m² : </b> ${iif(isempty(f.tra_valeur__m_),'Pas de valeur recensée',Round(f.tra_valeur__m_,0)+" €/m²")}<br>
        
       <br></div>`
}

 

However, this solution has one drawback: the data you're going to retrieve via the relationship class can only be accessed via Arcade (or you may be able to develop widgets to call these classes, in which case you don't need this post). So it's impossible to integrate this data into a Table or Chart widget after the fact, because Experience Builder doesn't handle relationship classes at all (and I hope that one day it will be able to.

However, Arcade is quite magical, and with third-party APIs it's easy to integrate graphs, tables and the like.

JasonBOCQUET_2-1738255818714.png

Here's an example of a graphic integrated into an Arcade tooltip using the Quickchart.io application. The other amazing thing is that graphs can be generated using connected data, thanks to our relationship classes.

 

With this method, we're able to display all the information related to a building without complicating the database or the Data Manager's work. A clean, efficient approach to filtering multiple sources simultaneously!

 

Last tip, very simple : combine the two methods  !

1st Method (Group Filter) :  Filter 25,000 buildings down to a short-list of 25, with access to the mass of information behind thanks to the group filters and our manipulation on the database. Result : your Table widget with all the transactions is updated and shows you the batch of transactions associated of your 25 final buildings selected by filter. You have not to made a manual selection.

2nd Method (Relationship Class) : Click on one of the 25 final buildings selected by filter. At the level of the individual building, you can see precisely each type of information (offers, transactions, etc) concerning THAT specific building. 

 

With these two methods combined, you can offer both massive and individual analysis of your data.

 

I'd like to finish with a few words for the future: a few days ago, I wrote an idea proposal in the “Ideas” section of the ArcGIS Experience Builder board : https://community.esri.com/t5/arcgis-experience-builder-ideas/improve-filter-widget-to-bring-more-dy... (you can support this idea if you like it).
The idea is to propose an ultimate evolution of the Filter widget to bring more dynamism and fluidity to the application, but above all, to its users/developers.
To achieve this, the tool would need to be capable, in the same way as the relationship classes, of detecting, when an entity is selected or filtered, all the other entities, from all the other data sources selected/filtered, which also have this identifier in their data table.

 

I hope this post has provided you with some useful information for your work. A year ago, when I was stuck trying to get dynamism in my application, I was running out of answers and this is the kind of solution I was hoping to find.

 

Gone°

more
6 0 263
JeffreyThompson2
MVP Regular Contributor

A few months ago, I asked for submissions to this blog stating that I was almost out of ideas. Well, this is it. This is my last idea. So, if you've got something, please help out. There is a reason this is the last post. It kind of doesn't belong here. It's really belongs on the JavaScript API Tips and Tricks Board, but that doesn't exist...yet. (Don't look at me. I'm not starting it. But if someone wants to do it, I'll play along.) But as I often say Experience Builder is mostly just a skin over the JavaScript API and this tip can be accomplished either with or without code.

And, this tip is not just for Developer Edition. There is at least some Enterprise users that may also find this useful. For many functions in Experience Builder, you will need to use Feature Layers, but for many reasons you may want to use Group Layers or Map Image Layers. In some versions of Enterprise, there is a bug that prevents you from accessing Feature Layers in various settings of Experience Builder. If you have encountered this issue, you may find it useful to hybridize your layers, shadow loading a Feature Layer to use for these Build Mode setting while showing your end users the Group or Map Image Layer. If you are on a recent version of Enterprise or Online Edition, you can stop reading now. This tip is not for you.

A quick primer for those who may not be familiar with the difference between Feature Layers and Map Image Layers. Feature Layers render client-side and transmit all their data to the end users computer which allows for Experience Builder to do stuff with it. Map Image Layer render server-side. The power of server-side rendering makes Map Image Layers faster in most circumstances. It also allows for more complex symbology and labels. The server-side labeling engine will also dynamically reposition labels as the end user moves around the map which is super useful for big polygons and long polylines. If you're not sure what kind of layer you have, a quick test is to look at the end of the URL. If you see MapServer, it's probably a Map Image Layer. If it ends in a number, it's probably a Feature Layer.

Map Image Layers can also contain sublayers and those sublayers can be Feature Layers. The way Experience Builder is designed to work, you first build a webmap preloaded with all the layers you want to use which you then pull into Experience Builder to use as data sources. And if that's how you load your data, this is your stop. You can get off the bus now. You are already using hybridized layers. But if you're a bad boy who doesn't always play by the rules and you like loading your data at runtime, say through a fancy custom widget, keep reading, the introduction is finally over.

Who's still on the Vangabus? We're going to Hybrid Layer Town!Who's still on the Vangabus? We're going to Hybrid Layer Town!

To the five people still reading this, you're cool. Let's do this.

There are at least four different ways to mix together Map Image Layers and Feature Layers. Each of these is useful in some way.

Map Image Layer With A Hidden Feature Layer - No Code

If you're one of those Enterprise people mentioned earlier, this is the method for you.

  1. In the Web MapViewer, add a Map Image Layer and a Feature Layer for whatever sublayer you need a data function for.
  2. Using the options in the Web Map Viewer, turn off Visibility, Show In Map Legend, and Enable Pop-ups.
  3. To also hide the Feature Layer from the Map Layers List, use the Map Layers Widget, not the Layers Tool, as the Map Layers Widget offers the option to hide layers.

Not everything will function exactly the same using this method as if you only had a single unified layer. The most troubling thing here being if you have say a Filter Widget , the user may see data in some other Widget that should be filtered out. But Actions like Zoom To, should still behave in a reasonable manner and this is kind of the best you can do in Enterprise.

Enterprise people please get off the bus. Save yourself. Only true madness and coding lies ahead.

Feature Layer With Map Image Layer Labeling

In my project, I have a road layer that I know users will almost never turn off. I need the advanced labeling of a Map Image Layer, but I also need to dynamically load and unload a Feature Layer. This is where I use this flavor of hybrid layer.

  1. In the Web MapViewer, add a Map Image Layer containing the layer you want to label.
  2. If there are any other sublayers in the Map Image Layer, remove them.
  3. With the sublayer you will get your labels from, turn off Show In Map Legend and Enable Pop-ups and make sure Enable Labels is turned on.
  4. In the Properties Tab, go to Appearance and find the Transparency slider. Slide that thing all the way to 100% transparent. At this point, your Map Image Layer should only be labels for the specific sublayer you want to label.JeffreyThompson2_0-1735828677797.png

     

  5. In Experience Builder, use the options in the Map Layers Widget to hide this labeling layer.
  6. Dynamically load a Feature Layer of the same data.

So, you could stop there and the only code you would need to write is adding a Feature Layer to a Map Widget. But...That won't work very well. You will get too many labels, as there will be labels from both the Map Image Layer and the Feature Layer and when the user turns the labeling or visibility of the Feature Layer, the labels from the Map Image Layer will still be there. But, we can fix these issues with some code. Let's address the over-labeling problem first.

A Feature Layer contains a boolean labelsVisible property, so when loading the Feature Layer set it to false and done. Nope, that won't work. At least, it won't if you give your end user a Map Layers Widget. This will turn off the double labels when it loads, but the user can just turn them back on again and with what we are going to do a little later, it will throw the Hide Labels Button out of sync. We need to alter the labels themselves. Feature Layers get their labeling info from a property appropriately called labelingInfo, this is an array of objects to support multiple label classes in a single Feature Layer. So, we can set this to an empty array... and it's not that simple either. Experience Builder rather sensibly interprets this empty array as the layer not having any labels and takes away the Hide Labels Button. We need to trick Experience Builder into thinking the Feature Layer is labeled when it actually isn't. We can do that with some code that looks like this...

 

 

featureLayer.labelingInfo = new LabelClass([
  {
    labelExpressionInfo: {
     expression: ' '
   },
   symbol: {
     type: 'text',
     color: 'black',
     font: {
        family: 'Noto Sans',
        size: 7,
        weight: 'normal'
     }
   }
  }
])

 

 

(I'm not certain if the symbol property is strictly necessary. I'm also not sure if the labelExpressionInfo can be '' without the space inbetween. If anyone tests this out let me know how it goes.)

With a empty space in the labelExpressionInfo, Experience Builder says, "Ah yes, it is very important I label this layer with empty spaces." and you get your Hide Label Button.

Now, we need to address how we hide the labels from the Map Image Layer. For this, we turn to my good buddy, the reactiveUtils.

 

 

const imageLayer = jimuMapView.view.map.findLayerById('idOfMapImageLayer')
//Watch for when the Map Image Layer loads and then add reactiveUtils to the Feature Layer
reactiveUtils.watch(() => imageLayer?.loadStatus === 'loaded', () => {
	if (imageLayer) {
		const featureLayer = jimuMapView.view.map.findLayerById('idOfFeatureLayer')
//Watch the labeling and visibility properties of the Feature Layer and hide the Map Image Layer if either are set to false.
		reactiveUtils.watch(() => [featureLayer?.visible, featureLayer?.labelsVisible], ([visible, labels]) => {
			if (visible && labels) {
				imageLayer.visible = true
			} else {
				imageLayer.visible = false
			}
		})
	}
},
{
	initial: true
})

 

 

Because the only thing in the whole Map Image Layer is just the labels of a single sublayer, we can just make it invisible if the Feature Layer is invisible or unlabeled. I've used other variants of this method with multiple sublayers in my Map Image Layer, which makes it slightly more complicated, but I'll leave that for you to work out for yourself. Also, if I was being thorough, I would add a reactiveUtils to monitor the definitionExpression of the Feature Layer and copy it to the sublayer on the Map Image Layer. This would hide the filtered out labels, if the user did any filtering.

Nothing in the Webmap

In this scenario, you want the fancy labeling of a Map Image Layer, but this layer won't be used very often, so you don't want it bogging down your map when it's not in use. Now you need to make a labels-only Map Image Layer using nothing but code. This code should work...

 

imageLayer.listMode = 'hide'
imageLayer.sublayers = [
 {
   //The id here is the sublayer number you wish to bring in as a label. This is the number at the end of the Feature Layer URL.
   id: 6,
   legendEnabled: false,
   listMode: 'hide',
   opacity: 0
 }
]

 

If you use the sublayers property of a Map Image Layer, any sublayer not listed by id will be excluded, so you can use that to filter out the unwanted sublayers while altering the properties of the one you want to keep. Set up your Feature Layer and reactiveUtils as above and you're good to go.

Ginger Rogers Style: A Map Image Layer, But Works Like A Feature Layer

Now, we have come to the true dark arts. Use these powers carefully, as you will be taxing both your server and the user's machine. There are also lag issues where the "feature" won't respond properly because the Map Image Layer has loaded, but the Feature Layer is still processing. This setup will also break the legend in the Map Layers Widget, but not the legend in the Legend Widget.

So, why would you want to do this to yourself... Map Image Layers support more complex symbology than Feature Layers and you may find complicated geometries draw significantly faster in Map Image form.

We will build an arrangement where the Map Image Layer is displayed unaltered in the map, but the buttons in the Map Layers List are actually from the Feature Layers. Yes, you heard that s correctly. This time I'm going to assume you are adding all the sublayers in the Map Image Layer as Feature Layers. We don't really need to alter the Map Image Layer this time, but we should give it listMode = 'hide'.

So, how do we go about making an invisible Feature Layer? You might think we can just set the layer's visible property to false, but this will disable many map functions, like pop-ups. However, you can alter the layer's renderer, so that it renders invisibly while still being functional. Here's what that looks like for a polygon layer...

featureLayer.renderer: {
    type: 'simple',
    symbol: {
        type: 'simple-fill',
        color: 'rgba(0,0,0,0)',
        outline: null
    }
}

We should also set the legendDisabled property to true and use the labelingInfo trick from above. And with that, you have a Feature Layer that has no visible presence, but will still trigger a pop-up or be found with a Zoom To.

Next, we make the buttons work by setting up some reactiveUtils.

const imageLayer = jimuMapView.view.map.findLayerById('idOfImageLayer')
reactiveUtils.watch(() => imageLayer?.loadStatus === 'loaded', () => {
	if (imageLayer) {
		const sublayers = imageLayer.allSublayers
		sublayers.forEach(sublayer => {
			const idNum = sublayer.id
			const featureLayer = jimuMapView.view.map.findLayerById(`idBaseOn${idNum}`)
			reactiveUtils.watch(() => featureLayer.visible, (visible => {
				if (visible) {
					sublayer.visible = true
				} else {
					sublayer.visible = false
				}
			}))
			reactiveUtils.watch(() => featureLayer.labelsVisible, (labels => {
				if (labels) {
					sublayer.labelsVisible = true
				} else {
					sublayer.labelsVisible = false
				}
			}))
			reactiveUtils.watch(() => featureLayer.opacity, (opacity => {
				sublayer.opacity = opacity
			}))
		})
	}
},
{
	initial: true
})

This should loop through the sublayers in a Map Image Layer and create reactiveUtils monitoring the visibility, opacity and labeling of each of them.

Backwards and in high heelsBackwards and in high heels

Hey look, you made it to the end. Good for you. I hope some of this is actually useful to you.

more
4 4 334
JeffreyThompson2
MVP Regular Contributor

I have been asked on multiple occasions for help with registering a custom widget in ArcGIS Enterprise. My answer has always been, "I don't know. My Enterprise is still on 10.9.1." Well, that is changing. We are upgrading to Enterprise 11.3 and now that our testing portal has crossed the threshold into that magic 11.X world that allows for hosting custom widgets, I have hosted some widgets. So, I'm going to walk you through the process and what I learned along the way.

The first thing I did was pull up the official documentation, which was rather good in this case. Ordinarily, I'd drop a link here, but the document is imbedded within Enterprise itself on an internal server. I found it by opening Experience Builder, scrolling down the Insert Widget Pane and hitting the question mark next to Custom. Also, note that the box with the lines on it will take you to the Item Page on your Portal, so if you want to make your own documentation for your custom widget, that would be the way to find it. Nice touch, ESRI.

JeffreyThompson2_0-1732216246603.png

So we have our recipe, what's on the ingredient list?

  • ArcGIS Enterprise 11.0 or higher
  • Administrator privileges on your ArcGIS Enterprise
  • A web server
  • A custom widget
  • Experience Builder Developer Edition
  • Love (I mean it's not specifically needed for this procedure, but everyone needs love, even if they are too big and brave to admit it. If you are feeling low on your love supply lately, don't be afraid to reach out to someone. More people genuinely care about you than you even know.)

Step One: Prepare Your Server

I'm copying in steps 1-4 on the official guide and chances are, you won't have to do them.

1. Enable anonymous access to the virtual directory that is hosting your widgets.

The hosting location must be anonymously accessible.

 

2. Enable HTTPS.

Enable HTTPS access in your web server to avoid creating mixed content. Experience Builder does not allow mixed active content caused by loading HTTP under an HTTPS connection. In addition, your server should have a valid SSL certificate issued by a certificate authority to establish the HTTPS connection.

 

3. Enable Cross-Origin Resource Sharing (CORS).

Experience Builder runs under your portal domain, which may be different from the domain of the web server hosting your custom widget. You need to enable CORS in the web server so that access from your portal domain is allowed.

 

4. Add a JSON handler to your web server.

Each widget consists of a JSON manifest file that describes widget properties. Some web servers do not recognize the JSON file extension by default. In such cases, you need to add it to your server as a new MIME type at the application level or a higher level. The MIME type should have .json as the file extension and application/json as the MIME type.

At this point, I would like to remind everyone, I am not an Administrator. I'm also way dumber than I appear. I'm just a monkey who's really good at knowing which buttons give me bananas and which ones give me electric shocks. I don't know how to get your server set up if it's not done already. But chances are you, or whoever set up your server, already did all of these things, so you can probably start at the next step and if it doesn't work you will need to change something on your server.

Step Two: Compile Your Widget

This is the step in the process that is probably where most people slip up. Here's a truth that might be hard to swallow, that code you wrote that you worked so hard on, will never actually be used by your final application. The code in the your-extensions/widgets folder runs through a compiler converting it from TypeScript and React into pure JavaScript. It is also minified. This is the actual code your application runs and this is the code you will need to host your widget. So, even if you are just downloading a completed widget from the Custom Widgets Group, you will still need to put it through Developer Edition first.

The other way compiling can go wrong is a version mismatch. Each version of ArcGIS Enterprise has a corresponding version of Developer Edition. For ArcGIS Enterprise 11.3, the corresponding Developer Edition version is 1.14. Experience Builder can run widgets written in earlier versions, but it can't handle widgets from a newer version. And this limitation also matters for what version it is compiled in. So if you have a widget that was written in 1.12 but compiled in 1.15, it will almost certainly fail in Enterprise 11.3, but if you use 1.14 as a compiler, it should work.

JeffreyThompson2_1-1732221667439.png

Ok, that's what not to do. What to do? There are two ways to get the compiled version. If you've already built a project and hit Publish since putting the widget in your-extensions. It should already be compiled. (Not sure if you need to use the widget in your project, but I don't think so.) If your widget isn't already waiting for you in the client/dist-prod/widgets folder, stop your Client server and run npm run build:prod on that directory. 

Step Three: Deploy Your Widget

Go to ...fileStructure/client/dist-prod/widgets in Windows Explorer and copy the folder containing your widget. Paste that folder onto your web server. Get the full URL to the manifest.json inside that folder. Open up your Enterprise Portal and go to the Content Tab. Click on Add Item and choose An Application, then Experience Builder Widget. Here is where you should enter that URL to the manifest.json. Finish completing the Add Item Wizard. You don't need me to tell you how to do that, do you?

Now, you'll want to Share it with your co-workers. And I encountered something odd on this step. The first time, I hit the big blue Share Button at the top of the Item Page. For some reason, this duplicated my widget both within My Content and Experience Builder. One version was Private and the other was shared with the Organization. On my other widget uploads, I used the Share Edit Button further down the page and didn't get a duplicate. So use the little button, not the big button.

JeffreyThompson2_0-1732225208526.png

Open up Experience Builder and say hi to your new widget, ready for your whole organization to enjoy.

more
5 0 563
Laura
by MVP Regular Contributor
MVP Regular Contributor

In Experience Builder (ExB), the Dynamic Content feature within the text widget allows you to create data-driven, interactive content. While it's a powerful tool, it doesn’t yet offer the same ease and flexibility that ArcGIS Dashboards provides—especially for features like dropdown filters.

As someone who values visual impact and quick, insightful data for users, I’ve integrated indicators into many of my applications. Dashboards’ indicators are far more refined and user-friendly compared to ExB’s options. Esri has suggested that the dynamic content in ExB’s text widget could help replicate the functionality of Dashboards indicators. However, after experimenting, I realized the gap is much larger than I expected. A key limitation is the inability to easily filter Dynamic Content—for example, to only show incidents in “City A” or, in my case, monitor a specific tree species in my city.

To address this limitation, I found a simple workaround: build the indicators in Dashboards and embed them into Experience Builder. Below, I’ll share my process using a real-world example from my city’s Tree Viewer.

Our city is actively addressing challenges with Ash trees and wanted an easy way to track the number of Ash trees left in our inventory. My dataset has a field for species, containing hundreds of different tree types. When I tried to create an indicator in ExB to filter for Ash trees, I realized I couldn’t do it directly. Here's how I worked around this limitation.


Step 1: Create Your Indicator in Dashboards

  1. Open ArcGIS Dashboards and create a new indicator.
  2. Add a filter to isolate the data you want to track. In my case, I filtered for planted trees and every type of Ash tree in our inventory.
  3. Configure the indicator to show the count of Ash trees only.
    • Customize the appearance to highlight the key number in an impactful way.

The result? A perfect indicator showing just the data I needed. This was something I couldn’t achieve natively in ExB!

Here’s what my Dashboards indicator looked like:

Laura_4-1732050217838.png

 


Step 2: Embed Your Dashboards Indicator into Experience Builder

  1. Open your existing Experience Builder project (or create a new one).
  2. Add an Embed Widget to your layout.
  3. Use the URL option in the widget settings and paste the URL of the Dashboard containing your indicator.

Laura_5-1732050240549.png

 


Step 3: Check Sharing Settings

Before you publish your app, ensure your Dashboard’s sharing level matches the intended audience of your ExB app. For example:

  • If your ExB app is public, make sure the Dashboard is shared publicly.
  • If it’s for internal use, ensure both the app and the Dashboard are shared within your organization.

The Result

Now, my Ash tree indicator seamlessly appears in my Tree Viewer application! Users can see the current count of Ash trees at a glance, with the refined design and filtering functionality of Dashboards embedded directly into Experience Builder.

Laura_6-1732050325673.png

 

 

 

more
3 7 942
JeffreyThompson2
MVP Regular Contributor

My first real, released to the world Experience Builder project was called Park Finder. It was designed for the citizens of Arlington to go in click some filters and find out what parks meet their criteria. Let me give you a quick tour and explain a little about how I made it.

JeffreyThompson2_0-1731692483226.png

In the lower right of the map, is a custom widget for switching between two basemaps made by importing the Basemap Toggle Widget from the Javascript API. At the time I was working on this project, the Experience Builder Basemap Gallery Widget did not exist and the Basemap Tool had too many choices. Plus, there is a simple elegance to how the Basemap Toggle works. Could I have used multiple maps within my Map Widget to achieve the same effect? Yeah, I guess so, but it was easier to just make my own Widget than to configure multiple maps and all the Actions to make it all work. All in all, I'd rate this custom widget as technically reproducible in Online, but it would be nice if it was a standard widget.

Now, let's look at the right side of the screen. Up at the top, there's a search bar, but it's not actually a Search Widget. It's a List Widget, but I've used CSS to hide everything but the search bar. I don't entirely remember why I did it this way, but I think it was mostly about that annoying Results Panel that wouldn't go away after a search. As of a few days ago, that Results Panel is now optional. So, I'll mark that design as functionally replicated in ArcGIS Online.

Moving down the right-hand column, we get to the filters. The first set of filters are tied together with an OR statement and are using geographic labels in the data to filter by area. Down below, we have filters tied together with an AND statement that allow the users to filter by the amenities the parks have. So of course, I needed to use a custom widget to make such complicated filters, right? No, those are just OOTB Filter Widgets. Ok, not quite. I did use some CSS to make the buttons closer together and change the highlighting color when they are selected. But, functionally they are just two Filter Widgets.

Shortly before we went live with this application, someone in the Parks Department asked if the filters could filter themselves as the user made their choices. At the time, the answer was no. And it was deemed too much work for me to make my own filter widget and re-build the entire application around it, so that idea didn't happen. But now, yes, filters can filter themselves. So all-in-all, I wish the Filter Widget had some more design options, but it's at least advanced functionally.

Now, let's look over at the left side of the screen. That List Widget is not a List Widget. It is a built from scratch custom job. Mostly so I could make those little icons that show what amenities each park has. Until we get an option to put a List Widget inside another List Widget, an idea that is never going to happen because it would be an absolute nightmare to code with a billion possible unintended consequences, that isn't going to be possible in ArcGIS Online.

Across the top of the custom list are a set of buttons that sort the list in several different ways. And finally, after all that introduction, we are finally getting to what this post is really about. While I was working on this application, the first version of Near Me was released. The release of this application was actually delayed so I could incorporate Near Me into the design. And then, I didn't. It just didn't work in this design. Instead, I built my own geographic sort, an incredibly complicated process that I never fully got all the bugs out of.

I've written about what I really wanted out of Near Me before and how with later updates, it became possible. If you haven't read that post before, I'm going to need you to do it now. The rest of this post is going to start where that one left off and won't make much since without that context. Go on...I'll be here when you get back.

skull-fall.gif

Ok, you're back. So at the end, I said:

The big downside is that I can't find a way to make my List Widget a list of all parks in absence of a Near Me search.

Well, there is sort of a way around that now. We can put our Near Me Output List into a Sidebar and have it open when the Search Widget is used. The Sidebar would physically cover a second List Widget that contains all the parks. This second List Widget would have been the one displayed when the app opens. The net effect is that the app appears to have one List that handles both all parks and nearby parks. Hey, why did I use the past conditional grammatical tense back there? Did it not work? No, it works. It's a viable build, but it's not exactly the one I stuck with. See after making the one List over the other, I couldn't stop there. I had to test out the filtering filters which exposed a flaw in that design. If the user changes the filters after Near Me does its thing, it won't trigger Near Me again and the List will not match the filtering criteria. So in my final proof-of-concept application, I made it so my Near Me Output List covered the Filter Widgets instead and I have an always displayed "All Parks" (But Not Really All Parks Because Its Affected By Filters) List Widget and a "Closest Parks" List Widget that only shows up when Near Me is triggered. So if you want that single List feel, it will be similar to, but not exactly what I'm about to describe building. And now, after all that secondary introduction, we can get to what you really want, the how to part...

I've already put my Output List into a Sidebar. We'll call this the Output Sidebar. I've also previously wired up a Near Me Widget in an unopenable Sidebar (We'll call this the Near Me Sidebar.) and set it up so Near Me is triggered by the Search Widget.

We'll start making our changes in the Search Widget. In the Action Tab, I have added a Open Sidebar Action to my existing Record Selection Changes Action to open the Output Sidebar. I also deleted the Zoom To Action I previously configured. Apparently, in the last update, a default zoom action was added to Near Me. Having a zoom action on the Search Widget and Near Me was causing a nauseating bouncing effect as the Search Widget first zoomed in then Near Me zoomed back out a bit. In the Content Panel, I scrolled down and opened up the Search Result options to use the new option to turn off the Result Panel. I will be putting the Search Widget under the Output Sidebar later and turning off the Result Panel prevents a visual glitch where the Result Panel clips through the Sidebar.

JeffreyThompson2_0-1731947732966.png

In the Map Widget, I went to the Style Tab and added 400px spacing from the left and right side of the screen. My map is now centered with space on each side for more stuff. Into the empty area on the right, I dragged a Column Widget. I used the Full Height option and manually set the Width to 400px and gave it a Background color to match my Theme. Then, I hit the Snap To Right button. Next, I used the Duplicate button to copy my Column and used Snap To Left on the new Column. In the right Column, I added a Text Widget to make a heading and a new List Widget to display a list of all the parks.

In the left Column, I assemble a delicious parfait with Text Widgets to make headings, my previously configured Search Widget and two Filter Widgets.shrek-donkey.gif 

I set up some filters using our filtering filters trick. And at this point, I must ask you not to judge my "final" application too harshly. This is a proof-of-concept, not a real application. There are design choices I would not make in a real application. I haven't even looked at anything but the Desktop view. And most glaringly, my data isn't really configured to take advantage of the filtering filters properly.

Almost done, I promise. Go to the Output Sidebar and set the Size to 400px, Overlay on, Resizable off, Default State Collapsed and Collapse Button off. I also gave the Left Panel a Fill color to match our Theme. This prevents the Output Sidebar from being see-through and showing the filters below. With these options set, there will be no way for the user to interact with the filters while looking at the Output List, preventing the inaccurate data issue discussed above.

JeffreyThompson2_0-1731950494870.png

Ok, so the user has set their filters and typed their address in the search bar. The nearby parks have been found by Near Me and sent to the Output Sidebar that is no preventing them from changing any more filters and now what? They're stuck. There's nothing more they can do with this application. So, let's give them a Button to close the Output Sidebar and get back to the controls.

Temporarily drag the Output List out of the Left Panel of the Sidebar Widget and drop a Column Widget in its place. Make the Column Widget Full Size. Add a Button Widget and another Text Widget for a heading into the new empty Column and drag the List Widget back inside. In the Button Widget, go to the Action Tab and Add A Trigger > Button Click > Output Sidebar > Toggle Sidebar. You'll also want to give your Button a meaningful Text value.

All this is to say, Experience Builder has come a long way in the last 18 months. Maybe it's not easy or intuitive, but there is a viable no-code path to re-creating an application that took some serious coding not that long ago. So, has ArcGIS Online caught up to Developer Edition? No, not really and it never really will, but the fact that it's a question is seriously impressive.

more
0 1 346
JeffreyThompson2
MVP Regular Contributor

Back in June, when ArcGIS Online was last updated, I went through the update notes and wrote about what I thought were the most impactful changes to Experience Builder and what you might be able to do with them. Well, you guys seemed to like that, so I guess this is a regular feature now. As before, I will not try to document every change. If you want that, the official What's New Page is here. And I have done very little testing, so don't blame me if something doesn't work the way I say it does.

Honestly, I feel a bit underwhelmed by this update, which is weird because this update contains five of the most commonly requested updates on the Ideas board (and maybe a small something from one of the Ideas I posted): text support in the Draw Widget, Express Mode for making app creation simpler, users can build their own SQL queries in the Filter Widget, starting an Edit session from a popup, and de-selecting a feature with Zoom To on can un-zoom. So why am I unimpressed? I don't know. Maybe, it's because Batch Editing got pushed back to the next update. Or maybe, I'm just bitter that ESRI is going to make Experience Builder too easy and put me out of business? I don't get paid for this. That should be a good thing. Anyway, if you aren't seeing your chance at international fame slipping away in front of your eyes, you should be happy about this update.

Action Updates

  • Edit Action - This new action allows for starting an edit session from another Widget, including popups in the Map Widget. My understanding of this update is that if you place an Edit Widget in a Widget Controller, editing is turned on and off automatically when the Edit Widget is opened or closed. Last week, @ZachBodenner showed us how to use multiple Edit Widgets to prevent accidental edits, now we can use Widget Controllers to take that idea a step further and make our data even safer from whoopsies.
  • View In Table Action - A Table Widget can now target itself, meaning you can select stuff in one Sheet and send your selection to a separate Sheet.
  • Some Message Actions now prompt you to select trigger data. - Honestly, I'm still struggling figuring out what this means and how to use it. But I think, it means you can choose for some things to not have a certain Action.
  • Show On Map Action - The graphics generated now appear the the Layers Tool and Map Layers Widget, where the user can find them to hide them more easily than that tiny trash can. The tiny trash can still exists as well, but you know maybe it shouldn't, maybe we could design this better, ESRI? The Map Widget also has a new Set As Operational Layers option that will turn them into real boys Feature Layers.
  • Zoom To and Pan To Actions - Un-selecting a feature can optionally return the Map Widget to its default extent. Use this with caution: I tried it for a bit and I did not like the way it felt as a user.
  • Widgets in the Pending List cannot be targeted for Message Actions. - Should make setting up an application for multiple screen sizes less confusing, but I worry about unexpected behavior if the screen-size changes.

Data Source Updates

  • Support for Subtype Group Layers.
  • In the last update, the Feature Info Widget got an upgrade that automatically added all the layers from a Map Widget at once, this option is now available in every Widget that would benefit from it.

Express Mode

Instant Apps for Experience Builder. Templates designed to get you from start to finish much faster and easier with a simplified Builder Mode. You can start in Express Mode and then go to the full-featured version if Express Mode isn't enough. Official introduction blog post here.

Style Settings

Borders for the sides of Widgets can be set separately. Want a line between Widgets in a Column? Throw a top and bottom border. No need to mess with a Divider Widget.

URL Parameters

Use URL parameters to select some features and zoom to them. You can select features by id, geometry or with a SQL where clause.

Widget Updates

  • Accordion Widget - It's a new. It allows you to stack multiple Widgets into a menu that the user can open up when they need it. Much like musical accordions, design accordions are often hated. Design experts caution against using Accordions as they are not good for accessibility and users frequently do not notice/understand they can be expanded. The general rule of thumb is to never hide vital information inside an Accordion. With that said data-heavy/GIS applications, often need to break general principles of web design to be useful. Use Accordions with caution.
  • Basemap Gallery Widget - Add your own basemap by URL.
  • Bookmark Widget - More options for how your Bookmarks appear with a reportedly more user-friendly Builder interface.
  • Business Analyst Widget - More options for calculating travel times.
  • Coordinates Widget - I can't quite wrap my head around what this sentence means, but I pretty sure its important.You can use the new Use transform forward setting to specify whether you want to perform a datum transformation in the forward or reverse direction.
  • Chart Widget - So many updates it needs a submenu. If only I had an Accordion...
  1. Use the layer symbology to color a chart.
  2. Bar and column charts support time binning.
  3. Line charts can be continuous or discrete.
  4. You can turn off axis labels.
  5. You can hide empty data.
  6. Auto generated titles that can also be changed manually.
  7. Breaking Change Alert!

Additionally, the Chart widget no longer supports using ID fields for statistics other than count. If you have an existing chart that does this, the chart may fail and you should reconfigure the widget.

  • Draw Widget - Text!!!!!!!!!!!!!!! With many font choices, the OOTB Draw Widget is now officially a better Write On A Map Widget than my uninvited collaboration with @RobertScheitlin__GISP. (Although, we still have the official widget beat with freehand drawing and post-drawing editing support.) Drawn graphics can also appear in the Map Layers Widget or Tool.
  • Edit Widget - Enable Tooltips can be turned on by default. (Could help fill the gap left by the WebAppBuilder Traverse Widget?) Show and edit vertices. (Is that really a new feature? We didn't already have that?)  Hide Edit/Create Features panels to the user if not using them.
  • Filter Widget - Users can take control of their own destiny and make their own SQL queries.
  • Map Widget - In addition to other stuff mentioned in other places, you can also choose where to dock docked popups.
  • Map Layers Widget - Popups can be toggled on/off on a layer by layer basis. Users can turn off popups for that one layer that super annoying and not very helpful, but covers your entire map.
  • Near Me Widget - View Related Records in Near Me. Find intersecting polygons. Find features in invisible layers. Cancel slow searches. More Data Action support. Sounds like Experience Builder's most hackable Widget just got even more hackable.
  • Query Widget - Query spatially with stuff added from the Add Data Widget.
  • Search Widget - Should be easier to set up for new Experience Builder designers, but I paradoxically if you know what you want and what your doing, it seems to be a clunkier building process. Every step through setting up a Search Widget answer I have ever written is now wrong. The Result Panel that covers up half your screen and doesn't hide itself after a search is now optional.
  • Text Widget - Additional formatting options.
  • Timeline Widget - Increased precision and an option to start with filtering on or off.
  • Widget Controller Widget - There are new options for when there are too many Widgets for your Widget Controller Widget to control all your Widgets. They can be scrolled through with arrows or have the overflow compacted down to a single button. Making a Widget Controller one button wide and using this second option could be a valid design choice. The Manage Widgets Panel allows you to make an Accordion within a Widget Controller. It's not mentioned in the What's New document, but the took my advice and added box shadow options to the buttons. I would have preferred that they listened to the border and bigger buttons parts of that suggestion instead. You can also make the icon colors different for every Widget in the Widget Controller. Don't do that. But you can do that.

There it is. My most highlights from the November 2024 ArcGIS Online Experience Builder Update. Have a great day to everybody, except whoever spilled their coffee on the ArcGIS Online servers this morning.

more
7 3 532
ZachBodenner
MVP Regular Contributor

This little trick will help tame some of the complicating features of the new Edit tool and create a safe location for editing small numbers of attributes.

Read more...

more
6 1 262
JeffreyThompson2
MVP Regular Contributor

I want to make a tool where users can select one or more counties and easily see the calculated total area. So I added a Text Widget, turned on Connect To Data, found my Counties layer, and switched to the Selected Features View.

JeffreyThompson2_0-1730380042086.png

With the Text Widget selected, I clicked the stacked circles to make some Dynamic Content. In the Statistics Tab, I select the Sum Operator and the Field containing my area. Every polygon is required to have one, and by default, this usually looks like SHAPE.AREA().

JeffreyThompson2_1-1730380740230.png

I hit Insert and it works. The user can use the Select Widget or the Select Map Tool to pick some counties and instantly know their area. But, when they don't have anything selected, it looks like this... 

JeffreyThompson2_2-1730380778726.png

Bad, ugly. We can do better.

Instead of using the Statistics Tab, go to the Expression Tab. And here's the trick, that unlabeled text area above the unlabeled text area where you write your Expression, that's what gets displayed when nothing is selected. So I make my Expression like this...

JeffreyThompson2_3-1730381295276.png

And here's how it looks when nothing is selected...

JeffreyThompson2_4-1730381380491.png

more
3 0 246
JeffreyThompson2
MVP Regular Contributor

I'm just going to put a link here to this epic comment by @fpolia21. Take an Experience Builder project from Developer Edition and register it as an Online or Enterprise Item. Or download it from your Online/Enterprise and edit it in Developer Edition. 

https://community.esri.com/t5/arcgis-experience-builder-questions/deploy-exb-developer-edition-to-po...

more
1 0 295
167 Subscribers