The scenario I am trying to support is that of a base web form which displays data. However, that form has the ability to support minor edits. In this case we are using a basic button to invoke a modal dialogue (Ajax ModalDialogExtender) with
the user, in which those edits will be performed. To support this various validations are required. The way I support the display of validation messages is the Ajax ModalDialogExtender. Therefore the result of this is the need to nest calls
to this feature. This seems to work fine when calls to ModalDialogExtender are client side invoked, but the problems start when you need server side support to assist with the validations.
This question includes a full VS 2017 project. It is very minimal and attempts to demonstrate the issue rather than be to pretty! The project references AjaxControlToolkit.15.1.4.0.
The project is mainly HTML with embedded JS and CSS Style. There is a very small amount of code behind in VB.
<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="ModalFromModal.aspx.vb" Inherits="ModalFromModal.frmMain" %><%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %><!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head runat="server"><title>Modal from modal</title><script type="text/javascript">
function ShowDialog() {
$find("frmDialog").show();
var hfld = document.getElementById("bHfdDialogActive");
hfld.value = 1;
return false;
}
function HideDialog() {
$find("frmDialog").hide();
var hfld = document.getElementById("bHfdDialogActive");
hfld.value = 0;
return false;
}
function ShowMsg() {
$find("frmMsg").show();
return false;
}
function CheckMyData() {
var htxtMyWord = document.getElementById("txtMyWord");
var pos = htxtMyWord.value.search(" ");
if (pos != -1) {
var hWarning = document.getElementById("lblWarning");
hWarning.innerText = "Spaces are not allowed";
$find("frmMsg").show();
return false;
}
return true;
}</script><style>
.mpxMsg {
z-index:1001;
}
.mpxDialog {
z-index:1000;
}
.errmsg {
text-align: center;
}
.errpnl {
width: 400px;
}
.pnlDialog {
width: 600px;
height:200px;
}</style></head><body><form id="frmMain" runat="server"><asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager><div><h1>Modal from modal - Base form</h1><asp:Button ID="Button1" runat="server" Text="Edit data" OnClientClick="return ShowDialog();" /></div><asp:HiddenField ID="hfdForModel" runat="server" /><asp:ModalPopupExtender
ID="frmMsg"
TargetControlID="hfdForModel"
runat="server"
BackgroundCssClass="mpxMsg"
DropShadow="true"
PopupControlID="pnlIssues" ></asp:ModalPopupExtender> <asp:Panel ID="pnlIssues" runat="server" BorderColor="Black" BorderStyle="Outset" BorderWidth="2" BackColor="White" style="display:none" CssClass="errpnl" ><div class="errmsg"><asp:Label ID="lblHdr" runat="server" text="Information" style="font-weight: bold;"/><br /><br /><asp:Label ID="lblWarning" runat="server" > </asp:Label><br /><button type="button" onclick="$find('frmMsg').hide();" class="msgbutton">OK</button></div></asp:Panel><asp:HiddenField ID="bHfdDialogActive" runat="server" /><asp:HiddenField ID="hfDialogTarg" runat="server" /><asp:ModalPopupExtender
ID="frmDialog"
TargetControlID="hfDialogTarg"
runat="server"
BackgroundCssClass="mpxDialog"
DropShadow="true"
PopupControlID="pnlDialog" ></asp:ModalPopupExtender><asp:Panel ID="pnlDialog" runat="server" BorderColor="Black" BorderStyle="Outset" BorderWidth="2" BackColor="White" style="display:none" CssClass="pnlDialog" ><h2>Dialogue - edit</h2><asp:Label ID="lblMyWord" runat="server" Text="My word"></asp:Label><asp:TextBox ID="txtMyWord" runat="server"></asp:TextBox><asp:Button ID="cmdCheck" runat="server" Text="Check" OnClientClick="return CheckMyData();" /><br /><br /><asp:Button ID="cmdClose" runat="server" Text="Close" OnClientClick="HideDialog();" /></asp:Panel></form></body></html>
Public Class frmMain
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If IsPostBack Then
If bHfdDialogActive.Value = "1" Then frmDialog.Show()
If Not WordInDatabase() Then
lblWarning.Text = "Your word is not on file"
frmMsg.Show()
End If
End If
End Sub
Function WordInDatabase() As Boolean
Return False
End Function
End Class
The HTML covers the base form, a declaration of a frmDialog which is launched from the base form button (edit). There is also a declaration of frmMsg, used to report a validation error to the user.
The edit form has a textbox a check button and a close button. The idea is that when the check button is pressed, validation is in two stages:
First, client side, there is a check to make sure only a single word is entered. The purpose of this is to illustrate how I want it to work. i.e. That the base form is in background, the edit form overlays that and finally the validation message
overlays that.
Second stage of validation is the perform a lookup on a database to see if that word exists. I have not bothered to include the code behind for that, other than a shell function which always returns a false to invoke the same frmMsg from server side.
The problem: Unfortunately, the result of this is that whilst both the frmDialog and frmMsg are issued, the frmDialog overlays the frmMsg. If you use the frmDialog close button, you can see the frmMsg.
I have seen other articles where the use of a styled z-order which seems to be relevant. You will see I have implemented this, but it seems to have no benefit. Other articles also refer to JS basedToTop feature, but I could never find enough details to understand how to try this out.
You will see that I force the re-display of the frmDialog for each postback, based on a hidden field. There might be a more elegant way of doing this? I did experiment with calling that from LoadComplete but that made no difference.