[javascript] How can I make window.showmodaldialog work in chrome 37?

We have a huge web application where we use window.showmodaldialog for alerts, confirmations and popups. Since Chrome version 37 this call has been disabled.

Is there any quick workaround to make window.showmodaldialog work in the latest version of Chrome?

I am adding here a workaround for window.showmodaldialog, although this is not a perfect workaround because this will not break the code execution as showmodaldialog was doing, instead this will open the popups.

window.showModalDialog = function (url, arg, feature) {
        var opFeature = feature.split(";");
       var featuresArray = new Array()
        if (document.all) {
           for (var i = 0; i < opFeature.length - 1; i++) {
                var f = opFeature[i].split("=");
               featuresArray[f[0]] = f[1];
            }
       }
        else {

            for (var i = 0; i < opFeature.length - 1; i++) {
                var f = opFeature[i].split(":");
               featuresArray[f[0].toString().trim().toLowerCase()] = f[1].toString().trim();
            }
       }



       var h = "200px", w = "400px", l = "100px", t = "100px", r = "yes", c = "yes", s = "no";
       if (featuresArray["dialogheight"]) h = featuresArray["dialogheight"];
        if (featuresArray["dialogwidth"]) w = featuresArray["dialogwidth"];
       if (featuresArray["dialogleft"]) l = featuresArray["dialogleft"];
        if (featuresArray["dialogtop"]) t = featuresArray["dialogtop"];
        if (featuresArray["resizable"]) r = featuresArray["resizable"];
       if (featuresArray["center"]) c = featuresArray["center"];
      if (featuresArray["status"]) s = featuresArray["status"];
        var modelFeature = "height = " + h + ",width = " + w + ",left=" + l + ",top=" + t + ",model=yes,alwaysRaised=yes" + ",resizable= " + r + ",celter=" + c + ",status=" + s;

        var model = window.open(url, "", modelFeature, null);

       model.dialogArguments = arg;

    }

Just put this code in the head section of page.

This question is related to javascript jquery asp.net google-chrome cross-browser

The answer is


The window.showModalDialog is deprecated (Intent to Remove: window.showModalDialog(), Removing showModalDialog from the Web platform). [...]The latest plan is to land the showModalDialog removal in Chromium 37. This means the feature will be gone in Opera 24 and Chrome 37, both of which should be released in September.[...]


From http://codecorner.galanter.net/2014/09/02/reenable-showmodaldialog-in-chrome/

It's deprecated by design. You can re-enable showModalDialog support, but only temporarily – until May of 2015. Use this time to create alternative solutions.

Here’s how to do it in Chrome for Windows. Open Registry Editor (regedit) and create following key:

HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome\EnableDeprecatedWebPlatformFeatures

Under the EnableDeprecatedWebPlatformFeatures key create a string value with name 1 and value of ShowModalDialog_EffectiveUntil20150430. To verify that the policy is enabled, visit chrome://policy URL.


