Combining Identify and Add Data widgets?

796
2
Jump to solution
12-13-2019 12:55 PM
EricRuberson1
New Contributor III

What I'm working on is modifying Robert's Identify Widget and adding the functionality of esri's Add Data widget. The purpose is to be able to upload a shapefile/kml/etc and then pass it on to be queried and generate a table and all that using the Identify Widget.  We already have the Identify Widget running and I've added a button to that which exports it's results (shamelessly copies it's outputted list and reconfigures it) to a new window with some added functionality, but I'm working on adding the shapefile upload abilities.

I've added a listener to the Identify widget to listen for any layer add events and then run a new function which grabs the geometry from the added layer to pass into the rest of the Identify widget.

Changes: 

added to _bindEvents

        this.own(on(this.map,'layer-add',lang.hitch(this,function(event){
          console.log("*** layer-add event triggered *** ::: ");
          console.log(event);

          if(event.layer.graphics.length > 0){ //doesn't run on empty layers
          this._onAddedLayer(event);
          }
        })));

New function (started based on Identify's _onDrawEnd):

    _onAddedLayer: function(addedLayer){
        let layer = addedLayer.layer;
 
        //need: to extract the layers geometry

        var layerGeoms =[];
        for (var i = 0; i < layer.graphics.length; i++) {
          // Collect the line features from the uploaded layer
          var thisGeoms = layer.graphics[i].geometry;
          this.graphicsLayer.add(layer.graphics[i]);
          layerGeoms.push(thisGeoms);
          console.log(layerGeoms);
        };
        var geometryUnion = geometryEngine.union(layerGeoms);
      
        //depending on integration method, html lines will need to be expanded or removed
        html.setStyle(this.btnClear, 'display', 'block');
        html.setStyle(this.btnExportResults, 'display', 'block');

        this.identifyFeatures(geometryUnion); //runs identifyFeatures, passing it the geometry provided by the drawing tools
      },‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

So the problem is well, this a) doesnt succesfully run identifyFeatures because b) it's a sloppy hack that is outside of the scope of it's launching widget. All it really was meant to do was prove that I could get the geometry from the loaded layer and flatten a shapefile with multiple features into one geometry (which is what gometryUnion does). 

I have to open the Identify widget first, to activate the listener, but then open the Add Data widget to add a shapefile to the map. Then I can go back to the Identify widget and... I havent made the rest of it work and I'm not sure how to proceed.

So I guess my question is this: Should I try to integrate the Add Data source code into the Identify widget and then add a button after the Identify Widget's Draw Box for running the Add Data button? Or do I investigate turning the Identify Widget into a controller widget and then adding the Add Data widget button after the Identify Widget's Draw Box? Or is there some better alternative?

I've successfully slipped a button into the Identify Widget's Results tab, so I'm pretty positive that adding a button after it's Draw Box is feasible, I just dont really know how to go about integrating the two widgets, or what to look for in doing so.

0 Kudos
1 Solution

Accepted Solutions
EricRuberson1
New Contributor III

Resolved:

I turned the Identify Widget into a controller widget and embedded the launching icon for the Add Data widget within the Identify Widget's first tab container.

My key takeaways or problems solved:

1)

<div class="container-section" data-dojo-attach-point="containerNode"></div>

That determines where the widgets being controlled by the parent widget wind up. (This goes into the widget.html of your controller widget.)

Note that it only attached the button that launches the widget. Our Add Data widget still ended up running all it's panel functions into the panel associated with my table of contents/layer list widget. At some point I may have to figure out how to run it in it's own new popup panel, but that is an aside from this post.

2) There's a nearly undocumented ability to choose which widgets are being controlled by which Controller widget. It's part of the functionality of jimu/PoolControllerMixin

Assume you want multiple controller widgets in your app.

All apps being controlled by the widgets (aka the children apps) need to be listed in the root app's config.json file in the widget pool. That is, I don't believe you need to add a widget pool to your parent widgets.

You need to add:  '   "IsController": true, ' to the manifest.json properties for your controller widgets if its not already there.

you Also need to add: '  "controlledWidgets": ["_50"]  ' to your manifest.json properties section. Inside the array you need a list of strings that have the id for your widget. In this case my Add Data widget had the id of _50. I also had a Header Controller widget in the app (saved here: \themes\FoldableTheme\widgets\HeaderController), and the line I added to it's manifest was: "controlledWidgets": ["widgets_TOC_Widget_38", "widgets_BasemapGallery_Widget_60"]

It had two widgets, our table of contents, and a basemap gallery widget. I copied these id values from our root widget's config file.

Other than these, I more or less followed the directions of Esri's create a new controller widget tutorial: Create a controller widget—Web AppBuilder for ArcGIS (Developer Edition) | ArcGIS for Developers 

View solution in original post

2 Replies
EricRuberson1
New Contributor III

Resolved:

I turned the Identify Widget into a controller widget and embedded the launching icon for the Add Data widget within the Identify Widget's first tab container.

My key takeaways or problems solved:

1)

<div class="container-section" data-dojo-attach-point="containerNode"></div>

That determines where the widgets being controlled by the parent widget wind up. (This goes into the widget.html of your controller widget.)

Note that it only attached the button that launches the widget. Our Add Data widget still ended up running all it's panel functions into the panel associated with my table of contents/layer list widget. At some point I may have to figure out how to run it in it's own new popup panel, but that is an aside from this post.

2) There's a nearly undocumented ability to choose which widgets are being controlled by which Controller widget. It's part of the functionality of jimu/PoolControllerMixin

Assume you want multiple controller widgets in your app.

All apps being controlled by the widgets (aka the children apps) need to be listed in the root app's config.json file in the widget pool. That is, I don't believe you need to add a widget pool to your parent widgets.

You need to add:  '   "IsController": true, ' to the manifest.json properties for your controller widgets if its not already there.

you Also need to add: '  "controlledWidgets": ["_50"]  ' to your manifest.json properties section. Inside the array you need a list of strings that have the id for your widget. In this case my Add Data widget had the id of _50. I also had a Header Controller widget in the app (saved here: \themes\FoldableTheme\widgets\HeaderController), and the line I added to it's manifest was: "controlledWidgets": ["widgets_TOC_Widget_38", "widgets_BasemapGallery_Widget_60"]

It had two widgets, our table of contents, and a basemap gallery widget. I copied these id values from our root widget's config file.

Other than these, I more or less followed the directions of Esri's create a new controller widget tutorial: Create a controller widget—Web AppBuilder for ArcGIS (Developer Edition) | ArcGIS for Developers 

NathanHeickLACSD
Occasional Contributor III

Thanks a lot Eric!  @Jianxia, is there are any more documentation for having multiple controller widgets?  I am hoping that all I need to do is add the property controlledWidgets to each controller widgets' manifest.json file.  Still, I am not too clear about the widget pool.  I am trying to merge the SidebarController and the HeaderController into one app.  I think I can get each controller to manage different widgets, but I'm not sure where to put the panel references.

0 Kudos