widgetmanager.triggerWidgetOpen does not show widget in tab theme

1360
13
Jump to solution
11-10-2016 03:37 PM
JadeFreeman
Occasional Contributor III

I'm developing a Feature Action for a custom widget.  Following the instructions at Create a feature action in your widget—Web AppBuilder for ArcGIS (Developer Edition) | ArcGIS for De... , I have everything working except when I add my custom widget to an application using the Tab theme, my widget is not shown.

Here's the code for my onExecute method:

onExecute: function(featureSet){
    WidgetManager.getInstance().triggerWidgetOpen( this.widgetId )
        .then( lang.hitch( this, function ( myWidget ) {
            this.widget = myWidget;
            var feature = featureSet.features[0];
            this.showLinksForFeature( feature );
        }));
},

Am I doing something wrong?  I'm using Web AppBuilder 2.1.

0 Kudos
1 Solution

Accepted Solutions
JadeFreeman
Occasional Contributor III

I abstracted the code for handling opening the widget in the sidebar into a separate method in a mixin (so that I can use it multiple feature actions).  If the widget being opened is not in tab position 1-4, adding some code to set the selected property of tabs 1 thru 4 to false and hide the indicator seems to do the trick.

showSidebarControllerTab: function () {
    var controller = WidgetManager.getInstance().getWidgetsByName( 'SidebarController' )[ 0 ];
    if ( !controller ) {
        return;
    }
    controller.setOpenedIds( [ this.widgetId ] );

    var configs = controller.getAllConfigs();
    var configIds = array.map(configs, function(g) {
        if (g && g.id) {
            return g.id;
        }
        return null;
    });

    var idx = configIds.indexOf( this.widgetId );
    if (idx > 3) {
        array.forEach( [0,1,2,3], function ( tabIndex ) {
            controller.tabs[ tabIndex ].selected = false;
            controller._hideIndicator( tabIndex );
        } );
    }
}

					
				
			
			
				
			
			
				
			
			
				

View solution in original post

0 Kudos
13 Replies
RobertScheitlin__GISP
MVP Esteemed Contributor

Jade,

   So it is actually opening the widget. But it is not triggering the tab theme panel to open. to do that you need to add some more code:

    onExecute: function(featureSet){
      WidgetManager.getInstance().triggerWidgetOpen(this.widgetId)
      .then(function(myWidget) {
        var sidebarWidget = WidgetManager.getInstance().getWidgetsByName("SidebarController");
        if (sidebarWidget[0]) {
          WidgetManager.getInstance().maximizeWidget(sidebarWidget[0]);
        }
        var vertexCount = 0;
        featureSet.features.forEach(function(f){
          f.geometry.rings.forEach(function(r){
            vertexCount += r.length;
          });
        });
        myWidget.showVertexCount(vertexCount);
      });
    }‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
JadeFreeman
Occasional Contributor III

Thanks Robert!  One question, when you call the .maximizeWidget() function are you passing in the Controller widget or the widget you just opened?  In your code above you pass in the the controller widget but it would seem you want to maximize the widget being opened?

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Jade,

I am passing in the SidebarController from the tab theme. The widget itself is open and maximized by the triggerWidgetOpen.

0 Kudos
JadeFreeman
Occasional Contributor III

Also, I've noticed similar behavior in the foldable theme.  I imagine you would also want to check for the HeaderController as well to make the action truly portable?

0 Kudos
JadeFreeman
Occasional Contributor III

Nevermind that last question.  The SidebarController can expand and collapse which is why your code is needed also is not needed for the HeaderController.  Unfortunately, this doesn't entirely fix the issue.  In my case, the app I am including the widget in has another widget in the Sidebar which is open by default.  

The problem I'm having is a little more subtle.  I actually have two custom widgets in my app both which have custom feature actions.  The first call to triggerWidgetOpen seems to work fine.  Any existing widget which is open gets replaced with the widget being opened by the custom feature action.  However, if another custom widget/feature action is invoked, it almost seems the second widget is being opened on top of the first widget and so if you invoke the first custom widget/feature action again, since the widget it is opening is already open but sitting underneath another widget, nothing happens, i.e. the widget isn't shown.

Seems like there needs to be a call to some method on the Controller widget to tell it which widget to show.  Hopefully, this explanation isn't too confusing!

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Jade,

  I believe this is what you are after then:

    onExecute: function(featureSet){
      WidgetManager.getInstance().triggerWidgetOpen(this.widgetId)
      .then(function(myWidget) {
        var sidebarWidget = WidgetManager.getInstance().getWidgetsByName("SidebarController")[0];
        if (sidebarWidget) {
          WidgetManager.getInstance().maximizeWidget(sidebarWidget);
          sidebarWidget.setOpenedIds([this.widgetId]);
        }
        var vertexCount = 0;
        featureSet.features.forEach(function(f){
          f.geometry.rings.forEach(function(r){
            vertexCount += r.length;
          });
        });
        myWidget.showVertexCount(vertexCount);
      });
    }
JadeFreeman
Occasional Contributor III

Hmm..not quite working.

Digging thru the SidebarController\Widget code, the setOpenedIds method simply calls the _openLastTab method passing in the array of ids it was passed.  This method retrieves the tab index for each id passed in but will only call the selectTab method (which I assume would actually show the widget correctly) if the tab index is less than 4.

The setOpenedIds method in the HeaderController code (foldable theme) works a bit different and looks like would hide or close any opened widget and then show the widget id(s) passed into the method.

Looks like I'll need to detect whether the app uses a HeaderController or SidebarController and then if it uses a HeaderController, call the setOpenedIds method but if it uses a SidebarController then I'll need to get the tab index from the widget configs and then call the selectTab method.

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Jade,

   I disagree on the Tab theme. When you use setOpenedIds if you trace the whole progression it calls the selectTab method. So there is not need for you to call that directly.

I guess I don't understand why this question is not answered. In my testing when using the tab theme my last code works great for opening the sidebar controller and the widget in question, even if there is already another widget opened in the sidebar controller.

JadeFreeman
Occasional Contributor III

First off, thanks for your help!  I do appreciate it!  

I've gone back to calling the setOpenIds method and can tell you definitively that while it does call the selectTab method, the right widget is not being shown.  I suspect it may have something to do with having more than 4 widgets configured in the sidebar and one of the widgets I'm trying to open is configured as the last widget in the sidebar so it shows up in the more widgets group.  I'm trying to track that down now.  

The problem seems to stem from calling a feature action of a custom widget that's not configured to be in one of the first four widgets in the sidebar.  While the widget is shown, if I then invoke a custom feature action on a widget that is configured to be in one of the first 4 positions, the selectTab method is indeed called, the icon for that widget is highlighted but the widget that is displayed is the previous custom widget.

Can you confirm that calling setOpenedIds works for you with more than 4 widgets configured with widgets that have custom feature actions configured in positions 1-4 and one in position greater than 4?  

0 Kudos