使用必填字段验证器更改文本框颜色。请勿使用扩展控件。

24

每当单击“提交”按钮时,需要字段验证器触发时更改文本框的颜色。


我使用了这个:https://gist.github.com/meziantou/1755cd2d21c8a1d1d148 - H.Wolper
17个回答

26
你可以注册一个 JavaScript 函数,在提交后迭代全局的 Page_Validators 数组,并根据需要设置背景。这种方法的好处是可以在页面上的所有控件上使用它。该函数如下所示:
function fnOnUpdateValidators()
{
   for (var i = 0; i < Page_Validators.length; i++)
   {
      var val = Page_Validators[i];
      var ctrl = document.getElementById(val.controltovalidate);
      if (ctrl != null && ctrl.style != null)
      {
         if (!val.isvalid)
            ctrl.style.background = '#FFAAAA';
         else
            ctrl.style.backgroundColor = '';
      }
   }
}

最后一步是将脚本注册到 OnSubmit 事件:

VB.NET:

Page.ClientScript.RegisterOnSubmitStatement(Me.GetType, "val", "fnOnUpdateValidators();")

C#:

Page.ClientScript.RegisterOnSubmitStatement(this.GetType(), "val", "fnOnUpdateValidators();");

你将会在所有的代码后端中保持正确的IsValid状态,并且它可以与所有控件一起工作。

注意:我从这篇博客中找到了这个解决方案。我只是想将其记录在这里,以防源博客失效。


1
我喜欢这个解决方案 - 我自己做的一个改变是允许控件有多个验证器。还不能编辑帖子,所以不确定如何分享它。 - Dieter G
WebForm_OnSubmit在哪里?我已经搜索了整个项目,但找不到它的引用。 - sQuijeW
@sQuijeW 你使用了上面的“final step”代码吗?那将会把该操作注册到相应的事件中。 - Dillie-O
@Dillie-O,我需要在代码中编写最后一条语句(page.clien.....),请问这是在代码后台文件中吗?你能帮忙吗? - Glory Raj
@pratapk,您需要将该Page.ClientScript代码放置在代码后台文件的Page_Load方法中,以便在回发后始终注册脚本。 - Dillie-O
提交页面需要按两次提交按钮,这很不完美。 - Giox

18

您可以非常容易地覆盖ASP.NET更新已验证字段的显示的JavaScript函数。这是一个不错的选择,因为您可以保留现有的字段验证器,而无需编写任何自定义验证逻辑或查找要验证的字段。在下面的示例中,我将向具有类“control-group”的父元素添加/删除“error”类(因为我正在使用Twitter Bootstrap CSS):

    /**
    * Re-assigns the ASP.NET validation JS function to
    * provide a more flexible approach
    */
    function UpgradeASPNETValidation() {
        if (typeof (Page_ClientValidate) != "undefined") {
            AspValidatorUpdateDisplay = ValidatorUpdateDisplay;
            ValidatorUpdateDisplay = NicerValidatorUpdateDisplay;
        }
    }

    /**
    * This function is called once for each Field Validator, passing in the 
    * Field Validator span, which has helpful properties 'isvalid' (bool) and
    * 'controltovalidate' (string = id of the input field to validate).
    */
    function NicerValidatorUpdateDisplay(val) {
        // Do the default asp.net display of validation errors (remove if you want)
        AspValidatorUpdateDisplay(val);

        // Add our custom display of validation errors
        if (val.isvalid) {
            // do whatever you want for invalid controls
            $('#' + val.controltovalidate).closest('.control-group').removeClass('error');
        } else {
            // reset invalid controls so they display as valid
            $('#' + val.controltovalidate).closest('.control-group').addClass('error');
        }
    }

    // Call UpgradeASPNETValidation after the page has loaded so that it 
    // runs after the standard ASP.NET scripts.
    $(document).ready(UpgradeASPNETValidation);

这是从这里稍作修改并结合这些文章中的有用信息得到的。


当控件有多个验证器时,它的工作方式不正确。 - Der_Meister
这是一个很好的想法。我一直在尝试找到一种方法来劫持现有的验证机制,而这正是完美的解决方案。只要这些函数名不会改变就可以了。谢谢!不过我认为你把关于有效/无效的评论搞反了。 - xr280xr

