Como faço para fazer uma caixa de seleção obrigatória em um formulário ASP.NET?


112

Eu fiz algumas pesquisas sobre isso, e encontrei várias respostas parciais, porém nada que me dê aquela impressão calorosa "esta é a maneira certa de fazer isso". Para responder à reclamação que ocorre com mais frequência contra esta pergunta: "as caixas de seleção podem ter dois estados legítimos - marcada e desmarcada", esta é uma caixa de seleção "Aceito os termos e condições ..." que deve ser marcada para concluir um registro, portanto, marcar a caixa é necessária do ponto de vista da lógica de negócios.

Forneça fragmentos de código prontos para cortar e colar completos com sua resposta! Eu sei que há várias peças para isso - o CustomValidator (presumivelmente), o code-behind, algum javascript e possivelmente uma verificação para IsValid, e a parte frustrante para mim é que em cada exemplo que vi, um desses peças estão faltando!

Respostas:


216

função javascript para validação do lado do cliente (usando jQuery) ...

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

code-behind para validação do lado do servidor ...

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

Código ASP.Net para a caixa de seleção e validador ...

<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>

e, finalmente, em seu postback - seja de um botão ou qualquer outro ...

if (Page.IsValid)
{
    // your code here...
}

Provavelmente estou fazendo algo errado. Vou continuar investigando até o fim, no entanto ControlToValidate = "<id-of-checkbox-control>" lança exceção "O controle <id-of-checkbox-control> referenciado pela propriedade ControlToValidate não pode ser validado." Que quebra o javascript etc.
— Bob Kaufman

2
ahh certo. Apenas remova isso - CheckBox não implementa a interface correta para amarrá-lo. O validador ainda funcionará bem sem esse conjunto de propriedades. Vou atualizar meu exemplo de acordo.
— Scott Ivey

2
O parâmetro CustomValidator para o nome da função javascript deve ser 'ClientValidationFunction', não 'OnClientValidate'. Consulte: msdn.microsoft.com/en-us/library/9eee01cx(v=VS.100).aspx
— Chris

1
Eu sugeriria usar, em jQuery("#<%= MyCheckBox.ClientID %>")vez de jQuery(".AcceptedAgreement input:checkbox")ser mais explícito, qual elemento você está tentando afetar.
— Jesse Webb

3
Inicialmente, não percebi que não há um atributo ControlToValidate. Incluir esse atributo causa uma exceção, portanto, uma palavra de aviso para outras pessoas que também podem não perceber isso.
— MicrosoftAccessPros.com

19

Versão C # da resposta de andrew:

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

Código por trás:

protected void CustomValidator1_ServerValidate(object source, ServerValidateEventArgs args)
{
    args.IsValid = CheckBox1.Checked;
}

obrigado pela versão C #. Bom uso de minimizar o código também.
— andrewWinn

13

Se você quiser um validador verdadeiro que não dependa do jquery e lide com a validação do lado do servidor também (e você deve. A validação do lado do servidor é a parte mais importante), então aqui está um controle

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>";
    }
}

Esta é a única resposta que funcionará em mais de um CheckBox em um formulário, ao invés de precisar de 1 função para cada objeto. Huzzah!
— Haliphax

Muito obrigado. Eu precisava de uma maneira de fazer isso com vários controles renderizados dinamicamente. Impressionante.
— schmosef

Embora a solução selecionada de Scott seja correta / válida, acredito que seja a solução mais completa. Esse controle personalizado deve ter sido incorporado à estrutura. Obrigado CirrusABS!
— Gabe

5

A resposta de Scott funcionará para classes de caixas de seleção. Se você quiser caixas de seleção individuais, precisa ser um pouco mais furtivo. Se você estiver fazendo apenas uma caixa, é melhor fazê-lo com IDs. Este exemplo faz isso por meio de caixas de seleção específicas e não requer jQuery. É também um pequeno exemplo bom de como você pode colocar esses IDs de controle irritantes em seu Javascript.

O .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>

E o código por trás:

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

3

Normalmente, eu executo a validação no lado do cliente:

<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>       

Uma das melhores soluções, pois não Postback.
— nu everest

O problema com isso é que a mensagem do validador não desaparece se você enviar, então tente e marque a caixa.
— MC9000

-1

Maneira não javascript. . página 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>

Código por trás:

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

Para quaisquer ações que você possa precisar (regras de negócios):

If Page.IsValid Then
   'do logic
End If 

Desculpe pelo código VB. . . você pode convertê-lo para C # se desejar. A empresa para a qual trabalho agora requer VB :(


3
Isso não funcionará, pois você não pode anexar um validador à caixa de seleção! DOOOH!
— 0xDEAD BEEF
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.