View Full Version : Cannot setup a Keymap with an iframe

16 Apr 2007, 11:18 AM
Hello all, this is my very first post. First of all, I am in awe of ext-js. It is well designed, easy to use, easy to blend with other libraries (even home-brewed). Thanks Jack, it has been a pleasure to dive into your source to learn how it works.

I am having an issue trying to setup global hotkeys for a page that contains an iframe. I am attempting to bind a keymap to the main document and another one to the iframe's contentDocument. Everything's well when I bind it to document, but when I try to to bind it to the iframe's document I get an exception saying:

this.el has no properties
Error Line: this.el.on(this.eventName, this.keyDownDelegate);

I have already made sure that I am passing a valid document object by printing it out to firebug's console.

There's an easy way to reproduce this problem:

Go to http://extjs.com/deploy/ext/docs/index.html (Using FF and Firebug)

Try to bind 'n' to the documentation iframe by typing the following into the console:

new Ext.KeyMap(document.getElementById('main').contentDocument,{ key: 'n', fn: function() {console.log("Hit n")}})

Notice that it doesn't work. If you pass it the standard document object, it works fine.

I've tracked this down to the following lines in El.get().

}else if(el == document){

var f = function(){};
f.prototype = El.prototype;
docEl = new f();
docEl.dom = document;
return docEl;
return null;

That seems to create a global element to use when a document is passed in. However, if we pass a different document (iframe's), it will fall out and return null which is what is causing the 'has no properties' error.

I am trying to see what can be done to workaround this but I figured I'd post it here in case anyone has some ideas.


16 Apr 2007, 2:00 PM
Soooo....... my post is not considered a bug and got moved to HELP? Sorry, it seemed like a bug to me since I showed an example that should work but didn't. Is it possible that whoever moved it can tell me why it's not a bug?

In any case, I've come up with a hackaround for El.get to work with multiple document elements, it's probably not ideal and I certainly don't want to keep my modifed version of ext-all.js.

A few points that I think are relevant to point out before trying to fix this:

El.get only accepts the main document (the one where Ext is loaded). Any other documents (from iframes) return null when passed to El.get.

El.get caches the Element it creates for the document as a global variable, assuming there will be only for the page.

My proposed solution is to have a separate cache for document objects wrapped as elements. Here it is -- replace the last else block (if (el == document){}) in El.get with:

else if (el.location) {
el.docId = el.docId || Ext.id(el);
// El.docCache was initialized at the same place as El.cache
var xdoc = El.docCache[el.docId];
if(!xdoc) {
var f = function(){};
f.prototype = El.prototype;
xdoc = new f();
xdoc.dom = el;
return xdoc;

Thanks again.