In in-panel custom widget onOpen() function, if some critical config aram is empty, I output alert,
then I want to close the widget (as if someone clicked the "x" button, or as I have not clicked to open it at all).
I wrote:
PanelManager.getInstance().closePanel(this.id + '_panel');
but it failed, maybe because I'm "inside" onOpen() ?
My questions:
1. How to nicely close in-panel custom widget programatically from within onOpen()?
2. My first lines of onPen() are:
if (!this.isOpening) {
this.isOpening = true;
Do I have to reset this.isOpening to false before I close the widget?
3. The code in WidgetManager.js id:
if (widget.state === 'closed') {
html.setStyle(widget.domNode, 'display', '');
widget.setState('opened');
try {
widget.onOpen();
} catch (err) {
console.error('fail to open widget ' + widget.name + '. ' + err.stack);
}
}
Should I exit onOpen() with exception and put the alert inside the Widgetmanager?
4. I wish that the widget will really cose (the icon will go back downwards.
5. I wish that I'll get the alert every time I click on the widget (not only in the first time).
Help will be greatly appreciated,
Michael
Solved! Go to Solution.
Michael,
Sounds like it may be a race condition (timing). You should try:
setTimeout(lang.hitch(this, function () {
PanelManager.getInstance().closePanel(this.id + '_panel');
}), 500);
Michael,
Sounds like it may be a race condition (timing). You should try:
setTimeout(lang.hitch(this, function () {
PanelManager.getInstance().closePanel(this.id + '_panel');
}), 500);
Dear Robert,
Thank you very much! You always save my day! It works!
Only I found that in order to get the alert when I re-open the in-panel widget,
I have to reset "isOpening" inside setTimeout:
onOpen: function () {
if (!this.isOpening) {
this.isOpening = true;
let missing = [];
// ... code lines to test parameters
if (missing.length !== 0) {
let errMsg = `missing config param${missing.length > 1 ? "s" : ""}: ${missing.join(", ")}`;
alert(errMsg);
} else {
// code lines to do if parameteers are OK
}
// close widget
setTimeout(lang.hitch(this, function () {
this.isOpening = false;
//PanelManager.getInstance().closePanel(this.id + '_panel');
WidgetManager.getInstance().closeWidget(this); //best way to close
}), 300);
}
}, // eof onOpen()
So, now it works - thank you for explaining that closing the widget from within onOpen() creates race conditions, and for showing how to handle it.
If I may only ask, I wish to also get explanations:
With appreciation,
Michael
Michael,
1. Q: What is the function of "isOpening" property?
A: I have not used that property before.
2. Q: What exactly is the cause of the race conditions? and how does the setTimeout handle it?
A: Your code is requesting that the widget is to be closed before something (not sure what) is completed in the widgets code or base code is complete. Using the timeout causes the request to close to delay for so many milliseconds thus allowing what ever the race condition is to be resolved.
3. Q: ....
A: widget shifting up and down... Are you using the launchpad theme? Again this is a timing issue and using an alert is a modal type dialog and thus blocks user interaction with the app. I normally use the jimu message dijit instead.
4. Q: Why if I use "closePanel(this.id + '_panel')" instead of closeWidget(this),
I get an unwanted behavior - I do see the alert only on each 2nd click of the widget?
A: I am not sure. I have always had the exact opposite experience. Using closeWidget would sometimes remove the widget but leave the panel still open.
Many thanks, Robert, for enlightening my eyes!
Michael