多个验证组,仅在控件失去焦点时验证一个。

4

摘要

我有一个单控件,带两个(几乎)相同的验证器,每个都链接到两个验证组。当光标离开控件时,ASP.NET会自动检查这两个验证器。是否有一种方法只触发一个(而不设置EnableClientScript="false"),以便在blur上没有显示两个*符号?

细节

我的表单中有两个按钮asp:btnSaveasp:btnSubmit……两个按钮都需要验证,因为某些控件必须在保存时进行验证才能正常工作。

所以我有两个验证组,一个是提交用的“默认”组(即未设置ValidationGroup属性),另一个是保存用的“SaveGroup”。有两个asp:ValidationSummary控件来反映这些内容。

在一个单独的控件上(例如设计用于接受十进制值的控件),我有以下内容。首先是提交所需的字段,然后是提交的范围验证器。然后是第三个验证器,它是范围验证器的副本,但是属于“SaveGroup”……

<asp:TextBox runat="server" id="txtMyDecVal" />
<asp:RequiredFieldValidator runat="server" ControlToValidate="txtMyDecVal" 
   Text="*" ErrorMessage="Enter a value" />
<asp:RangeValidator runat="server" ControlToValidate="txtMyDecVal" Type="Double"
   MinimumValue="0" MaximumValue="999.99" Text="*"
   ErrorMessage="Value must be between 0 and 999.99" />
<asp:RangeValidator runat="server" ControlToValidate="txtMyDecVal" Type="Double"
   MinimumValue="0" MaximumValue="999.99" Text="*"
   ErrorMessage="Value must be between 0 and 999.99"
   ValidationGroup="SaveGroup" />

这很好运作,这两个按钮的验证都是正确的。

问题在于... 如果您在控件中输入无效文本,当光标离开控件时,ASP.NET会自动触发RangeValidators的两个,导致出现两个*符号的可视化问题。

有没有办法使其中一个验证器只在控件的blur事件中检查?

我可以在一个验证器上设置EnableClientScript="false",但我仍然希望它在客户端首先检查控件而不进行后续操作。

更新

我一直在尝试将EnableClientScript = "false"设置为假,因为我认为保存时的后续操作实际上并不是重要的问题。

但是,这又会导致另一个视觉问题:输入无效文本,“提交”验证器显示*。单击“保存”,然后进行后续操作并显示“保存”验证器的*。如果您将文本更改为有效文本,则“保存”验证器不会消失,因此仍然看起来存在问题...如果您将文本更改为不同的无效文本,则会同时出现“提交”*,结果与之前相同......也就是两个*符号。


有进展了吗?这里有一些有趣的细节:http://www.codedigest.com/Articles/ASPNET/166_Restrict_AspNet_Validator_controls_to_Fire_on_Page_Submit.aspx -- 在该链接中,验证器在页面加载时被禁用,然后在(提交)控件单击时启用(可能使用特定的验证组)。 - Mayyit
3个回答

1
你应该在验证器中添加Display="Dynamic"
<asp:RequiredFieldValidator runat="server" ControlToValidate="txtMyDecVal" 
   Text="*" ErrorMessage="Enter a value" Display="Dynamic" />
<asp:RangeValidator runat="server" ControlToValidate="txtMyDecVal" Type="Double"
   MinimumValue="0" MaximumValue="999.99" Text="*"
   ErrorMessage="Value must be between 0 and 999.99" Display="Dynamic" />
<asp:RangeValidator runat="server" ControlToValidate="txtMyDecVal" Type="Double"
   MinimumValue="0" MaximumValue="999.99" Text="*"
   ErrorMessage="Value must be between 0 and 999.99"
   ValidationGroup="SaveGroup"  Display="Dynamic"/>

谢谢@Irfan,但是这样怎么才能阻止其中一个验证器在“失去焦点”事件上被触发呢?所有的“Display =“Dynamic””只会移除由“*”符号使用的空格,除非需要显示它。 - freefaller
啊,你的意思是两个不同的验证组。我以为是同一组。 - Irfan TahirKheli
1
那可以解释这种混淆...虽然我认为我在问题中提到了有多个验证组大约4次。 - freefaller

0

我也面临这个问题 - 我有:

  • 由不同按钮触发的多个验证组
  • 需要在两个组中进行验证的验证(在我的情况下是RequiredFieldValidators)

添加多个验证器的工作方式如上所述,直到您输入并随后清空字段 - 您会收到两条消息。我的解决方法如下:

覆盖IsValidationGroupMatch JavaScript方法,以允许在ValidationGroup属性中使用逗号分隔的值:

function IsValidationGroupMatch(control, validationGroup) {
    if ((typeof (validationGroup) == "undefined") || (validationGroup == null)) {
        return true;
    }
    var controlGroup = "";
    if (typeof (control.validationGroup) == "string") {
        controlGroup = control.validationGroup;
    }

    //return (controlGroup == validationGroup);

    var controlValidationGroups = controlGroup.split(",");
    return (controlValidationGroups.indexOf(validationGroup) > -1);
}

然后在ASP中添加:

<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server"
    ControlToValidate="TextBox1" ValidationGroup="VG1,VG2" Display="Dynamic">
    Text box is required
</asp:RequiredFieldValidator>
<asp:Button ID="Button1" runat="server" Text="Validate VG1"
    OnClick="Button1_Click" ValidationGroup="VG1" />
<asp:Button ID="Button2" runat="server" Text="Validate VG2"
    OnClick="Button2_Click" ValidationGroup="VG2" />

这在客户端上可以工作,但在服务器上,您需要添加自定义代码行以确保检查需要由两者验证的控件:

// controls listed as part of ValidationGroup 'VG1' will have had their
// validation tested, ones listed as 'VG1,VG2', 'VG2,VG1' etc would not
protected void Button1_Click(object sender, EventArgs e)
{
    Page.Validate("VG1,VG2");
    if (!Page.IsValid)
        return;

    // do something
}

这样,验证控件只需要添加一次,但可以为多个验证组实施。 这实际上只是一个在客户端上工作的解决方法/黑客,所有重要的服务器端验证上的额外检查将需要每次手动完成。


0

感谢Satheesh babu's artice,经过尝试了几个选项后——我认为处理复杂情况的最佳方式是自己动手。

我设置了CausesValidation="False"并从按钮中删除了ValidationGroup,然后添加了类似以下内容的代码:

    OnClientClick="if (EnableVal(['ValidationGroup1','ValidationGroup2']) == false) {return false;}"

对于客户端验证,我会在特定按钮上随着流程的进行逐步验证越来越复杂的规则。这样可以减少重复验证器。

然后,在服务器端,我会根据按钮或业务流程状态为每个组调用Page.Validate("ValidationGroup#"),最后检查Page.IsValid

此外,根据业务流程状态,可以从代码后台设置按钮的OnClientClick,具体取决于我现在想要处理哪些验证组。

最后,要合并验证摘要,请参见此处的JavaScript:Page_ClientValidate() with multiple ValidationGroups - how to show multiple summaries simultaneously?(稍作修改)。

不是非常优雅,但可能提供了最多的控制。


嗨@Mayyit - 感谢你的回答。老实说,我不记得我是如何解决它的(如果我真的解决了)。明天我回到开发机前有时间的话会检查一下。 - freefaller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接