dojo dijit.Dialog destroy underlay error - javascript

I have a class that extends dijit.Dialog but only to set default functionality and buttons for my site. When clicking the dialog's cancel button the following code is run:
this.actionDialog.destroyRecursive();
this.actionDialog.destroy();
nb this.actionDialog = dijit.Dialog
Sometimes (not always) the following error gets thrown:
Uncaught TypeError: Cannot call method 'destroy' of undefined
DialogUnderlay.xd.js:8
Which causes following dialogs to incorrectly display. I am using 1.5 from Google API's. Am I missing something with the underlay code?
Error thrown after Ken's answer:
exception in animation handler for: onEnd
TypeError: Cannot read property 'style' of null
Both from dojo.xd.js:14. But the code still works properly.

I'm still not entirely sure what the problem is, other than for some reason dijit.DialogUnderlay code is getting confused. FWIW, this doesn't happen in Dojo 1.6.
While I was poking at some potential solutions, I seemed to accidentally find out that avoiding this problem is perhaps as easy as calling hide() on the dialog immediately before destroying it, e.g.:
this.actionDialog.hide();
this.actionDialog.destroyRecursive();
Alternatively, you might be interested in hiding the dialog, then destroying it once the hide animation finishes.
Here's how you can do it on Dojo 1.5 and earlier (tested 1.3+):
dlg.connect(dlg._fadeOut, 'onEnd', function() {
this.destroyRecursive();
});
dlg.hide();
In 1.6, the fadeOut animation is no longer exposed on the instance (granted, it was technically private earlier anyway), but onHide now triggers once the animation ends (whereas before it triggered as soon as it began). Unfortunately a setTimeout is needed to get around an error that occurs due to other code in the branch calling onHide, which assumes that something still exists on the instance which won't after we've destroyed it (see #12436).
dlg.connect(dlg, 'onHide', function() {
setTimeout(function() { dlg.destroyRecursive(); }, 0);
});
dlg.hide();
See it in action on JSFiddle: http://jsfiddle.net/3MNRu/1/ (See the initial version for the original error in the question)

The dialog.hide() method returns a Deferred, your code can be something more readable like this:
var dialog = this.actionDialog;
dialog.hide().then(function(){ dialog.destroyRecursive(); });
Be careful not to do this:
this.actionDialog.hide().then(function(){ this.actionDialog.destroyRecursive(); });
At the context of then this has another meaning!

You only need to call destroyRecursive()
The second destroy command is what is probably causing the error, and the error probably is causing the issues with other dialogs.
http://dojotoolkit.org/api/1.3/dijit/_Widget/destroyRecursive
destroyRecursive
Destroy this widget and it's descendants. This is the generic "destructor" function that all widget users should call to cleanly discard with a widget. Once a widget is destroyed, it's removed from the manager object.

I was getting the IE8 error : 'this.focusNode.form' is null or not an object. I found this was the result of the dialog.hide() returning a deferred. I wrote my own _closeDialog which eliminated the IE error.
_closeDialog : function(cntxt){
cntxt.popup.hide().then(
function(){
cntxt.popup.destroyRecursive(false);
cntxt.popup.destroy(false);
cntxt.destroyRecursive(false);
cntxt.destroy(false);
});
},

Related

Extjs Intermittent error

Using Extjs 4.1, an intermittent error is occurring.
Sometimes it occurs, but most of the time it does not.
It always occurs when I start the application, so I press F5 and everything returns to normal.
Using this reference to debug the error, I noticed that it occurs at line 29590.
The error message is very generic:
Uncaught TypeError: Cannot read property 'dom' of null
at constructor.finishRender (ext-all-debug-w-comments.js:29590)
at constructor.finishRenderItems (ext-all-debug-w-comments.js:39796)
at constructor.finishRender (ext-all-debug-w-comments.js:40889)
at constructor.finishRenderChildren (ext-all-debug-w-comments.js:44526)
at constructor.afterRender (ext-all-debug-w-comments.js:29331)
at constructor.callParent (ext-all-debug-w-comments.js:6194)
at constructor.afterRender (ext-all-debug-w-comments.js:36521)
at constructor.finishRender (ext-all-debug-w-comments.js:29625)
at constructor.finishRenderItems (ext-all-debug-w-comments.js:39796)
at constructor.finishRender (ext-all-debug-w-comments.js:40889)
Here is an error print
What must be causing this?
I would have made this a comment, but it doesn't fit.
There is a wide variety of reasons I could think of. Most of them are based on asynchronous calls. You definitely have to provide more information for the question to be answerable.
Obviously, me.el is null, which it shouldn't be. So first you have to find which component is causing the problem. For this, you should exchange line 29590 against something like this:
try {
me.container = Ext.get(me.el.dom.parentNode);
} catch(e) {
console.log(me.id);
console.log(me.itemId);
console.log(me.xtype);
...
console.log(me);
throw e;
}
This should give you an idea which component(s) would be affected.
Then show us the code of that component. Also check whether you modify that component's config from outside the component, e.g. from a store load operation or other asynchronous tasks. Plus you should look at whether overrides for the component and its ancestors are loaded from separate JS files - maybe they are sometimes loaded before, sometimes after the finishRender has been called, and fix exactly this error.
These are only a few of the possible reasons.

Framework7 - PhotoBrowser onClose function

I am using framework7in my mobile app and I want to PhotoBrowser to display my images.
However, I want to detect when user close the PhotoBrowser so that I can process whatever is needed. In the documentation there is a onClose(photobrowser) callback function. But I am not sure how it works.
Based on the developer's coding conventions, it should be:
myPhotoBrowser.on('close', dosomefucntion());
but error:
myPhotoBrowserPopupDark.on is not a function
I tried
onClose(myPhotoBrowser, dosomefucntion());
and nothing happen, not even error.
I check his other framework SwiperSlider, he seems to use
mySwiper.on('slideChangeStart', function () {
console.log('slide change start 2');
});
to handle the callback function.
What seems to be the issue and how can I resolve this?
what is type property of your photoBrowser? if you set your photoBrowser object type to "page" onClose event won't trigger.
https://github.com/nolimits4web/Framework7/issues/1243

Dojo 'on' event from 'byId' triggers TypeError

I have a module which contains a switch statement producing content, and a variety of on events waiting dependent on what content is inserted into the DOM and then whichever trigger is activated.
I'm finding that on event handlers using dom.byId('foo'):
on(dom.byId('foo'), touch.press, function(e){
produce the error:
Uncaught TypeError: cannot read property 'on' of null.
I can kind of understand this - if the node foo doesn't yet exist because a different switch condition has been satisfied, but i've managed to skirt this by using a css class instead:
on(query('.foo'), touch.press, function(e){
But this has the same chance of existence as the id!
I'm relatively new to Dojo, and have had "fun" getting to grips with it, and i'm interested to know why this is happening, but also if it's a Big Red Flag that i'm doing something wrong!
It's hard to say without the full code but if you want to use query you need to use this way :
require(["dojo/query"], function(query){
query(".foo").on("click", clickHandler);
});
I don't know the context of your project but if it's for mobile you maybe look at "dojo/gesture/tap" like in this exemple in the doc :
define(["dojo/on", "dojo/gesture/tap", function(listen, tap){
on(button, tap, tapHandler);
...

jQuery-UI draggable error 'cannot call methods prior to init', in updating to version 1.10.1

I was working the draggable plugin fine while using jQuery-UI 1.8.2, then I changed to 1.10.1. The major difference I found was that in enabling and disabling the plugin, I no longer needed to use:
$this.draggable('option', 'disabled', true);
but could simply use
$this.draggable('disable');
But then I realized there's another problem. I get this error, which messes up my entire program, and I don't know how to fix it:
Error: cannot call methods on draggable prior to initialization;
attempted to call method 'enable'
To fix it, I ensured that I always call $this.draggable('enable'); before any further options, but it didn't make a difference. What's the problem?
The meaning of your error is : $this.draggable('enable'); is called before $this.draggable();.
Check the execution flow of your progam : make sure that you have indeed initialized the plugin (e.g : called $this.draggable();) before trying to do anything with it.
Expanding on what LeGEC said...
$this.draggable(); is being called before $this.draggable('enable');
For me the solution would be to chain the event like this...
$this.draggable().draggable('disable');
First declaring that $this is a draggable, then declaring that it is dissabled
I had a similar issue when upgrading from jquery 1.6.1 to 1.9.1
var tr$ = $('<tr>', { draggable: 'true' });
threw "cannot call methods on draggable prior to initialization"
modified to:
var tr$ = $('<tr>');
if(!('draggable' in document.createElement('span'))) {
//handle old browsers
} else {
tr$.attr('draggable', 'true');
}
Posting in case it helps someone else to see it this way.

Dojo Calendar Not Destroying On My Connect

Hey all, this is weird. This widget will not destroy onHide. I know the event is firing because I have placed debug code within the function that is ran. I have no idea why this won't work... it is clearly documented in the API. My code is below:
var formitem=new dijit.Calendar({
name:this.formitems.calendaritems[i].id,
id: this.formitems.calendaritems[i].id
},
dojo.create('dd',null,
this.lineitems));
dojo.connect(myself.dialog, 'onHide', function() {
formitem.destroy();
});
I keep getting the error the widget is already registered, however if the destroy function is supposed to work correctly then it is supposed to destroy the instance of it. Please help.
"the widget is already registered" error results from using a ID that's already been used. If you have to set the id, ensure that you never use the same one twice. But I would just remove that line where you set the id. Somewhere along the line you are recreating the Calendar. It's possible that you are deleting it as expected but its trying to recreate.
Note this is a bit of guess, since the example seems to be missing code that is relevant to your problem.

Categories