Já é de conhecimento de todos (ou da maioria) que a API [window.showModalDialog] foi descontinuada pelo Browser Chrome, a partir da versão 37 - Disabling showModalDialog.
Com isto muitos WebSites simplesmente não executam mais este recurso neste browser.
Como ele é usado extensamente, o que fazer então em substituição ao depreciado showModalDialog? Vamos criar um próprio, usando a tecnologia JQuery!
A função ShowModalDialog
if (typeof (GT) == "undefined") { GT = {}; }
GT.Functions = {
ShowModalDialog: function (content, parent, width, height, bkgImage, callbackFn) {
var divTag = '<div id="divDialog" ';
divTag += 'style="border: 6px solid gray; overflow:hidden; box-shadow: 1px 1px 5px #333; ">';
if (bkgImage) {
divTag += '<div id="divDialogLoading" ';
divTag += 'style="width:' + width + 'px; height:' + height + 'px; ';
divTag += 'background: white url(' + bkgImage + ') no-repeat center;" >';
divTag += '</div>';
}
divTag += '<iframe id="frameDialog" frameBorder="0" scrolling="no" ';
divTag += 'src="' + content + '" ';
divTag += 'style="width:100%;" ';
divTag += '>';
divTag += '</iframe>';
divTag += '</div>';
var div = null;
var $JQ = null;
if (parent != null) {
var $JQ = parent.jQuery.noConflict();
parent.window.defer = $JQ.Deferred();
div = $JQ(divTag).appendTo("body");
}
else {
$JQ = jQuery.noConflict();
window.defer = $JQ.Deferred();
div = $JQ(divTag);
}
div.append('<style type="text/css"> \
.ui-widget-overlay { \
position: absolute; \
top: 0; \
left: 0; \
width: 100%; \
height: 100%; \
background: #aaaaaa;\
opacity: 0.3; \
} \
.ui-front { \
z-index: 100; \
} \
</style>');
div.dialog({
position: {
my: "center",
at: "center",
of: div,
within: div
},
autoOpen: false,
closeOnEscape: false,
height: height,
width: width,
modal: true,
open: function () {
$JQ('#frameDialog').on("load", function () {
$JQ("#divDialogLoading").hide();
this.height = div.height();
});
},
close: function () {
if (callbackFn) callbackFn();
}
});
div.dialog('open');
return (parent != null ? parent.window.defer.promise() : window.defer.promise());
}
};
Algumas considerações
Em si a função é simples pois utiliza o componente JQuery UI Dialog para mostrar um diálogo para o usuário. O mais importante é o uso do método [$.Deferred()] e o retorno da função, que utiliza o método [promise].
É justamente isto que garante que o diálogo se comporte como a API window.showModalDialog, trabalhando de forma síncrona com o resto do seu código JavaScript.
Importante: Se você pretende usar as versões mais recentes (a partir da 1.7.x) do JQuery UI Dialog em uma página ASPX, não se esqueça de usar a seguinte declaração no documento de sua página
Isto garante que o diálogo vai ser posicionado corretamente (no caso da nossa função, no centro da página).
Como devo usar o método
Veja abaixo dois exemplos de uso do método. O primeiro uso é básico. O segundo é interessante porque permite ao desenvolvedor executar o método a partir de uma página dentro de um [iframe].
var url = "http://MeuSite/MinhaPagina.aspx?param=test";
GT.Functions.ShowModalDialog(
url,
null,
470,
470,
null,
function result() {
window.defer.then(
function (result) {
if (result)
{
// TRABALHA COM O RETORNO DA PÁGINA (url) PASSADA POR PARÂMETRO
}
});
});
var url = "http://MeuSite/MinhaPagina.aspx?param=test";
var _parentW = (document.parentWindow ? document.parentWindow.parent : document.defaultView.parent);
var $jParent = _parentW.jQuery.noConflict();
GT.Functions.ShowModalDialog(
url,
_parentW,
470,
470,
null,
function result() {
_parentW.window.defer.then(
function (result) {
if (result)
{
// TRABALHA COM O RETORNO DA PÁGINA (url) PASSADA POR PARÂMETRO
}
});
});
E por fim precisamos retornar um valor para o método através da nossa página de exemplo (MinhaPagina.aspx). Note novamente que temos um exemplo de retorno simples e outro na qual a página ASPX se encontra dentro de um [iframe]
function CloseDialog()
{
window.defer.resolve("VALOR PARA RETORNAR");
$("#divDialog").dialog("close");
$("#divDialog").dialog("destroy");
$("#divDialog").remove();
}
function CloseDialog()
{
var _parentW = (document.parentWindow ? document.parentWindow.parent : document.defaultView.parent);
_parentW.window.defer.resolve("VALOR PARA RETORNAR");
var $jParent = _parentW.jQuery.noConflict();
$jParent("#divDialog").dialog("close");
$jParent("#divDialog").dialog("destroy");
$jParent("#divDialog").remove();
}
Refs:
JQuery UI Dialog
JQuery Deferred API
Cheers!!