Problem with multiple ModalPopupExtenders in the same page, each requiring validation. For some reason I'm not seeing, the validation on the second fires (i.e., the error message displays), but the postback is not canceled and further, Page.IsValid is true in the code-behind. On the first MPE, the postback is canceled and we never hit the code-behind.
Markup for the modals:
<asp:Panel ID="pnlIndicatorEdit" runat="server" CssClass="modalPopup" style="display: none; width: 400px;">
<h3>Indicator edit</h3>
Name: <asp:TextBox ID="txtName" runat="server" Width="200px" />
<asp:RequiredFieldValidator ID="rfvIndicatorName" runat="server" Display="Dynamic" ControlToValidate="txtName"
ErrorMessage="Required" ValidationGroup="Indicator" CssClass="validator" />
<br />
Active:
<asp:RadioButtonList ID="rblActive" runat="server" RepeatDirection="Horizontal" RepeatLayout="Flow">
<asp:ListItem Text="True" Value="True" />
<asp:ListItem Text="False" Value="False" />
</asp:RadioButtonList>
<br />
Category: <asp:DropDownList id="ddlCategory" runat="server" DataTextField="Name" DataValueField="KpiCategoryId" />
<br />
Indicator Type: <asp:DropDownList id="ddlIndicatorType" runat="server" DataTextField="Name" DataValueField="IndicatorTypeId" />
<br />
Inspection Item: <asp:DropDownList ID="ddlInspectionItem" runat="server" DataTextField="FriendlyName"
DataValueField="InspectionItemId" AppendDataBoundItems="true">
<asp:ListItem Text="--None--" Value="" />
</asp:DropDownList>
<br />
Instructions: <asp:TextBox ID="txtInstructions" runat="server" TextMode="MultiLine" Columns="40" Rows="5" />
<br /><br />
<asp:Button ID="btnIndicatorSave" runat="server" CssClass="button-save" Text="Save" OnClick="btnIndicatorSave_Click" ValidationGroup="Indicator" /> <asp:Button ID="btnCancel" runat="server" CssClass="button-cancel" Text="Cancel" runat="server" CausesValidation="false" />
</asp:Panel>
<asp:Panel ID="pnlTargetEdit" runat="server" CssClass="modalPopup" style="display: none; width: 400px;">
<h3>Target edit</h3>
Indicator: <asp:Label ID="lblTargetIndicator" runat="server"/> Program: <asp:Label ID="lblTargetProgram" runat="server" />
<br />
<asp:RadioButtonList ID="rblTargetActive" runat="server" RepeatDirection="Horizontal" RepeatLayout="Flow">
<asp:ListItem Text="True" Value="True" />
<asp:ListItem Text="False" Value="False" />
</asp:RadioButtonList>
<br />
Value: <asp:TextBox ID="txtTargetValue" runat="server" ValidationGroup="target" />
<asp:RequiredFieldValidator ID="rfvTargetValue" runat="server" ControlToValidate="txtTargetValue"
ErrorMessage="Value is required" CssClass="validator" Display="Dynamic" Text="Required" />
<br />
<asp:Button ID="btnTargetSave" runat="server" CssClass="button-save" Text="Save" OnClick="btnTargetSave_Click" ValidationGroup="target" /> <asp:Button ID="btnTargetCancel" runat="server" CssClass="button-cancel" Text="Cancel" runat="server" CausesValidation="false" />
</asp:Panel>
<asp:HyperLink ID="lnkHiddenIndicatorEdit" style="display:none;" runat="server" />
<ajaxToolkit:ModalPopupExtender ID="mpeIndicatorEdit" BehaviorID="mpeIndicatorEdit" runat="server" TargetControlID="lnkHiddenIndicatorEdit"
PopupControlID="pnlIndicatorEdit" CancelControlID="btnCancel" BackgroundCssClass="modalBackground" />
<asp:HyperLink ID="lnkHIddenTargetEdit" style="display:none;" runat="server" />
<ajaxToolkit:ModalPopupExtender ID="mpeTargetEdit" BehaviorID="mpeTargetEdit" runat="server" TargetControlID="lnkHiddenTargetEdit"
PopupControlID="pnlTargetEdit" CancelControlID="btnTargetCancel" BackgroundCssClass="modalBackground" />
Server-side code:
protected void btnIndicatorSave_Click(object sender, EventArgs e)
{
//Never hit if vaildation fires
try
{
Indicator indicator = IndicatorFactory.GetById(IndicatorId);
indicator.Name = txtName.Text;
int newCategoryId = 0;
Int32.TryParse(ddlCategory.SelectedValue, out newCategoryId);
if (indicator.Category.KpiCategoryId != newCategoryId)
{
indicator.Category = KpiCategoryFactory.GetById(newCategoryId);
}
int newIndicatorTypeId = 0;
Int32.TryParse(ddlIndicatorType.SelectedValue, out newIndicatorTypeId);
if (indicator.IndicatorType.IndicatorTypeId != newIndicatorTypeId)
{
indicator.IndicatorType = IndicatorTypeFactory.GetById(newIndicatorTypeId);
}
indicator.IsActive = bool.Parse(rblActive.SelectedValue);
indicator.Instructions = txtInstructions.Text;
int newInspectionItemId = 0;
Int32.TryParse(ddlInspectionItem.SelectedValue, out newInspectionItemId);
if (indicator.InspectionItem == null)
{
if (newInspectionItemId > 0)
{
indicator.InspectionItem = InspectionFactory.GetById(newInspectionItemId);
}
}
else
{
if (newInspectionItemId == 0)
{
indicator.InspectionItem = null;
}
else if (newInspectionItemId != indicator.InspectionItem.InspectionItemId)
{
indicator.InspectionItem = InspectionFactory.GetById(newInspectionItemId);
}
}
IndicatorFactory.Save(indicator);
DataBind();
divMsg.Visible = true;
lblMsg.Text = "Save Successful!";
}
catch (Exception ex)
{
Logger.Error("An error occurred trying to save indicator with id " + IndicatorId.ToString(), ex);
divMsg.Visible = true;
lblMsg.Text = "An error occurred trying to save the indicator";
}
finally
{
mpeIndicatorEdit.Hide();
}
}
protected void btnTargetSave_Click(object sender, EventArgs e)
{
//hit regardless of validation, IsValid = true
if (Page.IsValid)
{
try
{
//trying to get validation right before filling in update code.
}
catch (Exception ex)
{
Logger.Error("An error occurred trying to save target with id " + hdnTargetId.Value, ex);
divMsg.Visible = true;
lblMsg.Text = "An error occurred trying to save the target";
}
finally
{
mpeTargetEdit.Hide();
}
}
}