showModalDialog returnValue is undefined in Google Chrome.. in Sitecore

DatasetTemplateField

I have a custom field type which has its own custom editor dialog window (much like the Rich Text editor window). When users want to edit the field, they click “Show Editor” button above the field. The modal dialog editor window opens..

DatasetTemplateEditorModal

they make their changes.. and then close the window which saves the new field value back to the Content Editor field. No problem!

Enter… Chrome!

This works great in IE, however there were reports of problems in Google Chrome. The issue was that the new value from the modal dialog was not updating the field value in Content Editor after the user clicked “OK”. Weird…

Well, after a lot of digging, I found the reason.. actually a few reasons. But before I get into that.. a quick look at how the dialog saves the value back to Content Editor.

Basically, in the “OK” button postback, I use ClientScriptManager.RegisterStartupScript to return some javascript to run. This javascript is basically:

window.returnValue = "the new value of my field";

I had created this modal dialog a few years ago, and at the time I guess I wasn’t overly concerned if it would work in any other browsers besides IE.

Using Chrome’s “Developer Tools” (F12), I was able to see that the value (in window.returnValue) returned to the Content Editor page was “undefined”. It seems this is in fact a well known issue with Chrome. Luckily, there were plenty of workarounds. Such as this one by Brian Pedersen.

  if (window.opener) {
    window.opener.returnValue = "your return value";
  }
  window.returnValue = "your return value";
  self.close();

Unfortunately, this didn’t work for me in Sitecore. When running Content Editor in Chrome, it uses /sitecore/shell/controls/Gecko.js to handle showing modal dialogs… (as opposed to /sitecore/shell/controls/InternetExplorer.js when using IE).

From Gecko.js:

scBrowser.prototype.showModalDialog = function(url, arguments, features, request) {
  window.top.returnValue = null;

  showModalDialog(url, arguments, features);

  var result = window.top.returnValue;

  if (request != null) {
    // When we close modal dialog, many commands expect 'undefined' (not 'null') result (since IE returns 'undefined' )
    request.dialogResult = result == null ? undefined : result;
  }

  return result;
}

As you can see, its looking for window.top.returnValue instead of window.returnValue. So, I changed Brian’s code just slightly and viola! It worked:

  if (window.opener) {
    window.opener.top.returnValue = "your return value";
  }
  window.returnValue = "your return value";
  self.close();

Happy Coding!

Advertisements

About Paul Martin

I enjoy rock climbing, playing guitar, writing code...
This entry was posted in Field Editor, Field Types, Sitecore and tagged , . Bookmark the permalink.

2 Responses to showModalDialog returnValue is undefined in Google Chrome.. in Sitecore

  1. vsrathore2 says:

    Hi Paul,

    I’m also building a custom field(which will post the media to CDN,instead of storing to Sitecore),but do not know how I can save the value in that field.
    Can you please provide me the source code for above example,s oI can get some help.
    Also see my post on SDN for the same problem this http://sdn.sitecore.net/forum//ShowPost.aspx?PostID=64021

    -Regards,
    Vikram

    • Paul Martin says:

      My dialog window is “saved” by clicking the OK button. This postback is handled in my code-behind by the btnOK_Click event handler. That handler then sets the window value using javascript and then closes the window.

              protected void btnOK_Click(object sender, EventArgs e)
              {
                  var value = StringUtil.EscapeJavascriptString(txtTemplate.Text);
                  // Use window.opener to work-around chrome bug... http://stackoverflow.com/questions/10213530/javascript-showmodaldialog-not-returning-value-in-chrome
                  var script = @"if (window.opener)
                                 {
                                     window.opener.top.returnValue = " + value + @";
                                 }
                                 window.returnValue = " + value + ";";
      
                  this.ClientScript.RegisterStartupScript(this.GetType(), "SetDialogValue", script, true);
                  CloseWindow();
              }
      
              protected void btnCancel_Click(object sender, EventArgs e)
              {
                  CloseWindow();
              }
      
              private void CloseWindow()
              {
                  this.ClientScript.RegisterStartupScript(this.GetType(), "CloseWindow", "window.close();", true);
              }
      

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s