Anthony Gilbert Anthony Gilbert - 7 months ago 38
Javascript Question

CustomValidator woes

Ok iv followed more than a few of the CustomValidators for multiple asp CheckBox's on here and on a few other sites and am having a little bit of a hard time with it actually validating when a check box is checked.

Whilst I have tried a variety of answers I have settled on one in particular.
I have gotten it to the point that it will show in the validation summary but when the checkbox's are checked they still show up in the summary that they are not. I don't know what iv done wrong or if I have missed something but i'm hoping an extra set of eyes can help me with what I have missed.

CheckBox's:

<div class="section">
<span>2</span>Induction Checklist:
</div>
<div class="inner-wrap">
<label>Introduction of relevant staff <asp:CheckBox CssClass="HitCheckbox" ValidationGroup="checkList" runat="server" ID="cbStaffIntro" /></label>
<label>Comments: <asp:TextBox runat="server" ID="txtStaffIntroComment" /></label>
</div> <!-- end inner-wrap -->

<div class="inner-wrap">
<label>Location of all Exits <asp:CheckBox CssClass="HitCheckbox" ValidationGroup="checkList" runat="server" ID="cbExitLocations" /></label>
<label>Comments: <asp:TextBox runat="server" ID="txtExitLocationComment" /></label>
</div> <!-- end inner-wrap -->

<div class="inner-wrap">
<label>Evacuation Assembly Point <asp:CheckBox CssClass="HitCheckbox" ValidationGroup="checkList" runat="server" ID="cbEvacuationPoint" /></label>
<label>Comments: <asp:TextBox runat="server" ID="txtEvacuationPointComment" /></label>
</div> <!-- end inner-wrap -->

<div class="inner-wrap">
<label>Location of Fire Extinguishers <asp:CheckBox CssClass="HitCheckbox" ValidationGroup="checkList" runat="server" ID="cbFireExtLocations" /></label>
<label>Comments: <asp:TextBox runat="server" ID="txtFireExtLocationsComment" /></label>
</div> <!-- end inner-wrap -->

<div class="inner-wrap">
<label>Location of Fire Hoses <asp:CheckBox CssClass="HitCheckbox" ValidationGroup="checkList" runat="server" ID="cbFireHoseLoc" /></label>
<label>Comment: <asp:TextBox runat="server" ID="txtFireHoseLocComment" /></label>
</div> <!-- end inner-wrap -->

<div class="inner-wrap">
<label>Location of First Aid Kits <asp:CheckBox CssClass="HitCheckbox" ValidationGroup="checkList" runat="server" ID="cbFirstAidLoc" /></label>
<label>Comment: <asp:TextBox runat="server" ID="txtFirstAidLocComment" /></label>
</div> <!-- end inner-wrap -->

<div class="inner-wrap">
<label>Location of Male / Female Toilets <asp:CheckBox CssClass="HitCheckbox" ValidationGroup="checkList" runat="server" ID="cbLooLoc" /></label>
<label>Comment: <asp:TextBox runat="server" ID="txtLooLocComment" /></label>
</div> <!-- end inner-wrap -->

<div class="inner-wrap">
<label>Location of Lunch Rooms <asp:CheckBox CssClass="HitCheckbox" ValidationGroup="checkList" runat="server" ID="cbLuncLoc" /></label>
<label>Comment: <asp:TextBox runat="server" ID="txtLunchLocComment" /></label>
</div> <!-- end inner-wrap -->

<div class="inner-wrap">
<label>Explain "No-Smoking" Policy in all Offices and Buildings <asp:CheckBox CssClass="HitCheckbox" ValidationGroup="checkList" runat="server" ID="cbNoSmoke" /></label>
<label>Comment: <asp:TextBox runat="server" ID="txtNoSmokeComment" /></label>
</div> <!-- end inner-wrap -->

<div class="inner-wrap">
<label>Explain and Indicate "No-Go" Zones in Warehouse <asp:CheckBox CssClass="HitCheckbox" ValidationGroup="checkList" runat="server" ID="cbNoGo" /></label>
<label>Comment: <asp:TextBox runat="server" ID="txtNoGoComment" /></label>
</div> <!-- end inner-wrap -->

