在ASP.NET验证失败时更改文本框的CSS类

21
当附加到文本框的必填字段验证器在客户端验证失败时,如何执行一些 JavaScript? 我试图做的是更改文本框的 CSS 类,使文本框的边框显示为红色。
我正在使用 WebForms,我可以使用 jQuery 库。
6个回答

25

这是一个快速且简陋的东西(但它有效!)

<form id="form1" runat="server">
      <asp:TextBox ID="txtOne" runat="server" />
      <asp:RequiredFieldValidator ID="rfv" runat="server" 
                                 ControlToValidate="txtOne" Text="SomeText 1" />
      <asp:TextBox ID="txtTwo" runat="server" />
      <asp:RequiredFieldValidator ID="rfv2" runat="server" 
                                 ControlToValidate="txtTwo" Text="SomeText 2" />
      <asp:Button ID="btnOne" runat="server" OnClientClick="return BtnClick();" 
                                         Text="Click" CausesValidation="true" />
    </form>
    <script type="text/javascript">
        function BtnClick() {
            //var v1 = "#<%= rfv.ClientID %>";
            //var v2 = "#<%= rfv2.ClientID %>";
            var val = Page_ClientValidate();
            if (!val) {
                var i = 0;
                for (; i < Page_Validators.length; i++) {
                    if (!Page_Validators[i].isvalid) {
                        $("#" + Page_Validators[i].controltovalidate)
                         .css("background-color", "red");
                    }
                }
            }            
            return val;
        }
    </script>

我认为你的v1和v2变量没有被使用 :P - billy
是的,但这很快而且有点“肮脏” :D。只是加了注释。 - TheVillageIdiot
也许有点不太规范,但我还没有找到更好的解决方案!! :P - billy
在 for 循环之外编写 var i = 0 语句的原因是什么? - Jan Aagaard
因为在 JavaScript 中,唯一的变量作用域分隔符是函数。因此,在 for 声明内声明它是具有误导性的。 - Marco Luglio
顺便提一下,如果控件有多个验证器,您需要实现控件逻辑以避免在多个验证上覆盖样式。 - Marco Luglio

21
您可以使用以下脚本:
<script>

    $(function(){
        if (typeof ValidatorUpdateDisplay != 'undefined') {
            var originalValidatorUpdateDisplay = ValidatorUpdateDisplay;

            ValidatorUpdateDisplay = function (val) {
                if (!val.isvalid) {
                    $("#" + val.controltovalidate).css("border", "2px solid red");
                }

                originalValidatorUpdateDisplay(val);
            }
        }
    });

</script>

这段代码修饰了原始的ValidatorUpdateDisplay函数,该函数负责更新验证器的显示,必要时更新controltovalidate。

希望这可以帮助你,


8
为了使自定义样式更容易,您可以执行以下操作:$("#" + val.controltovalidate).toggleClass('error',!val.isvalid); - Grimace of Despair
+1让我省了一些谷歌时间,在这里感谢gsimoes和@GrimaceofDespair - CResults

2
我认为你需要使用一个自定义验证器,然后使用ClientValidationFunction...除非它在失败时有用地添加了CSS类。