UPDATE: If the above didn’t work for you here’s another method to try.

  1. Download Chrome ADM templates from http://www.chromium.org/administrators/policy-templates
  2. Extract and import policy relevant to your locale (e.g. windows\adm\en-US\chrome.adm. You can import either via gpedit.mscor using these utilities on Home editions of windows: http://blogs.technet.com/b/fdcc/archive/2008/05/07/lgpo-utilities.aspx)
  3. Under “Adminstrative Templates” locate Google Chrome template and enable “Enable Deprecated Web Platform Feautes”.
  4. Open the feature and add “ShowModalDialog_EffectiveUntil20150430" key.


I put the following javascript in the page header and it seems to work. It detects when the browser does not support showModalDialog and attaches a custom method that uses window.open, parses the dialog specs (height, width, scroll, etc.), centers on opener and sets focus back to the window (if focus is lost). Also, it uses the URL as the window name so that a new window is not opened each time. If you are passing window args to the modal you will need to write some additional code to fix that. The popup is not modal but at least you don't have to change a lot of code. Might need some work for your circumstances.

<script type="text/javascript">
  // fix for deprecated method in Chrome 37
  if (!window.showModalDialog) {
     window.showModalDialog = function (arg1, arg2, arg3) {

        var w;
        var h;
        var resizable = "no";
        var scroll = "no";
        var status = "no";

        // get the modal specs
        var mdattrs = arg3.split(";");
        for (i = 0; i < mdattrs.length; i++) {
           var mdattr = mdattrs[i].split(":");

           var n = mdattr[0];
           var v = mdattr[1];
           if (n) { n = n.trim().toLowerCase(); }
           if (v) { v = v.trim().toLowerCase(); }

           if (n == "dialogheight") {
              h = v.replace("px", "");
           } else if (n == "dialogwidth") {
              w = v.replace("px", "");
           } else if (n == "resizable") {
              resizable = v;
           } else if (n == "scroll") {
              scroll = v;
           } else if (n == "status") {
              status = v;
           }
        }

        var left = window.screenX + (window.outerWidth / 2) - (w / 2);
        var top = window.screenY + (window.outerHeight / 2) - (h / 2);
        var targetWin = window.open(arg1, arg1, 'toolbar=no, location=no, directories=no, status=' + status + ', menubar=no, scrollbars=' + scroll + ', resizable=' + resizable + ', copyhistory=no, width=' + w + ', height=' + h + ', top=' + top + ', left=' + left);
        targetWin.focus();
     };
  }
</script>

Create a cross browser ModalDialog

function _showModalDialog(url, width, height, closeCallback) {
    var modalDiv,
        dialogPrefix = window.showModalDialog ? 'dialog' : '',
        unit = 'px',
        maximized = width === true || height === true,
        w = width || 600,
        h = height || 500,
        border = 5,
        taskbar = 40, // windows taskbar
        header = 20,
        x,
        y;

    if (maximized) {
        x = 0;
        y = 0;
        w = screen.width;
        h = screen.height;
    } else {
        x = window.screenX + (screen.width / 2) - (w / 2) - (border * 2);
        y = window.screenY + (screen.height / 2) - (h / 2) - taskbar - border;
    }

    var features = [
            'toolbar=no',
            'location=no',
            'directories=no',
            'status=no',
            'menubar=no',
            'scrollbars=no',
            'resizable=no',
            'copyhistory=no',
            'center=yes',
            dialogPrefix + 'width=' + w + unit,
            dialogPrefix + 'height=' + h + unit,
            dialogPrefix + 'top=' + y + unit,
            dialogPrefix + 'left=' + x + unit
        ],
        showModal = function (context) {
            if (context) {
                modalDiv = context.document.createElement('div');
                modalDiv.style.cssText = 'top:0;right:0;bottom:0;left:0;position:absolute;z-index:50000;';
                modalDiv.onclick = function () {
                    if (context.focus) {
                        context.focus();
                    }
                    return false;
                }
                window.top.document.body.appendChild(modalDiv);
            }
        },
        removeModal = function () {
            if (modalDiv) {
                modalDiv.onclick = null;
                modalDiv.parentNode.removeChild(modalDiv);
                modalDiv = null;
            }
        };

    // IE
    if (window.showModalDialog) {
        window.showModalDialog(url, null, features.join(';') + ';');

        if (closeCallback) {
            closeCallback();
        }
    // Other browsers
    } else {
        var win = window.open(url, '', features.join(','));
        if (maximized) {
            win.moveTo(0, 0);
        }

        // When charging the window.
        var onLoadFn = function () {
                showModal(this);
            },
            // When you close the window.
            unLoadFn = function () {
                window.clearInterval(interval);
                if (closeCallback) {
                    closeCallback();
                }
                removeModal();
            },
            // When you refresh the context that caught the window.
            beforeUnloadAndCloseFn = function () {
                try {
                    unLoadFn();
                }
                finally {
                    win.close();
                }
            };

        if (win) {
            // Create a task to check if the window was closed.
            var interval = window.setInterval(function () {
                try {
                    if (win == null || win.closed) {
                        unLoadFn();
                    }
                } catch (e) { }
            }, 500);

            if (win.addEventListener) {
                win.addEventListener('load', onLoadFn, false);
            } else {
                win.attachEvent('load', onLoadFn);
            }

            window.addEventListener('beforeunload', beforeUnloadAndCloseFn, false);
        }
    }
}

Yes, It's deprecated. Spent yesterday rewriting code to use Window.open and PostMessage instead.


This article (Why is window.showModalDialog deprecated? What to use instead?) seems to suggest that showModalDialog has been deprecated.


I wouldn't try to temporarily enable a deprecated feature. According to the MDN documentation for showModalDialog, there's already a polyfill available on Github.

I just used that to add windows.showModalDialog to a legacy enterprise application as a userscript, but you can obviously also add it in the head of the HTML if you have access to the source.


The window.returnValue property does not work directly when you are opening a window using window.open() while it does work when you are using window.showModalDialog()

So in your case you have two options to achieve what you are trying to do.

Option 1 - Using window.showModalDialog()

In your parent page

var answer = window.showModalDialog(<your page and other arguments>)
if (answer == 1)
 { do some thing with answer }

and inside your child page you can make use of the window.returnValue directly like

window.returnValue = 'value that you want to return';

showModalDialog halts the executions of the JavaScript until the dialog box is closed and can get a return value from the opened dialog box when its closing.But the problem with showModalDialog is that it is not supported on many modern browsers. In contrast window.open just opens a window asynchronously (User can access both the parent window and the opened window). And the JavaScript execution will continue immediately. Which bring us to Option 2

Option 2 - Using window.open() In your parent page write a function that deals with opening of your dialog.

function openDialog(url, width, height, callback){
if(window.showModalDialog){
    options = 'dialogHeight: '+ height + '; dialogWidth: '+ width + '; scroll=no'
    var returnValue = window.showModalDialog(url,this,options);
    callback(returnValue)
}
else {
    options ='toolbar=no, directories=no, location=no, status=yes, menubar=no, resizable=yes, scrollbars=no, width=' + width + ', height=' + height; 
        var childWindow = window.open(url,"",options);
        $(childWindow).on('unload',function(){
            if (childWindow.isOpened == null) {
                childWindow.isOpened = 1;
            }
            else {
                if(callback){
                    callback(childWindow.returnValue);
                }
            }
        });
}

}

And whenever you want to use open a dialog. Write a callback that deals with the return value and pass it as a parameter to openDialog function

function callback(returnValue){
if(returnValue){
    do something nice with the returnValue
}}

And when calling the function

openDialog(<your page>, 'width px', 'height px', callbak);

Check out an article on how to replace window.showModalDialog with window.open


A very good, and working, javascript solution is provided here : https://github.com/niutech/showModalDialog

I personnally used it, works like before for other browser and it creates a new dialog for chrome browser.

Here is an example on how to use it :

function handleReturnValue(returnValue) {
    if (returnValue !== undefined) {
        // do what you want
    }
}

var myCallback = function (returnValue) { // callback for chrome usage
    handleReturnValue(returnValue);
};

var returnValue = window.showModalDialog('someUrl', 'someDialogTitle', 'someDialogParams', myCallback); 
handleReturnValue(returnValue); // for other browsers except Chrome

    (function() {
        window.spawn = window.spawn || function(gen) {
            function continuer(verb, arg) {
                var result;
                try {
                    result = generator[verb](arg);
                } catch (err) {
                    return Promise.reject(err);
                }
                if (result.done) {
                    return result.value;
                } else {
                    return Promise.resolve(result.value).then(onFulfilled, onRejected);
                }
            }
            var generator = gen();
            var onFulfilled = continuer.bind(continuer, 'next');
            var onRejected = continuer.bind(continuer, 'throw');
            return onFulfilled();
        };
        window.showModalDialog = window.showModalDialog || function(url, arg, opt) {
            url = url || ''; //URL of a dialog
            arg = arg || null; //arguments to a dialog
            opt = opt || 'dialogWidth:300px;dialogHeight:200px'; //options: dialogTop;dialogLeft;dialogWidth;dialogHeight or CSS styles
            var caller = showModalDialog.caller.toString();
            var dialog = document.body.appendChild(document.createElement('dialog'));
            dialog.setAttribute('style', opt.replace(/dialog/gi, ''));
            dialog.innerHTML = '<a href="#" id="dialog-close" style="position: absolute; top: 0; right: 4px; font-size: 20px; color: #000; text-decoration: none; outline: none;">&times;</a><iframe id="dialog-body" src="' + url + '" style="border: 0; width: 100%; height: 100%;"></iframe>';
            document.getElementById('dialog-body').contentWindow.dialogArguments = arg;
            document.getElementById('dialog-close').addEventListener('click', function(e) {
                e.preventDefault();
                dialog.close();
            });
            dialog.showModal();
            //if using yield
            if(caller.indexOf('yield') >= 0) {
                return new Promise(function(resolve, reject) {
                    dialog.addEventListener('close', function() {
                        var returnValue = document.getElementById('dialog-body').contentWindow.returnValue;
                        document.body.removeChild(dialog);
                        resolve(returnValue);
                    });
                });
            }
            //if using eval
            var isNext = false;
            var nextStmts = caller.split('\n').filter(function(stmt) {
                if(isNext || stmt.indexOf('showModalDialog(') >= 0)
                    return isNext = true;
                return false;
            });
            dialog.addEventListener('close', function() {
                var returnValue = document.getElementById('dialog-body').contentWindow.returnValue;
                document.body.removeChild(dialog);
                nextStmts[0] = nextStmts[0].replace(/(window\.)?showModalDialog\(.*\)/g, JSON.stringify(returnValue));
                eval('{\n' + nextStmts.join('\n'));
            });
            throw 'Execution stopped until showModalDialog is closed';
        };
    })()

;

**Explanation:
------------**
The best way to deal with showModalDialog for older application conversions is use to `https://github.com/niutech/showModalDialog` inorder to work with show modal dialogs  and if modal dailog has ajax calls you need to create object and set the parameters of function to object and pass below...before that check for browser and set the useragent...example: agentStr = navigator.userAgent; and then check for chrome

var objAcceptReject={}; // create empty object and set the parameters to object and send to the other functions as dialog when opened in chrome breaks the functionality
    function rejectClick(index, transferId) {
        objAcceptReject.index=index;
        objAcceptReject.transferId=transferId;

     agentStr = navigator.userAgent;

                var msie = ua.indexOf("MSIE ");

                if (msie > 0) // If Internet Explorer, return version number
                {
                    var ret = window.showModalDialog("/abc.jsp?accept=false",window,"dialogHeight:175px;dialogWidth:475px;scroll:no;status:no;help:no");   

                    if (ret=="true") {
                        doSomeClick(index);
                    }

                } else if ((agentStr.indexOf("Chrome")) >- 1){
                spawn(function() {

                    var ret = window.showModalDialog("/abcd.jsp?accept=false",window,"dialogHeight:175px;dialogWidth:475px;scroll:no;status:no;help:no");   

                    if (ret=="true") {// create an object and store values in objects and send as parameters
                        doSomeClick(objAcceptReject.index);
                    }

                });

                }
                else {
                    var ret = window.showModalDialog("/xtz.jsp?accept=false",window,"dialogHeight:175px;dialogWidth:475px;scroll:no;status:no;help:no");   

                    if (ret=="true") {
                        doSomeClick(index);
                    }
                }

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to jquery

How to make a variable accessible outside a function? Jquery assiging class to th in a table Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Getting all files in directory with ajax Bootstrap 4 multiselect dropdown Cross-Origin Read Blocking (CORB) bootstrap 4 file input doesn't show the file name Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource how to remove json object key and value.?

Examples related to asp.net

RegisterStartupScript from code behind not working when Update Panel is used You must add a reference to assembly 'netstandard, Version=2.0.0.0 No authenticationScheme was specified, and there was no DefaultChallengeScheme found with default authentification and custom authorization How to use log4net in Asp.net core 2.0 Visual Studio 2017 error: Unable to start program, An operation is not legal in the current state How to create roles in ASP.NET Core and assign them to users? How to handle Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause() ASP.NET Core Web API Authentication Could not load file or assembly 'CrystalDecisions.ReportAppServer.CommLayer, Version=13.0.2000.0 WebForms UnobtrusiveValidationMode requires a ScriptResourceMapping for jquery

Examples related to google-chrome

SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 81 SameSite warning Chrome 77 What's the net::ERR_HTTP2_PROTOCOL_ERROR about? session not created: This version of ChromeDriver only supports Chrome version 74 error with ChromeDriver Chrome using Selenium Jupyter Notebook not saving: '_xsrf' argument missing from post How to fix 'Unchecked runtime.lastError: The message port closed before a response was received' chrome issue? Selenium: WebDriverException:Chrome failed to start: crashed as google-chrome is no longer running so ChromeDriver is assuming that Chrome has crashed WebDriverException: unknown error: DevToolsActivePort file doesn't exist while trying to initiate Chrome Browser How to make audio autoplay on chrome How to handle "Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first." on Desktop with Chrome 66?

Examples related to cross-browser

Show datalist labels but submit the actual value Stupid error: Failed to load resource: net::ERR_CACHE_MISS Click to call html How to Detect Browser Back Button event - Cross Browser How can I make window.showmodaldialog work in chrome 37? Cross-browser custom styling for file upload button Flexbox and Internet Explorer 11 (display:flex in <html>?) browser sessionStorage. share between tabs? How to know whether refresh button or browser back button is clicked in Firefox CSS Custom Dropdown Select that works across all browsers IE7+ FF Webkit