<div class="inner-wrap">
<label>Other <asp:CheckBox CssClass="HitCheckbox" ValidationGroup="checkList" runat="server" ID="cbOther" /></label>
<label>Comment: <asp:TextBox runat="server" ID="txtOtherComment" /></label>
</div> <!-- end inner-wrap -->


Client side validation:

<script>
function CheckBoxRequired_ClientValidate(sender, e)
{
e.IsValid = jQuery(".HitCheckBox input:checkbox").is(':checked');
}
</script>


Server Side Validation:

public void Required_ServerValidate(object source, ServerValidateEventArgs args)
{
args.IsValid = (cbStaffIntro.Checked);
args.IsValid = (cbExitLocations.Checked);
args.IsValid = (cbEvacuationPoint.Checked);
args.IsValid = (cbFireExtLocations.Checked);
args.IsValid = (cbFireHoseLoc.Checked);
args.IsValid = (cbFirstAidLoc.Checked);
args.IsValid = (cbLooLoc.Checked);
args.IsValid = (cbLuncLoc.Checked);
args.IsValid = (cbNoSmoke.Checked);
args.IsValid = (cbNoGo.Checked);
}


Custom Validators:

<!-- Checklist Validation Section cbStaffIntro -->
<asp:CustomValidator runat="server" ID="CustomValidatorSi" ValidateEmptyText="true" ValidationGroup="checkList" EnableClientScript="true" Display="None" ErrorMessage="Introduction to relevant Staff Not Completed!" OnServerValidate="Required_ServerValidate" ClientValidationFunction="CheckBoxRequired_ClientValidate" />
<asp:CustomValidator runat="server" ID="CustomValidatorEl" ValidateEmptyText="true" ValidationGroup="checkList" EnableClientScript="true" Display="None" ErrorMessage="Emergancy Exit Locations Not Completed!" OnServerValidate="Required_ServerValidate" ClientValidationFunction="CheckBoxRequired_ClientValidate" />
<asp:CustomValidator runat="server" ID="CustomValidatorEp" ValidateEmptyText="true" ValidationGroup="checkList" EnableClientScript="true" Display="None" ErrorMessage="Evacuation Point Not Covered!" OnServerValidate="Required_ServerValidate" ClientValidationFunction="CheckBoxRequired_ClientValidate" />
<asp:CustomValidator runat="server" ID="CustomValidatorFe" ValidateEmptyText="true" ValidationGroup="checkList" EnableClientScript="true" Display="None" ErrorMessage="Fire Extinguisher Locations Not Covered!" OnServerValidate="Required_ServerValidate" ClientValidationFunction="CheckBoxRequired_ClientValidate" />
<asp:CustomValidator runat="server" ID="CustomValidatorFh" ValidateEmptyText="true" ValidationGroup="checkList" EnableClientScript="true" Display="None" ErrorMessage="Fire Hose Locations Not Covered!" OnServerValidate="Required_ServerValidate" ClientValidationFunction="CheckBoxRequired_ClientValidate" />
<asp:CustomValidator runat="server" ID="CustomValidatorFa" ValidateEmptyText="true" ValidationGroup="checkList" EnableClientScript="true" Display="None" ErrorMessage="First Aid Locations Not Covered!" OnServerValidate="Required_ServerValidate" ClientValidationFunction="CheckBoxRequired_ClientValidate" />
<asp:CustomValidator runat="server" ID="CustomValidatorToilet" ValidateEmptyText="true" ValidationGroup="checkList" EnableClientScript="true" Display="None" ErrorMessage="Toilet Locations Not Covered!" OnServerValidate="Required_ServerValidate" ClientValidationFunction="CheckBoxRequired_ClientValidate" />
<asp:CustomValidator runat="server" ID="CustomValidatorLr" ValidateEmptyText="true" ValidationGroup="checkList" EnableClientScript="true" Display="None" ErrorMessage="Lunchroom Location Not Covered!" OnServerValidate="Required_ServerValidate" ClientValidationFunction="CheckBoxRequired_ClientValidate" />
<asp:CustomValidator runat="server" ID="CustomValidatorNsp" ValidateEmptyText="true" ValidationGroup="checkList" EnableClientScript="true" Display="None" ErrorMessage="No Smoking Policy Not Covered!" OnServerValidate="Required_ServerValidate" ClientValidationFunction="CheckBoxRequired_ClientValidate" />
<asp:CustomValidator runat="server" ID="CustomValidatorNg" ValidateEmptyText="true" ValidationGroup="checkList" EnableClientScript="true" Display="None" ErrorMessage="'No-Go' Zones Not Covered!" OnServerValidate="Required_ServerValidate" ClientValidationFunction="CheckBoxRequired_ClientValidate" />


