需在父頁面彈出子視窗選取資料 (如選擇客戶、商品、日期範圍),子視窗關閉後將選取值回填父頁面欄位,**不刷新父頁面**。傳統 window.open 需跨域通訊複雜,IE 專屬 window.showModalDialog 提供同步阻塞與 returnValue 機制,極適合內部系統。
注意:showModalDialog已從 Chrome、Firefox、Edge 移除,**僅 IE/舊版 Edge 支援**。現代專案請改用window.open+postMessage或 Modal 彈窗元件 (Bootstrap Modal, jQuery UI Dialog, SweetAlert2 等)。本文僅供維舊系統參考。
Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<html><body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="txtParentValue" runat="server" />
<asp:Button ID="btnOpen" runat="server" Text="開啟選取視窗" OnClick="btnOpen_Click" />
</div>
</form>
</body></html>
Default.aspx.cs
protected void btnOpen_Click(object sender, EventArgs e)
{
var sb = new StringBuilder();
sb.Append("<script language=javascript>");
sb.Append("var ret = window.showModalDialog('Child.aspx', window, 'dialogWidth:400px;dialogHeight:300px;center:yes;resizable:no;status:no');");
sb.Append("if (ret != null) document.getElementById('").Append(txtParentValue.ClientID).Append("').value = ret;");
sb.Append("</script>");
ScriptManager.RegisterStartupScript(this, GetType(), "openModal", sb.ToString(), false);
}
Child.aspx (關鍵:<base target="_self"> 防止表單提交跳出對話框)
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Child.aspx.cs" Inherits="Child" %>
<html>
<head><base target="_self" /></head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="txtInput" runat="server" />
<asp:Button ID="btnConfirm" runat="server" Text="確定" OnClick="btnConfirm_Click" />
</div>
</form>
</body></html>
Child.aspx.cs
protected void btnConfirm_Click(object sender, EventArgs e)
{
var sb = new StringBuilder();
sb.Append("<script language=javascript>");
sb.Append("window.returnValue = '").Append(txtInput.Text.Replace("'", "\\'")).Append("';");
sb.Append("window.close();");
sb.Append("</script>");
ScriptManager.RegisterStartupScript(this, GetType(), "returnVal", sb.ToString(), false);
}
showModalDialog('Child.aspx'),父頁面**阻塞等待**。window.returnValue = '使用者輸入值' → window.close()。showModalDialog 回傳值 → 腳本將值寫入 txtParentValue。returnValue 僅支援字串。若需傳遞物件,子頁面序列化為 JSON:
// 子頁面
var obj = { id: 123, name: "Tom", roles: ["Admin","User"] };
window.returnValue = JSON.stringify(obj);
window.close();
// 父頁面
var ret = window.showModalDialog(...);
if (ret) {
var data = JSON.parse(ret);
document.getElementById("hidId").value = data.id;
document.getElementById("txtName").value = data.name;
}
| 方案 | 特點 | 適用性 |
|---|---|---|
| Bootstrap Modal / jQuery UI Dialog | 同頁 DOM、無阻塞、跨瀏覽器 | 新專案首選 |
| window.open + postMessage | 真正彈窗、跨域安全、非阻塞 | 需獨立視窗、跨域 |
| SweetAlert2 / Layer / Ant Design Modal | 美觀、Promise API、支援表單驗證 | 現代前端框架整合 |
showModalDialog 是 IE 時代的產物,以同步阻塞簡化父子傳值。維護舊系統時掌握其 returnValue、base target="_self"、ScriptManager.RegisterStartupScript 三要素即可。新專案請直接採用前端 Modal 元件,架構更清晰、相容性更佳。