Widget.destroy() is destroying too much

1519
4
08-21-2017 02:07 PM
GregSalvador
New Contributor III

Howdy all!

I have been practicing with the BasemapGallery widget. I wanted to make a button that destroys or creates the widget, so i could "hide" and "show" the widget. The BasemapGallery is pretty big, screen space wise, so I just want a way to get it out of the way when it isn't needed.  I did this by creating a <div> element, then assigning the "hide" button and the widget to it. In my code, all the button does is destroy the widget (I'll figure out how to bring it back later). However, when I click the button, both the widget and the button get destroyed. Why is my basemapGallery.destroy() command so bloodthirsty? Below is the code I have:

//initialization of the basemapGallery widget
var basemapDom = domConstruct.toDom("<div id='divContainer'></div>");
var basemapGallery = new BasemapGallery({
view: view,
container: basemapDom
});
//BasemapGallery hide button is being defined
watchUtils.whenDefinedOnce(basemapGallery, "viewModel", function (evt) {
//trying to create a div element and place the button and widgit inside of it

var buttonDom = domConstruct.create("button",
{ class: 'basemapGallery', type: 'button', innerHTML: 'Basemaps'},
basemapDom, "first");
on(buttonDom, 'click', function () {
basemapGallery.destroy();
});
});

view.ui.add(basemapDom, {
position: "top-right"
});

Thanks for taking a look at this

Tags (1)
0 Kudos
4 Replies
JohnGrayson
Esri Regular Contributor
KevinMacLeodCAI
Occasional Contributor II

@JohnGrayson  does expand destroy the widget? I want to remove a measurement widget instance so as to remove its click handlers, on-screen graphics, etc.  Basically I want to take the Measurement example and put it in a side panel in a dom node. Of course out of the box; this does not work as this thread describes, because the widget destroys its own container. I've struggled with trying to use plain JS or jQuery to create a dom node; then append and move the widget to it; no dice. 

When widgets are added with the view.ui.add it doesn't do this. But when you add them to a DOM node; it adds esri classes to the container node itself. I suspect the destroy method looks for these classes and queries, to decide what to destroy. I agree with original poster. It goes one level up too high. Destroying a widget should not destroy its container. Nor should a container get polluted with classes from a widget it contains, they should be separate. Furthermore it would be nice to have a unified click handling for widgets with a default where if you start measuring, Draw stops listening, other widgets stop listening etc. Have that on by default with ability to turn off 'smart' clicking handling.  This widget destroy() container issue is relevant for just about any widget.

 

Meantime maybe I'll do a hack of a way to do it; try moving the element from view.ui and appending to the panel after it gets rendered. 

KevinMacLeodCAI
Occasional Contributor II

@JohnGrayson  is there an example sample with a Measure widget being put in to an existing DOM node? Where it won't destroy its container when it gets removed with the .destroy() method?  I tried Expand and predictably all it does is hide the interface, it has no effect on the graphics or click handlers.

0 Kudos
JohnGrayson
Esri Regular Contributor

@KevinMacLeodCAI sorry, just saw this.  We can try to find a workaround here, but you might also consider creating a ticket via Tech Support so these dev usability issues get into the system.  I've recently used the Measurement related widgets in several apps, both using the view.ui.add(...) technique and in a side panel outside of the view.  I never try to destroy the widget; the UI is always around.  If you want to clear existing measurement results and graphics, you can call the clear() method.  Do you have a codepen showing the issue?

0 Kudos