简体   繁体   English

Gridview中的必填字段验证器取决于条件c#

[英]Required Field Validator in Gridview depend on condition c#

I have a required field validator in a Gridview. 我在Gridview中有一个必需的字段验证器。 I want fire the validater only if the ddlPartsStatus is "Ordered". 我仅在ddlPartsStatus为“已订购”时才触发验证器。 I just can't get it to work. 我就是无法正常工作。

At the moment required field validator fires for all the textboxes. 目前,所有文本框都需要字段验证器。

my code 我的密码

<asp:GridView ID="gvPartsToOrderDetail" CssClass="gvPartsToOrderDetail" runat="server" AutoGenerateColumns="false" OnRowDataBound="gvPartsToOrderDetail_RowDataBound">
    <Columns>
        <asp:TemplateField HeaderText="Ticket Number">
            <ItemTemplate>
                <asp:TextBox ID="txtTicketNo" Text='<%# Eval("TicketNo") %>' runat="server"></asp:TextBox>
                <asp:RequiredFieldValidator ID="rfvTxtTicketNo" runat="server" ForeColor="Red" Font-Bold="true" Font-Size="Medium" ErrorMessage="*" ControlToValidate="txtTicketNo" ValidationGroup="Submit"></asp:RequiredFieldValidator>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Parts Status">
            <ItemTemplate>
                <asp:DropDownList ID="ddlPartStatus" runat="server" AutoPostBack="true">
                    <asp:ListItem Value="0" Text="-Select-"></asp:ListItem>
                    <asp:ListItem Value="1" Text="Ordered"></asp:ListItem>
                </asp:DropDownList>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

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

Any help is greatly appreciated. 任何帮助是极大的赞赏。 Thanks 谢谢

For this you need a CustomValidator . 为此,您需要一个CustomValidator Then the ClientValidationFunction should evaluate both the TextBox and the DropDownList. 然后, ClientValidationFunction应该评估TextBox和DropDownList。

<asp:CustomValidator ID="CustomValidator1" runat="server" ErrorMessage="*" 
    ValidationGroup="Submit" ControlToValidate="txtTicketNo" 
    ClientValidationFunction="checkValuesInRow" ValidateEmptyText="true"></asp:CustomValidator>

<script type="text/javascript">
    function checkValuesInRow(sender, element) {
        var isValid = false;
        var ddlValue = $("#" + sender.controltovalidate).closest('tr').find('select').val();
        if (element.Value === "" && ddlValue === "0") {
            isValid = true;
        }
        element.IsValid = isValid;
    }
</script>

NOTE: Further reading is intended to be informative and not practical given all the clicking that must happen. 注意:鉴于必须进行所有单击,进一步阅读旨在提供信息,而不是实用的。 But it shows how things can be done, not necessarily how the should be done and is only here due to the OP's Request for more info...so, here we go 但它显示了怎样的事情可以做,不一定如何应该做的,是只有在这里,由于OP的要求提供详细信息...所以,在这里我们去

Given this GridView <ItemTemplate> : 鉴于此GridView <ItemTemplate>

    <asp:TextBox ID="tbxTicketNo" runat="server" Text='<%# Bind("TicketNo") %>'></asp:TextBox>
    <asp:RequiredFieldValidator ID="rfvTxtTicketNo" runat="server" 
        ErrorMessage="RequiredFieldValidator" Text="*"
        ControlToValidate="tbxTicketNo"
        InitialValue="0"
        ValidationGroup="vgSubmit">
    </asp:RequiredFieldValidator>

Renders a table with x number of validators based on your row count. 根据您的行数渲染一个带有x个验证器的表。 You can use your browser's Developers Tools to inspect gvPartsToOrderDetail where you will find something similar to this, note the data-val-validationgroup attributes on all rows: 您可以使用浏览器的开发人员工具检查gvPartsToOrderDetail ,在其中您可以找到类似的内容,请注意所有行上的data-val-validationgroup属性:

    <span 
      data-val-controltovalidate="ContentPlaceHolder1_gvPartsToOrderDetail_tbxTicketNo_0" 
      data-val-errormessage="RequiredFieldValidator" 
      data-val-validationgroup="vgSubmit"
      id="ContentPlaceHolder1_gvPartsToOrderDetail_rfvTxtTicketNo_0" 
      data-val="true" 
      data-val-evaluationfunction="RequiredFieldValidatorEvaluateIsValid" 
      data-val-initialvalue="0" style="visibility:hidden;">*</span>

Do you see that data-val-validationgroup="vgSubmit" is not unique? 您看到data-val-validationgroup="vgSubmit"不是唯一的吗? So when you click btnSubmit with its ValidationGroup set to "vgSubmit", they all get triggered. 因此,当您将btnSubmitValidationGroup设置为“ vgSubmit”时,它们都会被触发。

Now given @VDWWD's answer you may well prefer to keep it this way. 现在给出@VDWWD的答案,您可能更希望保持这种方式。 And that's perfectly fine and legal and likely more in line with your needs. 这完全是合法的,并且可能更符合您的需求。

