Comment faire une case à cocher obligatoire sur un formulaire ASP.NET?

112

J'ai fait quelques recherches à ce sujet, et j'ai trouvé plusieurs réponses partielles, cependant rien qui me donne ce chaud flou "c'est la bonne façon de faire". Pour répondre à la réclamation la plus fréquente concernant cette question: "les cases à cocher peuvent avoir deux états légitimes - cochée et décochée", il s'agit d'une case à cocher "J'accepte les termes et conditions ..." qui doit être cochée afin de terminer une inscription, il est donc nécessaire de cocher la case du point de vue de la logique métier.

Veuillez fournir des fragments de code complets prêts à copier-coller avec votre réponse! Je sais qu'il y a plusieurs éléments à cela - le CustomValidator (vraisemblablement), le code-behind, du javascript et peut-être un chèque pour IsValid, et la partie frustrante pour moi est que dans chaque exemple que j'ai vu, l'un de ces critiques il manque des morceaux!

Bob Kaufman
la source

Réponses:

216

fonction javascript pour la validation côté client (à l'aide de jQuery) ...

function CheckBoxRequired_ClientValidate(sender, e)
{
    e.IsValid = jQuery(".AcceptedAgreement input:checkbox").is(':checked');
}

code-behind pour la validation côté serveur ...

protected void CheckBoxRequired_ServerValidate(object sender, ServerValidateEventArgs e)
{
    e.IsValid = MyCheckBox.Checked;
}

Code ASP.Net pour la case à cocher et le validateur ...

<asp:CheckBox runat="server" ID="MyCheckBox" CssClass="AcceptedAgreement" />
<asp:CustomValidator runat="server" ID="CheckBoxRequired" EnableClientScript="true"
    OnServerValidate="CheckBoxRequired_ServerValidate"
    ClientValidationFunction="CheckBoxRequired_ClientValidate">You must select this box to proceed.</asp:CustomValidator>

et enfin, dans votre postback - que ce soit à partir d'un bouton ou autre ...

if (Page.IsValid)
{
    // your code here...
}
Scott Ivey
la source
Je fais probablement quelque chose de mal. Je vais continuer à enquêter de mon côté, mais ControlToValidate = "<id-of-checkbox-control>" lève l'exception "Le contrôle <id-of-checkbox-control> référencé par la propriété ControlToValidate ne peut pas être validé." Ce qui casse le javascript, etc.
Bob Kaufman
2
ahh, c'est vrai. Supprimez simplement cela - CheckBox n'implémente pas l'interface correcte pour le lier. Le validateur fonctionnera toujours correctement sans cet ensemble de propriétés. Je mettrai à jour mon exemple en conséquence.
Scott Ivey
2
Le paramètre CustomValidator pour le nom de la fonction javascript doit être «ClientValidationFunction» et non «OnClientValidate». Voir: msdn.microsoft.com/en-us/library/9eee01cx(v=VS.100).aspx
Chris
1
Je suggérerais d'utiliser jQuery("#<%= MyCheckBox.ClientID %>")au lieu de jQuery(".AcceptedAgreement input:checkbox")pour être plus explicite dans quel élément vous essayez d'affecter.
Jesse Webb
3
Je n'ai pas initialement remarqué qu'il n'y a pas d'attribut ControlToValidate. L'inclusion de cet attribut provoque une exception, donc un mot d'avertissement à d'autres qui peuvent également manquer cela.
MicrosoftAccessPros.com
19

Version C # de la réponse d'Andrew:

<asp:CustomValidator ID="CustomValidator1" runat="server" 
        ErrorMessage="Please accept the terms..." 
        onservervalidate="CustomValidator1_ServerValidate"></asp:CustomValidator>
    <asp:CheckBox ID="CheckBox1" runat="server" />

Code derrière:

protected void CustomValidator1_ServerValidate(object source, ServerValidateEventArgs args)
{
    args.IsValid = CheckBox1.Checked;
}
John Rasch
la source
merci pour la version C #. Bonne utilisation de la minimisation du code aussi.
andrewWinn
13

Si vous voulez un vrai validateur qui ne repose pas sur jquery et gère également la validation côté serveur (et vous devriez. La validation côté serveur est la partie la plus importante), alors voici un contrôle

public class RequiredCheckBoxValidator : System.Web.UI.WebControls.BaseValidator
{
    private System.Web.UI.WebControls.CheckBox _ctrlToValidate = null;
    protected System.Web.UI.WebControls.CheckBox CheckBoxToValidate
    {
        get
        {
            if (_ctrlToValidate == null)
                _ctrlToValidate = FindControl(this.ControlToValidate) as System.Web.UI.WebControls.CheckBox;

            return _ctrlToValidate;
        }
    }

    protected override bool ControlPropertiesValid()
    {
        if (this.ControlToValidate.Length == 0)
            throw new System.Web.HttpException(string.Format("The ControlToValidate property of '{0}' is required.", this.ID));

        if (this.CheckBoxToValidate == null)
            throw new System.Web.HttpException(string.Format("This control can only validate CheckBox."));

        return true;
    }

    protected override bool EvaluateIsValid()
    {
        return CheckBoxToValidate.Checked;
    }

    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);

        if (this.Visible && this.Enabled)
        {
            System.Web.UI.ClientScriptManager cs = this.Page.ClientScript;
            if (this.DetermineRenderUplevel() && this.EnableClientScript)
            {
                cs.RegisterExpandoAttribute(this.ClientID, "evaluationfunction", "cb_verify", false);
            }
            if (!this.Page.ClientScript.IsClientScriptBlockRegistered(this.GetType().FullName))
            {
                cs.RegisterClientScriptBlock(this.GetType(), this.GetType().FullName, GetClientSideScript());
            } 
        }
    }

    private string GetClientSideScript()
    {
        return @"<script language=""javascript"">function cb_verify(sender) {var cntrl = document.getElementById(sender.controltovalidate);return cntrl.checked;}</script>";
    }
}
CirrusABS
la source
C'est la seule réponse qui fonctionnera sur plus d'un CheckBox dans un formulaire, plutôt que d'avoir besoin d'une fonction pour chaque objet. Huzzah!
haliphax
Merci beaucoup. J'avais besoin d'un moyen de le faire avec plusieurs contrôles rendus dynamiquement. Impressionnant.
schmosef
Bien que la solution choisie par Scott soit correcte / valide, je pense que c'est la solution la plus complète. Ce contrôle personnalisé doit avoir été intégré au framework. Merci CirrusABS!
Gabe
5

