javascript - showModalDialog not returning value in Chrome

ConnorsFan picture ConnorsFan · Apr 18, 2012 · Viewed 31.6k times · Source

I made a small calendar popup in Javascript. Very simple, using the Calendar control from ASP.NET. I call the popup window with showModalDialog. In the modal window, changing the current month of the calendar causes problems because of the postback, and I found in several places that the solution is to put:

<base target="_self"/>

in the head part of the aspx file. Everything works great... except for one thing, and only in Google Chrome. To get back the selected date, I set the returnValue of the popup to the date selected in the calendar. In IE and Firefox, it always works. In Chrome, however, it works only if I don't change the current month in the calendar. As soon as I change it, the return value is not passed back to the caller of showModalDialog. It is as if the modal window is not the original one anymore; the return value is undefined.

Has anyone experienced that behavior and have a suggestion to make it work? I tried using dialogArguments to keep trace of the caller window but it gets passed only to the first modal window (it is lost after changing the current month).

The code in the calling procedure:

var d = window.showModalDialog(...)

The code in the modal window:

window.returnValue = selectedDate; 
self.close();

As I said to Teemu, selectedDate and window.returnValue are both always correct. However, in the case of Google Chrome (after a month change in the calendar), returnValue is not passed back by showModalDialog and d is undefined.

Answer

ConnorsFan picture ConnorsFan · Apr 19, 2012

In order to keep using showModalDialog in my page, I had to come up with my own workaround for the bug. So, here it is...

In Google Chrome, after a postback, showModalDialog always returns undefined. However, the window.opener property in the modal dialog points to the caller window, even after postbacks. So, I thought about putting the result of the dialog in the returnValue property of that caller window. And it works.

In the caller window:

var prevReturnValue = window.returnValue; // Save the current returnValue
window.returnValue = undefined;
var dlgReturnValue = window.showModalDialog(...);
if (dlgReturnValue == undefined) // We don't know here if undefined is the real result...
{
    // So we take no chance, in case this is the Google Chrome bug
    dlgReturnValue = window.returnValue;
}
window.returnValue = prevReturnValue; // Restore the original returnValue

At this point, use dlgReturnValue for further processing

In the modal dialog window:

if (window.opener)
{
    window.opener.returnValue = dateValue;
}
window.returnValue = dateValue;
self.close();