13

你可以使用CustomValidator代替RequiredFieldValidator:

.ASPX

<asp:CustomValidator ID="CustomValidator1" runat="server" ErrorMessage=""
    ControlToValidate="TextBox1" ClientValidationFunction="ValidateTextBox"
    OnServerValidate="CustomValidator1_ServerValidate"
    ValidateEmptyText="True"></asp:CustomValidator>

<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>

<script src="jquery-1.2.6.js" type="text/javascript"></script>
<script type="text/javascript">
    function ValidateTextBox(source, args)
    {
        var is_valid = $("#TextBox1").val() != "";
        $("#TextBox1").css("background-color", is_valid ? "white" : "red");
        args.IsValid = is_valid;
    }
</script>

.CS

:这是一个文件扩展名,通常用于C#编程语言中的源代码文件。
protected void CustomValidator1_ServerValidate(object source, ServerValidateEventArgs args)
{
    bool is_valid = TextBox1.Text != "";
    TextBox1.BackColor = is_valid ? Color.White : Color.Red;
    args.IsValid = is_valid;
}

客户端和服务器的验证函数逻辑相同,但客户端函数使用jQuery访问文本框的值并修改其背景颜色。


2
如果没有安装jQuery,您可以使用以下代码进行文本框验证:function ValidateTextBox(source, args) { var target = document.getElementById("TextBox1"); var is_valid = target.value != ""; if( is_valid ){ target.style.backgroundColor = "White"; }else{ target.style.backgroundColor = "Red"; } args.IsValid = is_valid; } - Travis J
如果无效,这会防止回发吗? - DevDave

5
非常晚才加入这个派对,但以防其他人偶然发现并想要一个可以与Bootstrap配合使用的完整答案,我已经采用了上面所有的例子,并制作了一个版本,它可以与多个验证器连接到一个单独的控件上,并且可以在验证组中起作用:
<script>
    /**
    * Re-assigns the ASP.NET validation JS function to
    * provide a more flexible approach
    */
    function UpgradeASPNETValidation() {
        if (typeof (Page_ClientValidate) != "undefined") {
            AspValidatorUpdateDisplay = ValidatorUpdateDisplay;
            ValidatorUpdateDisplay = NicerValidatorUpdateDisplay;
            AspValidatorValidate = ValidatorValidate;
            ValidatorValidate = NicerValidatorValidate;

            // Remove the error class on each control group before validating
            // Store a reference to the ClientValidate function
            var origValidate = Page_ClientValidate;
            // Override with our custom version
            Page_ClientValidate = function (validationGroup) {
                // Clear all the validation classes for this validation group
                for (var i = 0; i < Page_Validators.length; i++) {
                    if ((typeof(Page_Validators[i].validationGroup) == 'undefined' && !validationGroup) ||
                        Page_Validators[i].validationGroup == validationGroup) {
                        $("#" + Page_Validators[i].controltovalidate).parents('.form-group').each(function () {
                            $(this).removeClass('has-error');
                        });
                    }
                }
                // Call the original function
                origValidate(validationGroup);
            };
        }
    }

    /**
    * This function is called once for each Field Validator, passing in the 
    * Field Validator span, which has helpful properties 'isvalid' (bool) and
    * 'controltovalidate' (string = id of the input field to validate).
    */
    function NicerValidatorUpdateDisplay(val) {
        // Do the default asp.net display of validation errors (remove if you want)
        AspValidatorUpdateDisplay(val);

        // Add our custom display of validation errors
        // IF we should be paying any attention to this validator at all
        if ((typeof (val.enabled) == "undefined" || val.enabled != false) && IsValidationGroupMatch(val, AspValidatorValidating)) {
            if (!val.isvalid) {
                // Set css class for invalid controls
                var t = $('#' + val.controltovalidate).parents('.form-group:first');
                t.addClass('has-error');
            }
        }
    }

    function NicerValidatorValidate(val, validationGroup, event) {
        AspValidatorValidating = validationGroup;
        AspValidatorValidate(val, validationGroup, event);
    }

    // Call UpgradeASPNETValidation after the page has loaded so that it 
    // runs after the standard ASP.NET scripts.
    $(function () {
        UpgradeASPNETValidation();
    });
