I am adding a new field to a form. The form is used to update a status from not approved to approved.The goal is to make sure that if no changes are made but the update button is clicked, an error is displayed and no update is processed. This did work before I added the new field and switched from a RequiredFieldValidator
to a CustomValidator
.
The Problem
Now, when no changes are made to the drop downs the modal closes but the rest of the window is grayed out and the application seems to hang.
This is a bit over my head a great learning experience.
EDIT:
Error from the console
Doc-Comp-Composition-Templates:348 Uncaught TypeError: $(...).ddlCS is not a function
at ValidateStatusChange_ClientValidate (Doc-Comp-Composition-Templates:348)
at eval (eval at CustomValidatorEvaluateIsValid (ScriptResource.axd?d=nv7asgRUU0tRmHNR2D6t1FZw7wze8nmx-kJRmw2XEjbK3oXSAIyhKQNPF6n1kyJ-XavItdyBmyr8jQKkgUwJ4hvE-EOowyd5E-dQMLMfuYhYi3DooAGZ6tCMyoNO-1bI0OD14u047d3MStBJK15cjQ2&t=fffffffff974e48e:450), <anonymous>:1:1)
at HTMLSpanElement.CustomValidatorEvaluateIsValid [as evaluationfunction] (ScriptResource.axd?d=nv7asgRUU0tRmHNR2D6t1FZw7wze8nmx-kJRmw2XEjbK3oXSAIyhKQNPF6n1kyJ-XavItdyBmyr8jQKkgUwJ4hvE-EOowyd5E-dQMLMfuYhYi3DooAGZ6tCMyoNO-1bI0OD14u047d3MStBJK15cjQ2&t=fffffffff974e48e:450)
at ValidatorValidate (ScriptResource.axd?d=nv7asgRUU0tRmHNR2D6t1FZw7wze8nmx-kJRmw2XEjbK3oXSAIyhKQNPF6n1kyJ-XavItdyBmyr8jQKkgUwJ4hvE-EOowyd5E-dQMLMfuYhYi3DooAGZ6tCMyoNO-1bI0OD14u047d3MStBJK15cjQ2&t=fffffffff974e48e:200)
at Page_ClientValidate (ScriptResource.axd?d=nv7asgRUU0tRmHNR2D6t1FZw7wze8nmx-kJRmw2XEjbK3oXSAIyhKQNPF6n1kyJ-XavItdyBmyr8jQKkgUwJ4hvE-EOowyd5E-dQMLMfuYhYi3DooAGZ6tCMyoNO-1bI0OD14u047d3MStBJK15cjQ2&t=fffffffff974e48e:119)
at Sys$WebForms$PageRequestManager$_doPostBackWithOptions [as _doPostBackWithOptions] (ScriptResource.axd?d=JnUc-DEDOM5KzzVKtsL1tRZpRA_LXrniqfBmVmIZ3cAuPpCW1plWZw2RXdO0zo-BiAzza2U9Udple6pVeaDdyS14EzqQJMs1mhrjSf56Z17-S803UF2Z43EZ-6v-WWTiunEhUO4tmGiISgd0nYLoQNVyt3LQvd2TOLU7l5Fq6n-tE3oJIofGXa6OGTnxPRDQ0&t=fffffffffc18b87d:831)
at ScriptResource.axd?d=D9drwtSJ4hBA6O8UhT6CQi4RxEM3HXQdD1kANRSxcVDQlciZR3AdFzJCI2OSpEJ8btryaMvtylBgqedQo2VFV1HT2WfhU1dHTVqnIz5ypNeiBiXQQMaUQfmxLJUQguR-W97gIReVDFvaBQUHY7tXxFcflqZ4dU-xR3P7jVPaHdY1&t=fffffffffc18b87d:47
at HTMLInputElement.onclick (Doc-Comp-Composition-Templates:1)
Controls to validate:
<div class="form-group">
<label for="ddlCS">Current Status:</label>
<asp:DropDownList ID="ddlCS" runat="server" CssClass="form-control"
ToolTip="Choose Status" Enabled="false" ValidationGroup="gStatusChange" />
</div>
<div class="form-group">
<label for="ddlNS">New Status:</label>
<asp:DropDownList ID="ddlNS" runat="server" CssClass="form-control"
ToolTip="Choose Status" ValidationGroup="gStatusChange" />
</div>
<div class="form-group">
<label for="ddlPA">Proof Approval:</label>
<asp:DropDownList ID="ddlPA" runat="server" CssClass="form-control"
Tooltip="Choose Proof Status" ValidationGroup="gStatusChange" />
</div>
<div class="col-sm-3">
<asp:Button ID="btnUpdate" runat="server" Text="Update Status"
CssClass="btn btn-primary pull-left" ToolTip="Save Changes"
OnClick="btnUpdate_Click"/>
</div>
Validator:
<asp:CustomValidator ID="custvStatusChange" runat="server" Display="None"
ValidationGroup="gStatusChange"
ErrorMessage="Wow what an error!"
OnServerValidate="ValidateStatusChange_ServerValidate"
ClientValidationFunction="ValidateStatusChange_ClientValidate"/>
<asp:ValidationSummary ID="vscustvStatusChange" runat="server" ToolTip="Error Summary"
ShowSummary="true"
ShowMessageBox="false"
CssClass="alert alert-danger"
ValidationGroup="gStatusChange" />
<Triggers>
<asp:AsyncPostBackTrigger ControlID="gvTemplates"
EventName="RowCommand"/>
<asp:AsyncPostBackTrigger ControlID="btnUpdate" EventName="Click"/>
</Triggers>
Server-Side Validation:
protected void ValidateStatusChange_ServerValidate(object source,
ServerValidateEventArgs args)
{
if (ddlCS.SelectedValue == ddlNS.SelectedValue || ddlPA.SelectedIndex == 0)
{
args.IsValid = false;
}
}
Client-Side Validation:
<script>
$m = jQuery.noConflict();
</script>
<script type="text/javascript">
function ValidateStatusChange_ClientValidate(source, args) {
var cStatus = $(source).ddlCS("select").prop("selectedIndex");
var nStatus = $(source).ddlNS("select").prop("selectedIndex");
var pStatus = $(source).ddlPA("select").prop("selectedIndex");
if (cStatus == nStatus || pStatus == 0) {
args.IsValid = false;
} else {
args.IsValid = true;
}
}
function closeModal() {
$('#modStatus').modal('hide');
$('body').removeClass('modal-open');
$('.modal-backdrop').remove();
}
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(function () {
function closeModal() {
$('#modStatus').modal('hide');
$('body').removeClass('modal-open');
$('.modal-backdrop').remove();
}
});
</script>
Button Click event:
protected void btnUpdate_Click(object sender, EventArgs e)
{
Page.Validate("custvStatusChange");
if (Page.IsValid)
{
#region Template Status change
if (ddlNS.SelectedIndex > 0)
{
if (ddlCS.SelectedValue != ddlNS.SelectedValue)
{
if (ddlCS.SelectedValue == "5" && hfProofStatus.Value == "N")
{
lblUpdateStatus.Text = "Proof must be approved before template can be";
lblUpdateStatus.CssClass = "text-danger";
}
else
{
ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "Close", "$('#modStatus').modal('hide');$('body').removeClass('modal-open');$('.modal-backdrop').remove();", true);
// save and notify
DotNetAuth auth = (DotNetAuth)HttpContext.Current.Session["AppSysAuth"];
if (CompositionTemplate.UpdateStatus(Convert.ToInt32(hfTemplateID.Value),
Convert.ToInt32(ddlNS.SelectedValue), auth.Name, hfFileName.Value))
{
lblUpdateStatus.Text = "Status change saved";
lblUpdateStatus.CssClass = "text-success";
BindGrid();
}
else
{
lblUpdateStatus.Text = "Error saving status change";
lblUpdateStatus.CssClass = "text-danger";
}
}
}
}
#endregion
}
}
The ddlCS()
function (also with ddlNS()
and ddlPA()
) is undefined because they're not defined inside jQuery selector of $(source)
. You should change these lines:
var cStatus = $(source).ddlCS("select").prop("selectedIndex");
var nStatus = $(source).ddlNS("select").prop("selectedIndex");
var pStatus = $(source).ddlPA("select").prop("selectedIndex");
to these lines below, which uses ClientID
for each dropdown (since you're not using ClientIDMode="Static"
attribute, therefore assumed dynamic client ID is in place):
var cStatus = $('#<%= ddlCS.ClientID %>').prop("selectedIndex");
var nStatus = $('#<%= ddlNS.ClientID %>').prop("selectedIndex");
var pStatus = $('#<%= ddlPA.ClientID %>').prop("selectedIndex");
Or using select
element selector with id
attribute set to ClientID
of each dropdown like this:
var cStatus = $('select [id=<%= ddlCS.ClientID %>]').prop("selectedIndex");
var nStatus = $('select [id=<%= ddlNS.ClientID %>]').prop("selectedIndex");
var pStatus = $('select [id=<%= ddlPA.ClientID %>]').prop("selectedIndex");