show-modal-dialog

在原使用 ASP.NET 開發的網頁中,使用 window.showModalDialog 開啟查詢子視窗,再傳回查詢結果。但是 window.showModalDialog 在新版的瀏覽器,如 Firefox 或 Chrome,已被移除。只好繞彎,改用 jQuery UI 來達成。

參考:showModalDialog jquery plugin,其原始文章為 window.showModalDialog() - Cross Browser, new version。

showModalDialog.js 如下:

// Based on this article: http://extremedev.blogspot.com/2011/03/windowshowmodaldialog-cross-browser-new.html
/*
Usage example:
var url = 'test.html';
$.showModalDialog({
     url: url,
     height: 500,
     width: 900,
     scrollable: false,
     onClose: function(){ var returnedValue = this.returnValue; }
});
UPDATE August 2012: Looks like there is a problem when setting DocType: HTML 4.01 Doctype on top of extremedevStart.html. --> The popup does not close.
To fix this use:
$dlg.dialogWindow.dialog('close');
instead of:
window.close();
*/
var $dialog = null;
jQuery.showModalDialog = function (options) {
    var defaultOptns = {
        url: null,
        dialogArguments: null,
        height: 'auto',
        width: 'auto',
        position: 'center',
        resizable: true,
        scrollable: true,
        onClose: function () { },
        returnValue: null,
        doPostBackAfterCloseCallback: false,
        postBackElementId: null
    };
    var fns = {
        close: function () {
            opts.returnValue = $dialog.returnValue;
            $dialog = null;
            opts.onClose();
            if (opts.doPostBackAfterCloseCallback) {
                postBackForm(opts.postBackElementId);
            }
        },
        adjustWidth: function () { $frame.css("width", "100%"); }
    };
    // build main options before element iteration
    var opts = $.extend({}, defaultOptns, options);
    var $frame = $('<iframe id="iframeDialog" />');
    if (opts.scrollable)
        $frame.css('overflow', 'auto');
    $frame.css({
        'padding': 0,
        'margin': 0,
        'padding-bottom': 10
    });
    var $dialogWindow = $frame.dialog({
        autoOpen: true,
        modal: true,
        width: opts.width,
        height: opts.height,
        resizable: opts.resizable,
        position: opts.position,
        overlay: {
            opacity: 0.5,
            background: "black"
        },
        close: fns.close,
        resizeStop: fns.adjustWidth
    });
    $frame.attr('src', opts.url);
    fns.adjustWidth();
    $frame.load(function () {
        if ($dialogWindow) {
            var maxTitleLength = 50;
            var title = $(this).contents().find("title").html();
            if (title.length > maxTitleLength) {
                title = title.substring(0, maxTitleLength) + '...';
            }
            $dialogWindow.dialog('option', 'title', title);
        }
    });
    $dialog = new Object();
    $dialog.dialogArguments = opts.dialogArguments;
    $dialog.dialogWindow = $dialogWindow;
    $dialog.returnValue = null;
}
//function postBackForm(targetElementId) {
//    var theform;
//    theform = document.forms[0];
//    theform.__EVENTTARGET.value = targetElementId;
//    theform.__EVENTARGUMENT.value = "";
//    theform.submit();
//}
var prntWindow = getParentWindowWithDialog(); //$(top)[0];
var $dlg = prntWindow && prntWindow.$dialog;
function getParentWindowWithDialog() {
    var p = window.parent;
    var previousParent = p;
    while (p != null) {
        if ($(p.document).find('#iframeDialog').length) return p;
        p = p.parent;
        if (previousParent == p) return null;
        // save previous parent
        previousParent = p;
    }
    return null;
}
function setWindowReturnValue(value) {
    if ($dlg) $dlg.returnValue = value;
    window.returnValue = value; // in case popup is called using showModalDialog
}
function getWindowReturnValue() {
    // in case popup is called using showModalDialog
    if (!$dlg && window.returnValue != null)
        return window.returnValue;
    return $dlg && $dlg.returnValue;
}
if ($dlg) window.dialogArguments = $dlg.dialogArguments;
if ($dlg) window.close = function () { if ($dlg) $dlg.dialogWindow.dialog('close'); };
function CloseWindow() {
    if ($dlg) {
        $dlg.dialogWindow.dialog('close');
    } else {
        ForceCloseWindow();
    }
}
function ForceCloseWindow() {
    var browserName = navigator.appName;
    var browserVer = parseInt(navigator.appVersion);
    //alert(browserName + " : "+browserVer);
    //document.getElementById("flashContent").innerHTML = "<br>&nbsp;<font face='Arial' color='blue' size='2'><b> You have been logged out of the Game. Please Close Your Browser Window.</b></font>";
    if (browserName == "Microsoft Internet Explorer") {
        var ie7 = (document.all && !window.opera && window.XMLHttpRequest) ? true : false;
        if (ie7) {
            //This method is required to close a window without any prompt for IE7 & greater versions.
            window.open('', '_parent', '');
            window.close();
        }
        else {
            //This method is required to close a window without any prompt for IE6
            this.focus();
            self.opener = this;
            self.close();
        }
    } else {
        //For NON-IE Browsers except Firefox which doesnt support Auto Close
        try {
            this.focus();
            self.opener = this;
            self.close();
        }
        catch (e) {
        }
        try {
            window.open('', '_self', '');
            window.close();
        }
        catch (e) {
        }
    }
}

要使用此功能,必須先載入 jQuery 及 jQuery UI。主程式範例如下

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Show Modal Dialog Test</title>
  <link rel="stylesheet" type="text/css" href="css/ui-lightness/jquery-ui-1.10.4.custom.min.css">
</head>
<body>
<h1>Show Modal Dialog Test</h1>
課號: <span id='txt-cono'></span><br><br>
<button id="btn-query">查詢</button>
<script type="text/javascript" src="js/jquery-1.10.2.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.10.4.custom.min.js"></script>
<script type="text/javascript" src="js/showModalDialog.js"></script>
<script type="text/javascript">
$('#btn-query').click(function()
{
    var url = 'popup-test.html';
    $.showModalDialog({
        url: url,
        dialogArguments: '課程資料查詢',
        height: 500,
        width: 900,
        scrollable: false,
        onClose: function()
        {
            var returnedValue = this.returnValue;
            $('#txt-cono').text(returnedValue.cono);
        }
    });
});
</script>
</body>
</html>

popup-test.html 原始程式如下。

<!DOCTYPE html>
<html>
<head>
  <title>Popup Target</title>
</head>
<body>
<h1 id='h1-title'></h1>
<table>
  <tr>
    <td><button data-cono="004 40110">傳回</button></td><td>004 40110</td>
  </tr><tr>
    <td><button data-cono="004 M0130">傳回</button></td><td>004 M0130</td>
  </tr><tr>
    <td><button data-cono="222ED5010">傳回</button></td><td>222ED5010</td>
  </tr><tr>
    <td><button data-cono="323EU2260">傳回</button></td><td>323EU2260</td>
  </tr>
</table>
<script type="text/javascript" src="js/jquery-1.10.2.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.10.4.custom.min.js"></script>
<script type="text/javascript" src="js/showModalDialog.js"></script>
<script type="text/javascript">
$(document).ready(function()
{
   $('#h1-title').text(window.dialogArguments);
});
$('table button').click(function()
{
    var cono = $(this).attr('data-cono');
    setWindowReturnValue({cono: cono});    
     /* window.close() 在 IE 或其他情況下,可能沒有作用
          要改成下列指令
        */    
    $dlg.dialogWindow.dialog('close');
});
</script>
</body>
</html>