Mendix Fails to unregister child widget on destroy

3
Dear Mendix Community. Currently am I creating an time selection widget for Mendix 5.14. Within the widget the standard dijit.form.DataTextBox is used. This is fine widget, however when it is loaded in Mendix, it fails to open the data picker menu, after the first time. The second time you click on it you receive an error in the console: Uncaught Error: Tried to register widget with id==box_popup_mddb but that id is already registered I created an simplified working version on js Fiddle: https://jsfiddle.net/L1bq6h7g/ Now again; with mxui.js loaded, the error occurs (open drop down twice). https://jsfiddle.net/L1bq6h7g/1/ The reason that the error occurs is that the popup should be destroyed before it is opened again. This is included in the DataTextBox code, however the destroy does not remove all the ids from the registry. openDropDown: function (_21) { if (this.dropDown) { this.dropDown.destroy(); } var _22 = _5.isString(this.popupClass) ? _5.getObject(this.popupClass, false) : this.popupClass, _23 = this, _24 = this.get("value"); this.dropDown = new _22({onChange: function (_25) { _23.set("value", _25, true); }, id: this.id + "_popup", dir: _23.dir, lang: _23.lang, value: _24, textDir: _23.textDir, currentFocus: !this._isInvalidDate(_24) ? _24 : this.dropDownDefaultValue, constraints: _23.constraints, filterString: _23.filterString, datePackage: _23.datePackage, isDisabledDate: function (_26) { return !_23.rangeCheck(_26, _23.constraints); }}); this.inherited(arguments); } What happens in the Mendix code, that prevents this standard dojo code from functioning? Can anybody help me out in this? Thank you.
asked
3 answers
2

The issue is caused by Mendix who is extending the prototype of dijit widget and overwriting the destroy function. This destroy function tries to destroy all child widgets. But the calendar is generating child widgets that are not registered with this custom Mendix property _supportingWidgets and hence not destroyed.

         "mxui/widget/_Widget": function() {
            define(["dijit/_Widget", "dijit/registry"], 
            function(_Widget, registry ) {
                _Widget.prototype.destroy = function(preserveDom) {
                    if (!this._destroyed) {
                        this._beingDestroyed = true;
                        this.uninitializer && this.uninitializer();
                        try {
                            this.uninitialize();
                        } catch (e) {
                            throw new Error(this.id + ".destroy: Some trouble in uninitialize function: " + e.message);
                        }                            
                        dojo.forEach(this._connects, function(con) {
                            dojo.forEach(con, dojo.disconnect);
                        });
                        dojo.forEach(this._subscribes, function(sub) {
                            dojo.unsubscribe(sub);
                        });
                        dojo.forEach(this._supportingWidgets || [], function(w) {
                            if (w.destroyRecursive) {
                                w.destroyRecursive();
                            } else {
                                if (w.destroy) {
                                    w.destroy();
                                }
                            }
                        });
                        this.destroyRendering(preserveDom);
                        registry.remove(this.id);
                        this._destroyed = true;
                    }
                }; 
            });
        }

@ Mendix Please find a solution for this issue. This approach limits the use of external widgets to build Mendix Custom widgets. (a support ticket 317420)

Extracted Sample in jsfiddle: https://jsfiddle.net/L1bq6h7g/2/

answered
1

Mendix Support:

Our R&D department took a look at the case and told me that this will be fixed in 5.20.

Thank you!

answered
0

Mendix does not immediately destroy widgets but attempts to reuse them by applying another context, when a page is displayed with another object. As DUC BUI suggested, make sure your IDs are unique where necessary.

You do need to include any widget teardown in the destroy method to avoid browser memory leaks.

answered