</script>

4

我喜欢Rory的答案,但在我的情况下,它与ValidationGroups不兼容,因为我在一个字段上有两个由两个不同按钮触发的验证器。

问题在于,如果ValidatorValidate不在当前ValidationGroup中,它将把验证器标记为“isValid”,但我们的类更改代码没有注意到这一点。这意味着显示不正确(特别是IE9似乎不想播放)。

因此,为了解决这个问题,我进行了以下更改:

    /**
    * Re-assigns the ASP.NET validation JS function to
    * provide a more flexible approach
    */
    function UpgradeASPNETValidation() {
        if (typeof (Page_ClientValidate) != "undefined") {
            AspValidatorUpdateDisplay = ValidatorUpdateDisplay;
            ValidatorUpdateDisplay = NicerValidatorUpdateDisplay;
            AspValidatorValidate = ValidatorValidate;
            ValidatorValidate = NicerValidatorValidate;
        }
    }

    /**
    * This function is called once for each Field Validator, passing in the 
    * Field Validator span, which has helpful properties 'isvalid' (bool) and
    * 'controltovalidate' (string = id of the input field to validate).
    */
    function NicerValidatorUpdateDisplay(val) {
        // Do the default asp.net display of validation errors (remove if you want)
        AspValidatorUpdateDisplay(val);

        // Add our custom display of validation errors
        // IF we should be paying any attention to this validator at all
        if ((typeof (val.enabled) == "undefined" || val.enabled != false) && IsValidationGroupMatch(val, AspValidatorValidating)) {
            if (val.isvalid) {
                // do whatever you want for invalid controls
                $('#' + val.controltovalidate).parents('.control-group:first').removeClass('error');
            } else {
                // reset invalid controls so they display as valid
                //$('#' + val.controltovalidate).parents('.control-group:first').addClass('error');
                var t = $('#' + val.controltovalidate).parents('.control-group:first');
                t.addClass('error');
            }
        }
    }

    function NicerValidatorValidate(val, validationGroup, event) {
        AspValidatorValidating = validationGroup;
        AspValidatorValidate(val, validationGroup, event);
    }

    // Call UpgradeASPNETValidation after the page has loaded so that it 
    // runs after the standard ASP.NET scripts.
    $(document).ready(UpgradeASPNETValidation);

非常好!但是,如果我有多个验证器与一个控件相关联,它会对我产生影响。只有最后一个验证器起作用,因为它会覆盖之前的任何验证器(即使之前的某个验证器失败,它也会在有效时删除CSS类)。 - Leigh Bowers

4
在 CSS 中:
       .form-control
        {
            width: 100px;
            height: 34px;
            padding: 6px 12px;
            font-size: 14px;
            color: black;
            background-color: white;
        }
        .form-control-Error
        {
            width: 100px;
            height: 34px;
            padding: 6px 12px;
            font-size: 14px;
            color: #EBB8C4;
            background-color: #F9F2F4
            border: 1px solid #DB7791;
            border-radius: 4px;
        }

在您的页面中:

<asp:TextBox ID="txtUserName" runat="server" CssClass="form-control"></asp:TextBox>
 <asp:RequiredFieldValidatorrunat="server"Display="Dynamic" ErrorMessage="PLease Enter UserName" ControlToValidate="txtUserName"></asp:RequiredFieldValidator>

在你的页面结尾,在上面添加:
<script type="text/javascript">
    function WebForm_OnSubmit() {
        if (typeof (ValidatorOnSubmit) == "function" && ValidatorOnSubmit() == false) {
            for (var i in Page_Validators) {
                try {
                    var control = document.getElementById(Page_Validators[i].controltovalidate);
                    if (!Page_Validators[i].isvalid) {
                        control.className = "form-control-Error";
                    } else {
                        control.className = "form-control";
                    }
                } catch (e) { }
            }
            return false;
        }
        return true;
    }
</script>

3