The way i wish this to work is all of the check box's, except for the one marked 'Other', need to be selected before the form is validated.

As mentioned, I have this to the point that they will show up in the validation summary if they are not checked. What i'm having issues with is why they are still showing up as not checked in the validation summary when they are checked.

What is it im missing here? or is what i'm after not fully possible?
Before I forget i'm using .NET Framework 4 for this project.

EDIT: Thanks to Scotty for their efforts in helping me with this issue. After applying the fix offered I also had to remove the Javascript validation I had to get the code to work as needed.

Answer

You're seeing the ErrorMessages from all CustomValidators as you're using the same server side method Required_ServerValidate to validate all of your CustomValidator controls and aren't building your ErrorMessage dynamically.

You need to change your logic to dynamically build your Error Messages for each condition.

Firstly, remove all your CustomValidators except for one, then modify your code as follows.

Here's one approach...

ASPX

<asp:CustomValidator runat="server" ID="cvCheckList" ValidationGroup="checkList" EnableClientScript="true" Display="None" OnServerValidate="Required_ServerValidate" ClientValidationFunction="CheckBoxRequired_ClientValidate" />

Make sure you use DisplayMode="SingleParagraph" in your ValidationSummary so the html renders properly.

Code Behind

public void Required_ServerValidate(object source, ServerValidateEventArgs args)
{
    args.IsValid = true;

    var sb = new StringBuilder();
    sb.Append("<ul>");

    if (!cbStaffIntro.Checked)
        AppendErrorMessage(args, sb, "Introduction to relevant Staff Not Completed!");

    if (!cbExitLocations.Checked)
        AppendErrorMessage(args, sb, "Emergency Exit Locations Not Completed!");

    if (!cbEvacuationPoint.Checked)
        AppendErrorMessage(args, sb, "Evacuation Point Not Covered!");

    if (!cbFireExtLocations.Checked)
        AppendErrorMessage(args, sb, "Fire Extinguisher Locations Not Covered!");

    if (!cbFireHoseLoc.Checked)
        AppendErrorMessage(args, sb, "Fire Hose Locations Not Covered!");

    if (!cbFirstAidLoc.Checked)
        AppendErrorMessage(args, sb, "First Aid Locations Not Covered!");

    if (!cbLooLoc.Checked)
        AppendErrorMessage(args, sb, "Toilet Locations Not Covered!");

    if (!cbLuncLoc.Checked)
        AppendErrorMessage(args, sb, "Lunchroom Location Not Covered!");

    if (!cbNoSmoke.Checked)
        AppendErrorMessage(args, sb, "No Smoking Policy Not Covered!");

    if (!cbNoGo.Checked)
        AppendErrorMessage(args, sb, "'No-Go' Zones Not Covered!");

    sb.Append("</ul>");
    cvCheckList.ErrorMessage = sb.ToString();
}

private static void AppendErrorMessage(ServerValidateEventArgs args, StringBuilder sb, string message)
{
    args.IsValid = false;
    sb.AppendFormat("<li>{0}</li>", message);
}

protected void btnSubmit_Click(object sender, EventArgs e)
{
    Page.Validate();
    if (Page.IsValid)
        Response.Redirect("ValidationSuccessful.aspx");
}
Comments