Identify Widget from Mouse Click or Search Widget

2542
8
02-13-2024 07:34 AM

Identify Widget from Mouse Click or Search Widget

This widget is designed to serve a similar function to the @RobertScheitlin__GISP Feature Panel widget and was heavily inspired by it. Like the Feature Panel widget, it is designed to replace the popup and work in an auto-opening and closing sidebar. It differs in four upgrades and one downgrade.

Upgrades

  • It is written in function based React. (This won't matter to end users, but it should make further modifications easier on you.)
  • The results are displayed in tabbed form by layer making finding what you are looking for easier.
  • There is an off button. (Have you ever tried using the Feature Panel Widget with the Draw or Measure Widgets? It's impossible. That's why end users can turn this widget on and off at will.)
  • It is designed to get data from a lightly modified Search Widget. (Also included in the zip file. Yes, this is a 2 for 1 custom widgets deal.)
JeffreyThompson2_1-1707838430718.png

The Downgrade

It does not auto-detect what sidebar it is placed into. Why? Have you looked at @RobertScheitlin__GISP's code? More than half of it is dedicated to pulling off this really neat trick and I am way too lazy to try and translate all of it into functional React. (Also, his code doesn't quite work. At least, if you are using a layout with multiple sidebars.)

You will need to find the id number of your sidebar widget for the auto-sidebar to work. How?

  1. The widgets in Experience Builder are sequentially numbered in the order they are added, so if you add your Sidebar Widget immediately before adding the Identify Widget, you can subtract one from the widget_id shown in the Identify Settings Panel.
  2. Open the config.json file in /server/public/apps/your-application-number/resources/config. Use ctl+F to find the word "Sidebar" and use that widget_id.

How Identify works

The Identify Widget is split into three levels. The top level is dedicated to creating/destroying event listeners and sending new clicks down to the second level. In the second level, the screen point is sent to popup.fetchFeatures() (that calls hitTest() in the background) and gets the popupTemplate from all the featureLayers. Each identified feature is given a Feature Widget from the Javascript API that is packaged into an array and sent down the the third level. The second level is also responsible for adding and removing highlights from the map. The third level uses dangerouslySetInnerHTML to make the tabbed results display. (Note: dangerouslySetInnerHTML is no more dangerous than the standard .innerHTML() method. The React Devs named their version this way to remind developers that anything sent to the .innerHTML() method will be run as code, so it must come from a trusted source.)

How Search Works

The included Search Widget is the standard ESRI Search Widget with three lines of code added to the result-list.tsx onSelectRecord() function. One of which is just an aesthetic UI improvement to close the search result panel after the user makes a choice.

 

 

//Extracts geometry from data source
const geometry = records[0].feature.geometry
//Closes search result panel
onShowResultButtonclick()
//Sends geometry to identify widget
MutableStoreManager.getInstance().updateStateValue(`widget_${props.config.identifyWidgetId}`, 'newSearch', geometry)

 

 

It extracts the geometry from the data source and sends it to the Identify Widget where it is converted to a screen point and triggers the rest of the identify functionality. This Search Widget was designed and tested using a Locator source. It should also work with a point type layer source. It will not function properly with non-geographic data or other types of geometries.

You will need to enter the Identify widget_id into the Search Settings Panel. It can be easily seen in the Identify Settings Panel. Because Identify relies on hitTest(), you must also use the Zoom To Action to ensure that the searched location is visible on the screen. You may need to use a custom zoom level as well. If you do not zoom into a features visibility range, the feature will not be displayed and won't be found by hitTest(). And hitTest() is, by design, not super precise and will find all features in a six pixel buffer around the actual screen point, so you may need to zoom closer than the default to prevent finding more features than desired.

The Room For Improvement

At this time, I have no intention of doing additional work on these widgets, but should anyone else want to take a take a crack at improving them here are the rough spots.

  • Personally, I have never been very good at working with Promises, so I needed to use setTimeout() to await the processing of the results. (The default for this timeout is 2 seconds and can be adjusted in the Identify Settings Panel. Setting this timeout too low will result in missing data and setting it too high will cause the user to wait unnecessarily. You will need to adjust this number to account for the speed of your server and network.) If a better programmer can figure out how to make this widget properly await the resolution of all the promises, I would appreciate it.
  • Identify works best if it is placed in a sidebar partly for the aesthetic of keeping the map clean and visible, but also because between the users click and the final processing of the results, the old results will be displayed with no visual indicator to the user that the widget is working. The sidebar hides this problem by closing when a click/search is first passed to Identify and re-opening when the new results are ready. (I attempted to use the Loading Widget from jimu-ui, but could not find a way to make Loading load and unload correctly in all circumstances.)
  • An on-map loading indicator would also be nice.
  • There may be some ways to make the widget more efficient. There are some calls to the clearHighlights() function that were needed at some point in development, but I'm not sure are needed in the final version. I'm also not sure the identifyDiv does anything in the final version other than displaying a line of text before the first search.
Attachments
Comments
JasonBatory
Emerging Contributor

This is great, thanks for sharing.

Can you please clarify, the widget entries in my config.json look like this:

"widget_13": {
      "id": "widget_13",
      "uri": "widgets/layout/sidebar/",
      "config": {...

 but your widget_id setting value is a number, so would I just use 13 in this case? Or do I need to change something so my widgets get numeric IDs?

JeffreyThompson2
MVP Frequent Contributor

@JasonBatory Just use the number.

wliu
by
Emerging Contributor

Hi @JeffreyThompson2 Thanks very much for this useful custom widget. I'm playing around with the code and testing on an application. I am not sure if I did something wrong but it looks like the custom search widget is not communicating with the identify widget. I did quite a lot searching in Esri's documentation. However I wasn't able to figure out a solution myself. I wonder if you could kindly give me any advice.

JeffreyThompson2
MVP Frequent Contributor

@wliu This Widget broke at Experience Builder 1.13. It was rewritten in 1.14, if you are using 1.14 or later you should be using this version of the Widget. https://community.esri.com/t5/experience-builder-custom-widgets/identify-for-experience-builder-1-14...

With either version, you will need to enter the id number of the Identify Widget into the Settings Panel on the Search Widget to make them work together.

wliu
by
Emerging Contributor

@JeffreyThompson2 Thanks! I found your updated code right after I post this question. I'm working on it and trying to adapt the code to my own need. I really appreciate your help 🙂

ZhujingXia
Frequent Contributor

@wliu I tried the identify widget in 1.17 version of the EB, It only work for one layer (the top first layer), it would not work with other layers, no error message, just show the message 'No result found'.

Any one know how to fix this issue? 

wliu
by
Emerging Contributor

Hi @ZhujingXia. Have you tried using the newer version of this widget in this post? That one works for me. I only did some subtle changes to adjust it towards my own needs.

ZhujingXia
Frequent Contributor

Wliu,

 

I did download the newer version of the widget. the identify is only work for the top first layer in the web map, not work for other layers.

What kind of adjust you did for your own needs?

Version history
Last update:
‎02-13-2024 07:43 AM
Updated by:
Contributors