【问题标题】:Change textbox's css class when ASP.NET Validation failsASP.NET 验证失败时更改文本框的 css 类
【发布时间】:2010-11-21 01:14:59
【问题描述】:

当附加到文本框的必填字段验证器未通过客户端验证时,如何执行一些 javascript?我要做的是更改文本框的 css 类,使文本框的边框显示为红色。

我正在使用网络表单,并且我确实可以使用 jquery 库。

【问题讨论】:

    标签: asp.net javascript jquery validation webforms


    【解决方案1】:

    这是一个快速而肮脏的东西(但它有效!)

    <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
    • 是的,但这很快而且 :D。刚刚评论了他们。
    • 可能很脏,但我还没有找到更好的解决方案! :P
    • 在for循环之外写var i = 0语句的原因是什么?
    • 因为js中唯一的变量作用域分隔符就是函数。所以在 for 声明中声明它是有误导性的。
    【解决方案2】:

    您可以使用以下脚本:

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

    希望对你有帮助,

    【讨论】:

    • 要启用更简单的自定义样式,您可以执行以下操作:$("#" + val.controltovalidate).toggleClass('error', !val.isvalid);
    • +1 为我节省了一些 Google 时间,谢谢 gsimoes 和 @GrimaceofDespair
    【解决方案3】:

    我想你会想使用 Custom Validator 然后使用 ClientValidationFunction...除非它在失败时添加一个 CSS 类。

    【讨论】:

    • 重要提示:这不适用于尝试检查字段是否为空;如果要检查的字段为空,则不会触发 CustomValidator。 :-(
    【解决方案4】:

    前段时间我花了几个小时在上面,从那以后我一直在使用一些自定义的 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" />
    

    它的作用是在工作控件发生更改时触发 ASP.Net 客户端验证,并在其无效时应用 css 类。因此,要自定义可视化,您可以依赖 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ürsoy 我很久以前写过这篇文章,但主要是为了在标准 ASP.net 控件上添加一些行为。我想您也可以在任何提交元素上添加一些 onClick 行为来触发调用该函数。
    • 嗯,是的,谢谢。但我想这会导致与我在这里问的相同的错误:stackoverflow.com/questions/24477219/…
    • @HasanGürsoy 当然你可能需要一个自定义验证器
    【解决方案5】:

    这是我的解决方案。

    相对于其他解决方案的优势:

    • 与 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") {
                  // Validate sub controls
              }
              else {
                  // Validate the control
                  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) {
                              // Clear the error
                              $(this).removeClass("control_validation_error");
                          }
                          else {
                              // Show the error
                              $(this).addClass("control_validation_error");
                          }
                      }
                  });
              }
          }
      }
      }
      

    【讨论】:

      【解决方案6】:

      或者,只需按如下方式遍历页面控件:(需要使用 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", "");
          }
        }
      }
      

      应该适用于大多数情况,这意味着您在添加验证器时不必更新它。我已将此代码添加到 cstom Pageclass 中,因此它可以在我添加了验证器的任何页面上运行站点范围。

      【讨论】:

      • 遍历页面上的每个控件效率非常低,我认为您不应该这样做。
      猜你喜欢
      • 2011-01-10
      • 2015-04-21
      • 2012-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-05
      • 2011-02-19
      相关资源
      最近更新 更多