How to programmatically open a widgetOnScreen widget

10598
5
10-14-2014 08:54 AM
MapEnglish
Occasional Contributor

Let's say I put the Basemap Gallery widget in the widgetOnScreen section of the main config.json. How do I programmatically open it?

This code does not work:

PanelManager.getInstance().showPanel(WidgetManager.getInstance().appConfig.widgetOnScreen.widgets[4])

Any insight would be helpful,

Thanks, Matt English

0 Kudos
5 Replies
deleted-user-Jie3eyjOl9XM
Occasional Contributor

I have a similar problem. My widget isn't widgetOnScreen. Rather, I need to programmatically load and open a widget that was controller by the header widget. So, I had to load the widget, and also open the panel. Here's what I've got so far:

var wm = WidgetManager.getInstance(); 
var myWidget = null; 
arrayUtils.some(wm.appConfig.widgetPool.widgets, function(aWidget) {
  if(aWidget.id == 'somewidgetid') {
    myWidget = aWidget;
    return true;
  }
  return false;
}); 
wm.loadWidget(myWidget); 
wm.openWidget(myWidget); 
var pm = PanelManager.getInstance(); 
pm.showPanel(myWidget);

This will open the widget in the panel. Unfortunately, it opens my widget as a NEW widget, rather than activating the widget in the header controller. I can tell because the widget icon, in the header, is not toggled.

It's a step in the right direction. But hopefully this will bump someday else to contribute to the thread.

0 Kudos
LarryStout
Occasional Contributor III

Here are some functions I have written to programatically open widgets:

// For widgets not in a panel that are not loaded at startup, load and return the widget.
_getWidget: function(widgetCfg, start) {
  var def = new Deferred();
  var widget;

  if (widgetCfg) {
    // Try getting the widget
    widget = registry.byId(widgetCfg.id);

    if (widget) {
      def.resolve(widget);
    } else {
      this.widgetManager.loadWidget(widgetCfg).then(function(widget) {
        if (start) {
          widget.startup();
        }
        def.resolve(widget);
      });
    }
  } else {
    def.resolve(undefined);
  }
  return def;
},

_getWidget(widgetCfg, start) will return a widget for widgets not in panels.  An example of widgetCfg is WidgetManager.getInstance().appConfig.widgetOnScreen.widgets[4].  If start is true, the widget will be started.

// For in panel widgets that are not loaded at startup, load and return the widget.
_getPanel: function(widgetCfg, start) {
  var def = new Deferred();
  var panel;
  
  if (widgetCfg) {
    // Try getting the panel for this widget
    panel = registry.byId(widgetCfg.id + '_panel');

    if (panel) {
      def.resolve(panel);
    } else {
      this.panelManager.showPanel(widgetCfg).then(function(panel) {
        if (start) {
          panel.startup();
        }
        def.resolve(panel);
      });
    }
  } else {
    def.resolve(undefined);
  }
  return def;
},

_getPanel(widgetCfg, start) will return a panel (which contains the widget) for widgets in panels.  An example of widgetCfg is WidgetManager.getInstance().appConfig.widgetOnScreen.widgets[4].  If start is true, the widget will be started.

// For widgets that are loaded at startup, return the widget when it is available.
// Recursive Deferred from http://developer.the-hideout.de/?p=125
_getWidgetWhenLoaded: function(id, wait, count) {
  var def = new Deferred();
  var widget = registry.byId(id);
    
  if (widget || count === 0) {
    def.resolve(widget);
    return def.promise;
  }
  
  setTimeout(lang.hitch(this, function() {
    this._getWidgetWhenLoaded(id, wait, count - 1).then(function(widget) {
      def.resolve(widget);
    });
  }), wait);
  
  return def;
},

__getWidgetWhenLoaded(id, wait, count) will return a widget that is autoloaded as soon as it is available.  id is the widget id (e.g. WidgetManager.getInstance().appConfig.widgetOnScreen.widgets[4].id), wait is the milliseconds to wait between each attempt, and count is the number of times to try.  If wait is 100 and count is 10, it will try to get the widget every 100 milliseconds for a maximum of 1 second.

I am using these functions to retrieve and/or start the Attribute Table, Basemap Gallery, Coordinate, Geocoder, LayerList, and Scalebar widgets along with a couple of custom widgets I have written.

Larry

0 Kudos
deleted-user-Jie3eyjOl9XM
Occasional Contributor

The functions that Larry provided are great. Unfortunately, they didn't exactly work for me. I "think" (not sure), a lot depends on what kind of widget, panel, and group you are dealing with.

I posted a similar question here:

Web Appbuilder Communication Between Widgets

And the function that I'm using, similar to one of Larry's, is here:

Get on the “Event Bus” | A.J. Morris

After all that, my gut tells me that we need to get a handle to the HeaderController widget somehow, and use it's functions for showing the widget.

0 Kudos
LarryStout
Occasional Contributor III

AJ,

If I remember correctly, to start an inPanel widget, you only need to start the panel. See my _GetPanel function.

More details on exactly what you are trying to do and what is going wrong would be helpful.

Larry

0 Kudos
AsmaaMohamed
New Contributor II

I have problem, i need to open widget from another widget by code

Asmaa Mohamed
0 Kudos