La réponse de Scott fonctionnera pour les classes de cases à cocher. Si vous voulez des cases à cocher individuelles, vous devez être un peu plus sournois. Si vous ne faites qu'une seule boîte, il vaut mieux le faire avec des identifiants. Cet exemple le fait par des cases à cocher spécifiques et ne nécessite pas jQuery. C'est aussi un joli petit exemple de la façon dont vous pouvez obtenir ces ID de contrôle embêtants dans votre Javascript.

Le .ascx:

<script type="text/javascript">

    function checkAgreement(source, args)
    {                
        var elem = document.getElementById('<%= chkAgree.ClientID %>');
        if (elem.checked)
        {
            args.IsValid = true;
        }
        else
        {        
            args.IsValid = false;
        }
    }

    function checkAge(source, args)
    {
        var elem = document.getElementById('<%= chkAge.ClientID %>');
        if (elem.checked)
        {
            args.IsValid = true;
        }
        else
        {
            args.IsValid = false;
        }    
    }

</script>

<asp:CheckBox ID="chkAgree" runat="server" />
<asp:Label AssociatedControlID="chkAgree" runat="server">I agree to the</asp:Label>
<asp:HyperLink ID="lnkTerms" runat="server">Terms & Conditions</asp:HyperLink>
<asp:Label AssociatedControlID="chkAgree" runat="server">.</asp:Label>
<br />

<asp:CustomValidator ID="chkAgreeValidator" runat="server" Display="Dynamic"
    ClientValidationFunction="checkAgreement">
    You must agree to the terms and conditions.
    </asp:CustomValidator>

<asp:CheckBox ID="chkAge" runat="server" />
<asp:Label AssociatedControlID="chkAge" runat="server">I certify that I am at least 18 years of age.</asp:Label>        
<asp:CustomValidator ID="chkAgeValidator" runat="server" Display="Dynamic"
    ClientValidationFunction="checkAge">
    You must be 18 years or older to continue.
    </asp:CustomValidator>

Et le code derrière:

Protected Sub chkAgreeValidator_ServerValidate(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ServerValidateEventArgs) _
Handles chkAgreeValidator.ServerValidate
    e.IsValid = chkAgree.Checked
End Sub

Protected Sub chkAgeValidator_ServerValidate(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ServerValidateEventArgs) _
Handles chkAgeValidator.ServerValidate
    e.IsValid = chkAge.Checked
End Sub
Jorelli
la source
3

J'effectue généralement la validation côté client:

<asp:checkbox id="chkTerms" text=" I agree to the terms" ValidationGroup="vg" runat="Server"  />
<asp:CustomValidator id="vTerms"
                ClientValidationFunction="validateTerms" 
                ErrorMessage="<br/>Terms and Conditions are required." 
                ForeColor="Red"
                Display="Static"
                EnableClientScript="true"
                ValidationGroup="vg"
                runat="server"/>

<asp:Button ID="btnSubmit" OnClick="btnSubmit_Click" CausesValidation="true" Text="Submit" ValidationGroup="vg" runat="server" />

<script>
    function validateTerms(source, arguments) {
        var $c = $('#<%= chkTerms.ClientID %>');
        if($c.prop("checked")){
            arguments.IsValid = true;
        } else {
            arguments.IsValid = false;
        }
    }
</script>       
Rob
la source
Une des meilleures solutions car elle ne postback pas.
nu everest
Le problème avec cela est que le message du validateur ne disparaît pas si vous soumettez, puis essayez de cocher la case.
MC9000
-1

Manière non javascript. . page aspx:

 <form id="form1" runat="server">
<div>
    <asp:CheckBox ID="CheckBox1" runat="server" />
    <asp:CustomValidator ID="CustomValidator1"
        runat="server" ErrorMessage="CustomValidator" ControlToValidate="CheckBox1"></asp:CustomValidator>
</div>
</form>

Code derrière:

Protected Sub CustomValidator1_ServerValidate(ByVal source As Object, ByVal args As System.Web.UI.WebControls.ServerValidateEventArgs) Handles CustomValidator1.ServerValidate
    If Not CheckBox1.Checked Then
        args.IsValid = False
    End If
End Sub

Pour toute action dont vous pourriez avoir besoin (règles métier):

If Page.IsValid Then
   'do logic
End If 

Désolé pour le code VB. . . vous pouvez le convertir en C # si cela vous plaît. L'entreprise pour laquelle je travaille actuellement a besoin de VB :(

andrewWinn
la source
3
Cela ne fonctionnera pas, car vous ne pouvez pas attacher le validateur à la case à cocher! DOOOH!
0xDEAD BEEF