在傳統 ASP.NET WebForms 開發中,常遇到父頁面彈出模態視窗,關閉後需根據操作結果更新父頁面 UI(如將按鈕置灰)的需求。本文透過實際程式碼範例,詳細說明模態視窗與父頁面之間的變數傳遞、DOM 操作與狀態同步機制。
父頁面包含一個列表,使用者點選某列後彈出模態視窗進行審批。視窗關閉時,父頁面需根據回傳值決定是否將該列的核准按鈕設為不可用狀態。
<head runat="server">
<script type="text/javascript">
var clearData; // 模態視窗回傳旗標
var tmpControllerId; // 記錄目前點選的行號
// 彈出明細視窗
function ShowDetail(url, id) {
var title = "工時審批";
var reValue = ShowWindow(url, 1000, 700, 0, title); // 自訂彈窗函式
tmpControllerId = id; // 保存行 ID 供後續判斷
}
</script>
</head>
<body>
<form>
<asp:HiddenField runat="server" ID="hidCheckBoxId" Value="" />
<script type="text/javascript">
var idS = document.getElementById("hidCheckBoxId").value;
// clearData 未定義或為 false 表示審批未通過,移除該行 ID
if (clearData == undefined || !clearData) {
idS = idS.replace(tmpControllerId, "");
idS = idS.substr(0, idS.length - 1);
}
if (idS != undefined && idS != "") {
var arrId = idS.split(';');
for (var i = 0; i < arrId.length; i++) {
if (arrId[i] == "") continue;
var objBox = document.getElementById(arrId[i]);
objBox.disabled = "disabled";
var objBtnId = arrId[i].replace("chkSelect", "lbtnApprove");
var objBtn = document.getElementById(objBtnId);
objBtn.disabled = "disabled";
objBtn.onclick = function() { return false; };
}
}
document.getElementById("hidCheckBoxId").value = idS;
</script>
</form>
</body>
clearData、tmpControllerId 為全域變數,模態視窗可透過 window.opener 或 window.dialogArguments 存取並修改。hidCheckBoxId 存放已處理行的 ID 字串(以分號分隔),跨 PostBack 保持狀態。document.getElementById 取得核取方塊與按鈕元素,設定 disabled 屬性並覆寫 onclick 防止二次點擊。clearData 為假),從記錄字串中移除該行 ID,確保下次載入不會被誤判為已處理。// 模態視窗內部按鈕點擊事件
function btnApprove_Click() {
window.opener.clearData = true; // 設定父頁面旗標
window.close();
}
function btnReject_Click() {
window.opener.clearData = false;
window.close();
}
window.showModalDialog 時,父頁面變數需透過 dialogArguments 傳遞物件參考,而非單純全域變數。showModalDialog 在 Chrome 等瀏覽器已棄用的問題。chkSelect_RowIndex、lbtnApprove_RowIndex)需前後端一致,確保 replace 邏輯正確運作。