But to address the non-uniqueness of the Validation Group you can do this in the markup instead: 但是要解决验证组的非唯一性,您可以在标记中执行以下操作:

    <asp:RequiredFieldValidator ID="rfvTxtTicketNo" runat="server" 
        ...
        ValidationGroup='<%# string.Format("Submit_{0}", Container.DataItemIndex) %>'>
    </asp:RequiredFieldValidator>

which will then render: 然后将呈现:

<span ... data-val-validationgroup="Submit_0" ... </span>
<span ... data-val-validationgroup="Submit_1" ... </span>
<span ... data-val-validationgroup="Submit_2" ... </span>

But now you have design problem. 但是现在您遇到了设计问题。 To isolate the validation group in the gridview and to tie it to your submit button you need to select a row, which means introducing a Select command button. 要在gridview中隔离验证组并将其与您的Submit按钮绑定,您需要选择一行,这意味着要引入Select命令按钮。 More clicks, not good, but it can be done. 点击次数较多,效果不好,但是可以做到。 But this introduces a couple of more issues: 但这引入了更多其他问题:

1. How do you tell the Submit button which validation group to validate?
2. Also the Submit button has a nasty habit of Posting back regardless of validation.

Both can be fixed like this: 两者都可以这样修复:

    <asp:Button ID="btnSubmit" runat="server" Text="Button" 
        OnClientClick="return Page_ClientValidate('vgSubmit_1')" />

which is generated programmatically in btnSubmit_PreRender as follows: 它在btnSubmit_PreRender以编程方式生成,如下所示:

    protected void btnSubmit_PreRender( object sender, EventArgs e )
    {
        btnSubmit.OnClientClick = string.Format( "return Page_ClientValidate('vgSubmit_{0}')", gvPartsToOrderDetail.SelectedIndex );
    }

What follows is the Code behind and the page markup for review: 以下是后面的代码和要查看的页面标记:

To sum up, this solution, if you can call it that: 综上所述,如果您可以这样称呼,则此解决方案:

  1. Unique validation group names PER ROW 唯一的验证组名称PER ROW
  2. Requires the addition of a selected row 需要添加选定的行
  3. Rendering the Submit button to prevent postbacks and isolate the appropriate validation group 呈现“提交”按钮以防止回发并隔离适当的验证组

I can only hope this was at least informative and maybe gave you some ideas about the versatility of Server controls. 我只能希望这至少能为您提供信息,并可能为您提供有关Server控件多功能性的一些想法。

Happy Programming... 快乐编程...

Code behind: 后面的代码:

namespace WebApplication3
{
    public partial class _Default : Page
    {
        protected void Page_Load( object sender, EventArgs e )
        {
            if ( !Page.IsPostBack )
            {
                List<Parts> ListOfParts = new List<Parts>( new Parts[ ] {
                            new Parts(0, 0),
                            new Parts(0, 0),            
                            new Parts(0, 0) } );

                gvPartsToOrderDetail.DataSource = ListOfParts;
                gvPartsToOrderDetail.DataBind();
            }
        }

        protected void Button1_PreRender( object sender, EventArgs e )
        {
            Button1.OnClientClick = string.Format( "return Page_ClientValidate('vgSubmit_{0}')", gvPartsToOrderDetail.SelectedIndex );
        }
    }

    //------------------------------------------------------------
    // Dummy data class
    //
    public class Parts {
        public Parts( int ticketNo, int status ) {
            TicketNo = ticketNo;
            Status = status;
        }

        public int TicketNo { get; set; }
        public int Status { get; set; }
    }
}

And the Markup: 和标记:

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site1.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication3._Default" %>

<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="ContentPlaceHolder1">
    <asp:GridView ID="gvPartsToOrderDetail" runat="server" AutoGenerateColumns="False" 
        AutoGenerateSelectButton="True" ClientIDMode="Predictable">
        <Columns>
            <asp:TemplateField HeaderText="Ticket">
                <ItemTemplate>
                    <asp:TextBox ID="tbxTicketNo" runat="server" Text='<%# Bind("TicketNo") %>'></asp:TextBox>
                    <asp:RequiredFieldValidator ID="rfvTxtTicketNo" runat="server" 
                        ErrorMessage="RequiredFieldValidator" Text="*"
                        ControlToValidate="tbxTicketNo"
                        ValidationGroup='<%# string.Format("vgSubmit_{0}", Container.DataItemIndex) %>'>
                    </asp:RequiredFieldValidator>

                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Parts Status">
                <ItemTemplate>
                    <asp:DropDownList ID="ddlPartStatus" runat="server">
                        <asp:ListItem Text="[ Select ]" Value="0"></asp:ListItem>
                        <asp:ListItem Text="Ordered" Value="1"></asp:ListItem>
                    </asp:DropDownList>
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>

    </asp:GridView>

    <asp:Button ID="btnSubmit" runat="server" Text="Button" 
        OnClientClick='See code in PreRender' 
        OnPreRender="btnSubmit_PreRender" />

</asp:Content>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM