Open another widget from a custom widget link

3012
8
Jump to solution
10-28-2016 04:49 PM
GregRieck
Occasional Contributor III

Hello, I have a created a widget that loads at startup. This widget creates a couple of "links" on the bottom of the attribute window, next to the "Zoom To". I'm trying to pass data from the selected features attributes to another widget. I have the feature data I want to pass. I just can't get a reference to the other widget and I can't get it to open. I've been trying to follow the Communication with other widget and other examples I've found here but can't get it to work. Any idea's or thoughts would be appreciated. 

Shows the custom links in the attribute window

Below is MyStartUp widget that creates the links. I would like to call another widget "C" from the this.BClickListener = on(linkB, "click", function(evt){

It would also be nice to be able to do it as a function. So I can call the same function in the linkA click event. But, I've struggled with that too.

define([
'dojo/_base/declare',
'dojo/dom-construct',
'dojo/query',
'dojo/on',
'dojo/_base/lang',
'jimu/BaseWidget',
'jimu/WidgetManager',
'jimu/PanelManager'
], function(
declare, domConstruct, query, on, lang, BaseWidget, WidgetManager, PanelManager
) {
//To create a widget, you need to derive from BaseWidget.
return declare([BaseWidget], {

// Custom widget code goes here
baseClass: 'MyStartUp',
// this property is set by the framework when widget is loaded.
// name: 'MyStartUp',
// add additional properties here

//methods to communication with app container:
postCreate: function() {
this.inherited(arguments);
console.log('MyStartUp::postCreate');

this.ADomNode = null;
this.AClickListener = null;

this.BDomNode = null;
this.BClickListener = null;

this.map.infoWindow.on("selection-change", lang.hitch(this, function(){
if (this.ADomNode){
domConstruct.destroy(this.ADomNode);
}
if (this.AClickListener){
this.AClickListener.remove();
}
if (this.BDomNode){
domConstruct.destroy(this.BDomNode);
}
if (this.BClickListener){
this.BClickListener.remove();
}
var feature = this.map.infoWindow.getSelectedFeature();
if(feature){
if (feature.attributes.hasOwnProperty("myid")) {
this.ADomNode = domConstruct.create("a",{
"class": "action",
"id": "linkA",
"innerHTML": " A ", //text that appears in the popup for the link
"href": "javascript: void(0);"
}, query(".actionList", this.map.infoWindow.domNode)[0]);

//when the link is clicked register a function that will run
this.AClickListener = on(linkA, "click", function(evt){
console.log(evt);
});

this.BDomNode = domConstruct.create("a",{
"class": "action",
"id": "linkB",
"innerHTML": " B ", //text that appears in the popup for the link
"href": "javascript: void(0);"
}, query(".actionList", this.map.infoWindow.domNode)[0]);

//when the link is clicked register a function that will run
this.BClickListener = on(linkB, "click", function(evt){
console.log(evt);

var wm = WidgetManager.getInstance();
var widgetsConfig = wm.widgetPool.widgets;
var widgetId;
for(var i in widgetsConfig){
if(widgetsConfig.name == "B"){
widgetId = widgetsConfig.id;
break;
}
}
var widget = wm.getWidgetsByName("AnchorBarController")[0];
widget.setOpenedIds([widgetId]);


if(widgets.length === 0){
this.loadWidgetBInfoNode.innerText = 'Widget B is not configured.';
return;
}

var widgetId = widgets[0].id;
if(this.widgetManager.getWidgetById(widgetId)){
this.loadWidgetBInfoNode.innerText = 'Widget B has been loaded.';
return;
}
this.openWidgetById(widgetId).then(lang.hitch(this, function(widget){
this.loadWidgetBInfoNode.innerText = widget.name + ' is loaded';
}));
});
}
else if (feature.attributes.hasOwnProperty("myid")){
this.BDomNode = domConstruct.create("a",{
"class": "action",
"id": "linkB",
"innerHTML": " B ", //text that appears in the popup for the link
"href": "javascript: void(0);"
}, query(".actionList", this.map.infoWindow.domNode)[0]);

//when the link is clicked register a function that will run
this.BClickListener = on(linkB, "click", function(evt){
console.log(evt);
});
}
}
}
));
}
// startup: function() {
// this.inherited(arguments);
// console.log('MyStartUp::startup');
// },

// onOpen: function(){
// console.log('MyStartUp::onOpen');
// },

// onClose: function(){
// console.log('MyStartUp::onClose');
// },

// onMinimize: function(){
// console.log('MyStartUp::onMinimize');
// },

// onMaximize: function(){
// console.log('MyStartUp::onMaximize');
// },

// onSignIn: function(credential){
// console.log('MyStartUp::onSignIn', credential);
// },

// onSignOut: function(){
// console.log('MyStartUp::onSignOut');
// }

// onPositionChange: function(){
// console.log('MyStartUp::onPositionChange');
// },

// resize: function(){
// console.log('MyStartUp::resize');
// }

//methods to communication between widgets:

});

});

0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Greg,

   I now have spent more time looking at what you are actually trying to do and I would suggest that you look at the 

client\stemapp\widgets\AttributeTable\actions\ViewInAttributeTableFeatureAction.js 

FeatureActions can be added to the popups menu (this is assuming you do not really want that link next to the Zoom To and can deal with a option on the menu instead).

View solution in original post

8 Replies
RobertScheitlin__GISP
MVP Emeritus

Greg,

   Here is some change to your code to open a widget using your links:

define([
    'dojo/_base/declare',
    'dojo/dom-construct',
    'dojo/query',
    'dojo/on',
    'dojo/_base/lang',
    'jimu/BaseWidget',
    'jimu/WidgetManager',
    'jimu/PanelManager',
    'dojo/_base/array'
], function(
    declare, domConstruct, query, on, lang, BaseWidget, WidgetManager, PanelManager, array
) {
    //To create a widget, you need to derive from BaseWidget.
    return declare([BaseWidget], {
        // Custom widget code goes here
        baseClass: 'MyStartUp',
        wManager: null,
        pManager: null,
        // this property is set by the framework when widget is loaded.
        // name: 'MyStartUp',
        // add additional properties here
        //methods to communication with app container:
        postCreate: function() {
            this.wManager = WidgetManager.getInstance();
            this.pManager = PanelManager.getInstance();
            this.inherited(arguments);
            console.log('MyStartUp::postCreate');
            this.ADomNode = null;
            this.AClickListener = null;
            this.BDomNode = null;
            this.BClickListener = null;

            this.map.infoWindow.on("selection-change", lang.hitch(this, function() {
                if (this.ADomNode) {
                    domConstruct.destroy(this.ADomNode);
                }
                if (this.AClickListener) {
                    this.AClickListener.remove();
                }
                if (this.BDomNode) {
                    domConstruct.destroy(this.BDomNode);
                }
                if (this.BClickListener) {
                    this.BClickListener.remove();
                }
                var feature = this.map.infoWindow.getSelectedFeature();
                if (feature) {
                    if (feature.attributes.hasOwnProperty("myid")) {
                        this.ADomNode = domConstruct.create("a", {
                            "class": "action",
                            "id": "linkA",
                            "innerHTML": " A ", //text that appears in the popup for the link
                            "href": "javascript: void(0);"
                        }, query(".actionList", this.map.infoWindow.domNode)[0]);
                        //when the link is clicked register a function that will run
                        this.AClickListener = on(this.ADomNode, "click", function(evt) {
                            console.log(evt);
                        });
                        this.BDomNode = domConstruct.create("a", {
                            "class": "action",
                            "id": "linkB",
                            "innerHTML": " B ", //text that appears in the popup for the link
                            "href": "javascript: void(0);"
                        }, query(".actionList", this.map.infoWindow.domNode)[0]);
                        //when the link is clicked register a function that will run
                        this.BClickListener = on(this.BDomNode, "click", function(evt) {
                            console.log(evt);
//Here is my code for opening the widget and then getting a reference returned so that you can call a function in the widget                            
                            var widgetCfg = this._getWidgetConfig('B');
                            if (widgetCfg) {
                                this.wManager.triggerWidgetOpen(widgetCfg.id).then(lang.hitch(this, function(bWidget) {
                                    //now execute a function or set a var in the bWidget;
                                }));
                            }
//End                            
                        });
                    } else if (feature.attributes.hasOwnProperty("myid")) {
                        this.BDomNode = domConstruct.create("a", {
                            "class": "action",
                            "id": "linkB",
                            "innerHTML": " B ", //text that appears in the popup for the link
                            "href": "javascript: void(0);"
                        }, query(".actionList", this.map.infoWindow.domNode)[0]);
                        //when the link is clicked register a function that will run
                        this.BClickListener = on(this.BDomNode, "click", function(evt) {
                            console.log(evt);
                        });
                    }
                }
            }));
        },

        _getWidgetConfig: function(widgetName) {
            var widgetCnfg = null;
            array.some(this.wManager.appConfig.widgetPool.widgets, function(aWidget) {
                if (aWidget.name == widgetName) {
                    widgetCnfg = aWidget;
                    return true;
                }
                return false;
            });
            if (!widgetCnfg) {
                /*Check OnScreen widgets if not found in widgetPool*/
                array.some(this.wManager.appConfig.widgetOnScreen.widgets, function(aWidget) {
                    if (aWidget.name == widgetName) {
                        widgetCnfg = aWidget;
                        return true;
                    }
                    return false;
                });
            }
            return widgetCnfg;
      }
    });
});
0 Kudos
GregRieck
Occasional Contributor III

Robert,

Thank you for the response. My issues with getting this to work have revolved around being able to get a reference to the other widget. In the example 

var widgetCfg = this._getWidgetConfig('B');

'B' is the name of the other widget correct? Is there a particular "name" that it could be looking for? Is it case sensitive? I'm using the name as found in the config.json. What else can I try? I am getting this error: "Widget.js?wab_dv=2.2:78 Uncaught TypeError: this._getWidgetConfig is not a function"

Greg

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Greg,

   Ahh, if you are getting this_.getWidgetConfig is no a function then your code that is executing it is out of scope.

Update this code block with the code below:

                        this.BClickListener = on(this.BDomNode, "click", lang.hitch(this, function(evt) {
                            console.log(evt);
//Here is my code for opening the widget and then getting a reference returned so that you can call a function in the widget                            
                            var widgetCfg = this._getWidgetConfig('B');
                            if (widgetCfg) {
                                this.wManager.triggerWidgetOpen(widgetCfg.id).then(lang.hitch(this, function(bWidget) {
                                    //now execute a function or set a var in the bWidget;
                                }));
                            }
//End                            
                        }));

'B' is the name of the other widget correct? Yes

Is there a particular "name" that it could be looking for? What ever is the name of the widget you are trying to open.

Is it case sensitive? Yes

I'm using the name as found in the config.json That is correct.

0 Kudos
GregRieck
Occasional Contributor III

Robert, 

Same thing. "this" is okay, it's valid but _getWidgetConfig is not valid and is still throwing the is not a function error.

Greg

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Greg,

   I now have spent more time looking at what you are actually trying to do and I would suggest that you look at the 

client\stemapp\widgets\AttributeTable\actions\ViewInAttributeTableFeatureAction.js 

FeatureActions can be added to the popups menu (this is assuming you do not really want that link next to the Zoom To and can deal with a option on the menu instead).

GregRieck
Occasional Contributor III

Robert,

I'm trying to do the following:

1) have the link(s) visible only in specific feature layers

2) when a link is clicked pass certain attribute information to another widget

3) the other widget will use the attribute information to populate data within the widget and display itself for use

I do not care that the link is in the menu I just want a link in the attribute popup window that can communicate with and pass information to another widget. This widget needs to be available when the page loads so that the links appear right away and no other widgets need to be clicked first.

I looked at this url Create a feature action in your widget—Web AppBuilder for ArcGIS (Developer Edition) | ArcGIS for De...  and followed the sample link provided  http://<your host machine>:3344/webappviewer/?config=sample-configs/config-demo.json. This appears to do exactly what I'm looking for. However, being new to JS I find it difficult to pull out just what I need from all the provided sample material. Plus I'm not certain I can limit the visibility of the custom links to specific feature layers. I don't want the links available to all of the feature layers. They are only appropriate to specific features layers.

I'll keep working on it, thank you Robert for your comments and suggestions.

Greg

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Greg,

  You use the isFeatureSupported method to look at the featureSet and or the featureLayer properties to determine if this is a layer you want thei FeatureAction to be available for.

0 Kudos
GregRieck
Occasional Contributor III

Robert,

I apologize for the delay. My JS development isn't a priority so I don't get to work in as often as I would like. You were spot on with the FeatureAction. That is exactly what worked and I love how it functions.It cleared up my widget communication issues and accomplished my goal.

Thank You for your help could not have done it without your input.

Greg