Load In-Panel Widget onStart of the application

9249
10
Jump to solution
03-25-2015 02:48 AM
eduAED
by
New Contributor II

Anybody knows how to load a custom in-panel Widget onStartUp?

I want to receive data from an off-panel widget, but the onReceiveData event of in-panel widgets only fires if the Widget was already opened.

I would like to load the widget when my application stars, but not to open it!!! I saw the property "openAtStart": true, but this is showing the panel and

I dont want to show the panel on initialitation of the application.

Thank you very much!

0 Kudos
1 Solution

Accepted Solutions
LarryStout
Occasional Contributor III

Here's the function I use in my onScreen widget to start an inPanel widget "silently".  Basically, you start the panel, which starts the widget.  After the widget starts, you hide the panel.

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

    if (panel) {
      if (hide) {
        // Hide the panel immediately.
        domStyle.set(panel.domNode, 'display', 'none');
        // panelManager.showPanel calls panelManager.openPanel, which returns a promise.
        // We have to wait for the panel to open before we close it.
        on.once(panel, 'open', function() {
          panel.panelManager.closePanel(panel, false);
        });
      }
      def.resolve(panel);
    } else {
      this.panelManager.showPanel(widgetCfg).then(lang.hitch(this, function(panel) {
        if (hide) {
          // Hide the panel immediately.
          domStyle.set(panel.domNode, 'display', 'none');
          // panelManager.showPanel calls panelManager.openPanel, which returns a promise.
          // We have to wait for the panel to open before we close it.
          on.once(panel, 'open', function() {
            panel.panelManager.closePanel(panel, false);
          });
        }
        lang.mixin(panel, panelMixinData);
        def.resolve(panel);
      }));
    }
  } else {
    def.resolve(undefined);
  }
  return def;
},

The panelMixinData argument can be any object you want the widget to have access to when it starts.  For example, if the panelMixinData = { myStuff: { stuff1: 'abc', stuff2: 123 } }, the widget you are starting can get that data as:

this.panel = registry.byId(this.id + '_panel');
var thing1 = this.panel.myStuff.stuff1;  // 'abc'
var thing2 = this.panel.myStuff.stuff2; // 123

Here's a simplified version of the code at the top of my onScreen widget showing how I get access to the PanelManager:

define([
  'jimu/PanelManager'
], function(
  PanelManager
) { 
  var clazz = declare([BaseWidget], {
    name: 'Acme',
    baseClass: 'jimu-widget-acme',

    startup: function() {
      this.inherited(arguments);
      
      this.panelManager = PanelManager.getInstance();
    },
    

Hope this helps,

Larry

View solution in original post

0 Kudos
10 Replies
LarryStout
Occasional Contributor III

I have used an invisible onScreen widget to manage tasks such as this.  It starts when the app starts because it is onScreen (but invisible).

Larry

0 Kudos
eduAED
by
New Contributor II

Thank you Larry,

I also tried to initialize my widget from another custom onScreen Widget that I have, but trying to load "jimu/PanelManager" or "jimu/BaseWidget" I allways get that they are undefined.

I don´t have this problem for the in-panel widgets I created.

Did you ever have a similiar problem?

Thanks

0 Kudos
LarryStout
Occasional Contributor III

Here's the function I use in my onScreen widget to start an inPanel widget "silently".  Basically, you start the panel, which starts the widget.  After the widget starts, you hide the panel.

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

    if (panel) {
      if (hide) {
        // Hide the panel immediately.
        domStyle.set(panel.domNode, 'display', 'none');
        // panelManager.showPanel calls panelManager.openPanel, which returns a promise.
        // We have to wait for the panel to open before we close it.
        on.once(panel, 'open', function() {
          panel.panelManager.closePanel(panel, false);
        });
      }
      def.resolve(panel);
    } else {
      this.panelManager.showPanel(widgetCfg).then(lang.hitch(this, function(panel) {
        if (hide) {
          // Hide the panel immediately.
          domStyle.set(panel.domNode, 'display', 'none');
          // panelManager.showPanel calls panelManager.openPanel, which returns a promise.
          // We have to wait for the panel to open before we close it.
          on.once(panel, 'open', function() {
            panel.panelManager.closePanel(panel, false);
          });
        }
        lang.mixin(panel, panelMixinData);
        def.resolve(panel);
      }));
    }
  } else {
    def.resolve(undefined);
  }
  return def;
},

The panelMixinData argument can be any object you want the widget to have access to when it starts.  For example, if the panelMixinData = { myStuff: { stuff1: 'abc', stuff2: 123 } }, the widget you are starting can get that data as:

this.panel = registry.byId(this.id + '_panel');
var thing1 = this.panel.myStuff.stuff1;  // 'abc'
var thing2 = this.panel.myStuff.stuff2; // 123

Here's a simplified version of the code at the top of my onScreen widget showing how I get access to the PanelManager:

define([
  'jimu/PanelManager'
], function(
  PanelManager
) { 
  var clazz = declare([BaseWidget], {
    name: 'Acme',
    baseClass: 'jimu-widget-acme',

    startup: function() {
      this.inherited(arguments);
      
      this.panelManager = PanelManager.getInstance();
    },
    

Hope this helps,

Larry

0 Kudos
JosephDavies
New Contributor III

Hi Larry,

I'm trying to run your function from the onOpen section of my widget but I cant seem to get it to work. Am i supposed to change 'widgetCfg'?  Also is it necessary to change the panelMixinData value?

Thanks,

Joe

MarkJones7
Occasional Contributor

Hi Larry,

I realize this is an old thread, but I would appreciate it immensely if you could explain how you created your invisible onScreen Widget to run behind the scenes functionality.  I know how to create the functionality to turn a web layer on, but I want to place this within an invisible widget so it turns on automatically (the original web map has a particular layer turned off and I don't have access to that web map to change it). =]

Any help you can provide is greatly appreciated.


Thanks,

Mark

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Mark,

   Larry switched jobs quite a while back and is not active on GeoNet anymore. It does not sould like you need a widget for what you are trying to do. If you do not have access to that webmap then just create a new webmap referencing the same layers REST urls. If you are set doing this in code then just put your code in the MapManager.js file instead.

MarkJones7
Occasional Contributor

Wow! Lightning fast response Robert! Thank you kindly.

Doing it via code is a better option for me.

Your suggestion worked perfectly! Although, to be honest, it did take some trial and error to find the right process to attach it to. =]

Thanks again,

Mark

0 Kudos
MarkJones7
Occasional Contributor

Sorry to bother you again Robert, but I was still wondering how one would go about creating the "invisible onscreen widget" Larry made mention to.

Thanks,
Mark

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Mark,

   You create a widget that has the inPanel property in the manifest.json set to false, this widget will have no Widget.html and it has to be manually added to the apps main config.json. There are not any samples or examples of this provided by esri that I am aware of.