我喜欢亚历山大的答案,但希望javascript更加通用。因此,这里提供一种通用的方法来消耗自定义验证器中的错误。

    function ValidateTextBox(source, args) {
        var cntrl_id = $(source).attr("controltovalidate");
        var cntrl = $("#" + cntrl_id);
        var is_valid = $(cntrl).val() != "";
        is_valid ? $(cntrl).removeClass("error") : $(cntrl).addClass("error");

        args.IsValid = is_valid;
    }

2

我知道这已经有点老了,但是我有另一种修改版的组合来自Dillie-O和Alexander。 这使用jQuery与模糊事件来在验证成功时移除样式。

function validateFields() {
    try {
        var count = 0;
        var hasFocus = false;

        for (var i = 0; i < Page_Validators.length; i++) {
            var val = Page_Validators[i];
            var ctrl = document.getElementById(val.controltovalidate);

            validateField(ctrl, val);

            if (!val.isvalid) { count++; }
            if (!val.isvalid && hasFocus === false) {
                ctrl.focus(); hasFocus = true;
            }
        }

        if (count == 0) {
            hasFocus = false;
        }
    }
    catch (err) { }
}

function validateField(ctrl, val)
{
    $(ctrl).blur(function () { validateField(ctrl, val); });

    if (ctrl != null && $(ctrl).is(':disabled') == false) { // && ctrl.style != null
        val.isvalid ? $(ctrl).removeClass("error") : $(ctrl).addClass("error");
    }            

    if ($(ctrl).hasClass('rdfd_') == true) { //This is a RadNumericTextBox
        var rtxt = document.getElementById(val.controltovalidate + '_text');
        val.isvalid ? $(rtxt).removeClass("error") : $(rtxt).addClass("error");
    }
}

2
另一种可能性是......这段代码会给需要验证的控件(下拉列表和文本框等)添加红色边框(或者你在CSS类中定义的其他样式)。首先,我使用了 CustomValidator 而不是 RequiredFieldValidator,因为这样可以使用 CustomValidator 的 ClientValidationFunction 来更改要验证的控件的 CSS 样式。例如:当用户忘记填写 MyTextBox 文本框时,可以更改其边框颜色。MyTextBox 控件的 CustomValidator 如下所示:
<asp:CustomValidator ID="CustomValidatorMyTextBox" runat="server" ErrorMessage=""
     Display="None" ClientValidationFunction="ValidateInput" 
     ControlToValidate="MyTextBox" ValidateEmptyText="true" 
     ValidationGroup="MyValidationGroup">
     </asp:CustomValidator>

或者它也可以用于下拉列表,需要进行选择的情况。CustomValidator与上面相同,但ControlToValidate指向下拉列表。

对于客户端脚本,请使用JQuery。ValidateInput方法如下:

    <script type="text/javascript">
    function ValidateInput(source, args)
    {
        var controlName = source.controltovalidate;
        var control = $('#' + controlName);
        if (control.is('input:text')) {
            if (control.val() == "") {
                control.addClass("validation");
                args.IsValid = false;
            }
            else {
                control.removeClass("validation");
                args.IsValid = true;
            }
        }
        else if (control.is('select')) {
            if (control.val() == "-1"[*] ) {
                control.addClass("validation");
                args.IsValid = false;
            }
            else {
                control.removeClass("validation");
                args.IsValid = true;
            }
        }
    }
    </script>

“validation”类是一个包含验证器触发时标记的CSS类。它可能看起来像这样:

.validation { border: solid 2px red; }

PS:为了使下拉列表在IE中的边框颜色生效,请在页面头部添加以下meta标签:<meta http-equiv="X-UA-Compatible" content="IE=edge" />

[*]这与RequiredFieldValidator的“InitialValue”相同。当用户尚未选择任何内容时,这是默认选择的项目。


1

我也喜欢亚历山大和史蒂夫的答案,但我想要与代码后台相同的结果。我认为这段代码可能可以实现,但它取决于您的设置。我的控件位于内容占位符内。

protected void cvPhone_ServerValidate(object source, ServerValidateEventArgs args)
{
    bool is_valid = !string.IsNullOrEmpty(args.Value);
    string control = ((CustomValidator)source).ControlToValidate;
    ((TextBox)this.Master.FindControl("ContentBody").FindControl(control)).CssClass = is_valid ? string.Empty : "inputError";
    args.IsValid = is_valid;
}

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