1
重要提示:这种方法无法用于检查字段是否为空;如果要检查的字段为空,则不会触发CustomValidator。 :-( - Jez

0

这是我的解决方案。

相比其他解决方案的优点:

  • 与ASP.NET无缝集成 - 无需更改代码。只需在主页面上调用方法即可。
  • 当文本框或控件更改时,自动更改CSS类

缺点:

  • 使用了一些ASP.NET JavaScript代码的内部功能
  • 仅在ASP.NET 4.0上进行了测试

如何使用:

  • 需要 JQuery
  • 页面加载时调用“Validation_Load”函数
  • 声明一个名为“control_validation_error”的CSS类

    function Validation_Load() {
    if (typeof (Page_Validators) != "object") {
        return;
    }
    
    for (var i = 0; i < Page_Validators.length; i++) {
        var val = Page_Validators[i];
        var control = $("#" + val.controltovalidate);
        if (control.length > 0) {
            var tagName = control[0].tagName;
            if (tagName != "INPUT" && tagName != "TEXTAREA" && tagName != "SELECT") {
                // 验证子控件
            }
            else {
                // 验证控件
                control.change(function () {
                    var validators = this.Validators;
                    if (typeof (validators) == "object") {
                        var isvalid = true;
                        for (var k = 0; k < validators.length; k++) {
                            var val = validators[k];
                            if (val.isvalid != true) {
                                isvalid = false;
                                break;
                            }
                        }
                        if (isvalid == true) {
                            // 清除错误
                            $(this).removeClass("control_validation_error");
                        }
                        else {
                            // 显示错误
                            $(this).addClass("control_validation_error");
                        }
                    }
                });
            }
        }
    }
    }
    

0

前段时间我花了几个小时研究它,从那时起,我一直在使用一些自定义的js魔法来完成这个任务。

实际上,这很简单,就像ASP.NET验证工作的方式一样。基本思路是为每个你想要快速视觉反馈的控件添加一个CSS类来附加一个JavaScript事件。

<script type="text/javascript" language="javascript">
    /* Color ASP NET validation */
    function validateColor(obj) {
         var valid = obj.Validators;
         var isValid = true;

         for (i in valid)
              if (!valid[i].isvalid)
                  isValid = false;

         if (!isValid)
             $(obj).addClass('novalid', 1000);
         else
             $(obj).removeClass('novalid', 1000);
    }

    $(document).ready(function() {
        $(".validateColor").change(function() {validateColor(this);});
    });
</script>

例如,这将是在ASP.Net文本框控件上添加的代码。是的,您可以添加任意数量,并且它只会暗示添加一个CssClass值。
<asp:TextBox ID="txtBxEmail" runat="server" CssClass="validateColor" />

它的功能是在工作控件发生更改并且无效时应用CSS类触发ASP.Net客户端验证。因此,要定制可视化效果,您可以依赖于CSS。
.novalid {
    border: 2px solid #D00000;
}

它不是完美的,但几乎是 :) 至少您的代码不会受到额外的东西的影响。而且最好的是,它可以与所有类型的Asp.Net验证器一起使用,甚至是自定义验证器。

我在谷歌上没有看到类似的东西,所以我想与您分享我的技巧。希望它有所帮助。

服务器端的额外内容

使用一段时间后,当需要对某些可能仅在服务器端检查的事物进行特定验证时,我还会从代码后台添加此“.novalid”css类:

Page.Validate();
    if (!requiredFecha.IsValid || !CustomValidateFecha.IsValid)
        txtFecha.CssClass = "validateColor novalid";
    else
        txtFecha.CssClass = "validateColor";

如果用户没有输入任何内容并提交页面,那么这段代码将无法在提交时进行验证... - HasanG
@HasanGürsoy 我写了很久以前,但主要的想法是在标准ASP.net控件上添加一些行为。我猜你也可以在任何提交元素上添加一些onClick行为来触发调用该函数。 - guillem
嗯,是的,谢谢。但我猜它会引起与我在这里提出的问题相同的错误:https://dev59.com/p4Hba4cB1Zd3GeqPMRG8 - HasanG
@HasanGürsoy 如果您需要一个自定义验证器,那么肯定需要这样做。 - guillem

-2

或者,您可以按照以下方式迭代页面控件:(需要使用System.Collections.Generic引用)

const string CSSCLASS = " error";    

protected static Control FindControlIterative(Control root, string id)
{
   Control ctl = root;
   LinkedList<Control> ctls = new LinkedList<Control>();
   while ( ctl != null )
   {
     if ( ctl.ID == id ) return ctl;
     foreach ( Control child in ctl.Controls )
     {
       if ( child.ID == id ) return child;
       if ( child.HasControls() ) ctls.AddLast(child);
     }
     ctl = ctls.First.Value;
     ctls.Remove(ctl);
   }
   return null;
}



protected void Page_PreRender(object sender, EventArgs e)
{
  //Add css classes to invalid items
  if ( Page.IsPostBack && !Page.IsValid )
  {
    foreach ( BaseValidator item in Page.Validators )
    {
       var ctrltoVal = (WebControl)FindControlIterative(Page.Form, item.ControlToValidate);
       if ( !item.IsValid ) ctrltoVal.CssClass += " N";
       else ctrltoVal.CssClass.Replace(" N", "");
    }
  }
}

这应该适用于大多数情况,并且意味着您在添加验证器时无需更新它。我已将此代码添加到自定义Pageclass中,因此它可以在任何我已添加验证器的页面上全站运行。


1
遍历页面上的每个控件非常低效,我认为你不应该这样做。 - Ben Cameron

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