views:

6529

answers:

2

I've got a popup window that gives data back to its parent. Using window.opener.document.data = data_from_popup;

This work well in FF, but in IE (6/7) the data can be accessed for the time the popup is still displayed. When I close the popup it looks like the data gets garbage collected.

I've tried to use a clone() function for the data received from the popup :

window.opener.add_data(data_from_popup);

and in the parent :

function add_data(data_from_popup) {
 data = clone(data_from_popup); 
}

It somewhat works, but in certain conditions the clone() function seems to recurse infinitely.

Have you ever experienced the same thing, and is there a way to prevent that without using a clone function?

+2  A: 

Not sure exactly what you are experiencing, but I have successfully stored data on the opener from the child popup on a regular basis in IE (6,7 & 8) in development and production applications.

do you have a URL or some more source code that you can provide?

on a related note... you aren't trying to determine the type of an object on the opener... from the popup are you? - there's some known IE bugs in this area.

Update:

Here's a quick example...

<!--main window-->
<script>
  function getThing(id){
    url = 'http://mysite.com/...whatever...';
    features = 'locationbar=X,menubar=Y...';
    window['popup4'+id] = open(url, 'someNameWithoutSpaces', features);
  }
  function popupCallback(data){
    alert('I got data back! ' + data);
    document.getElementById('someID').innerHTML = '<b>' + data.label + ' (' + data.id + ')</b>';
    //close the popup (now that we have/are done with the data)
    window['popup4someID'].close();
  }
</script>
<div id="someID">{Nothing Selected Yet}</div>
<input type="button" value="Pick One" onclick="getThing('someID');"/>

<!--popup window-->
<script>
  function saveSelection(){
    //acquire data however you want/need
    var selData = {};
    selData.id = 123456;
    selData.label = 'iPod Touch (Jeff Atwood Edition)';
    //call callback on opener
    window.opener.popupCallback(selData);
  }
</script>

Update 2

In testing it appears that in IE7,IE8 (but not IE6) after the popup window is closed, any reference data is lost (the references don't capture a snapshot) thus if you need the data after the popup is closed, you will need to clone it.

I thought if the data can be wrapped in an Array, cloning is a piece of cake. Just call .slice() on it to copy it, but... that doesn't work either!

I guess you'll need to save the values out that you need (either to form elements, or the DOM) since IE doesn't look like it will let you use them after the popup closes. :-(

scunliffe
How did you store data on the opener? Specifically, did you store complex data (objects, arrays, dates) via window.opener?
Crescent Fresh
I've used 2 things. 1 window.opener.foo = somevalue; whereby this stores a global variable "foo" on the opening window. Or I'll open a popup window and call a callback... say window.opener.myCallback(someDataObj); where my opener callback function does whatever it wants/needs with the data.
scunliffe
Interesting. Those two examples are what break in IE. When the user closes the child window, the opener's reference to the data is just f***ed.
JPot
That is, references to complex data types (objects, arrays, dates) are f***ed. Scalar types (strings, Numbers, bools) are fine.
JPot
Yes I'm trying to pass complex data to the parent window. So just copying it will fail, and cloning it will fail too, probably because we're trying to determine the type of the object in the clone function.So is there a proper way to do this, like json encoding the object into a string and decoding on the parent side ?
mtourne
if you try the updated code above it should work with any data you pass it.
scunliffe
The subtle difference between the OP's example and your sample code is that you are not storing a reference to the data in the opener, but rather plucking properties to show in the DOM. If you were to change it to `function popupCallback(data) { self.data = data }`, and close the child window, you'd notice your reference was clobbered in IE.
Crescent Fresh
thanks crescentfresh - I'm pretty sure if in my callback function I do a window.someVar = data; that I will be able to save the data... that said I haven't checked that recently so I will do so and post a workaround if there are any issues.
scunliffe
Well I'll be darned! once the popup closes IE7/IE8 throw away the data and give this error when you try to access it: "Message: The object invoked has disconnected from its clients." It still seems to work in IE6 though. I guess you've found a valid need to clone... ;-)
scunliffe
+1  A: 

The way I finally did it is by json encoding the complex object I wanted to pass to the parent in the popup window. The data passed back is then a simple string and can be copied without problem. On the parent side the json encoded string is evaluated to a Javascript object.

mtourne