Change Text Box Color using Required Field Validator. No Extender Controls Please

佐手、 提交于 2019-11-26 08:10:49

问题


I need to change color of TextBox whenever its required field validator is fired on Clicking the Submit button


回答1:


What you can do is register a Javascript function that will iterate through the global Page_Validators array after submission and you can set the background appropriately. The nice thing about this is that you can use it on all of your controls on the page. The function looks like this:

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 = '';
      }
   }
}

The final step is to register the script with the OnSubmit event:

VB.NET:

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

C#:

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

You'll maintain the proper IsValid status in all of your code behind and it can work with all of your controls.

Note: I found this solution from the following blog. I just wanted to document it here in the event the source blog goes down.




回答2:


You can very easily override ASP.NET's javascript function that updates the display of validated fields. This is a nice option as you can keep your existing Field Validators, and don't have to write any custom validation logic or go looking for the fields to validate. In the example below I'm adding/removing an 'error' class from the parent element that has class 'control-group' (because I'm using 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);

This is adapted ever-so-slightly from here and with helpful info from these articles.




回答3:


You could use CustomValidator instead of 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

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;
}

Logic in client and server validation functions is the same, but the client function uses jQuery to access textbox value and modify its background color.




回答4:


Very late to the party, but just in case someone else stumbles across this and wants a complete answer which works with Bootstrap, I've taken all the examples above, and made a version which will work with multiple validators attached to a single control, and will work with validation groups:

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



回答5:


I liked Rory's answer, but it doesn't work well with ValidationGroups, certainly in my instance where I have two validators on one field triggered by two different buttons.

The problem is that ValidatorValidate will mark the validator as 'isValid' if it is not in the current ValidationGroup, but our class-changing code does not pay any attention. This meant the the display was not correct (certainly IE9 seems to not like to play).

so to get around it I made the following changes:

    /**
    * 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);



回答6:


in 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;
        }

in your page:

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

at the end of your page above of

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



回答7:


I liked Alexander's answer, but wanted the javascript to be more generic. So, here is a generic way of consuming the errors from a custom validator.

    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;
    }



回答8:


Another possibility... this code gives a red border (or whatever you put inside the CSS class) to the control to validate (works for dropdownlists and textbox, but can be extended for buttons etc...)

First of, I make use of a CustomValidator instead of a RequiredFieldValidator, because then you can use the ClientValidationFunction of the CustomValidator to change the CSS of the control to validate.

For example: change the border of a textbox MyTextBox when a user forgot to fill it in. The CustomValidator for the MyTextBox control would look like this:

<asp:CustomValidator ID="CustomValidatorMyTextBox" runat="server" ErrorMessage=""
     Display="None" ClientValidationFunction="ValidateInput" 
     ControlToValidate="MyTextBox" ValidateEmptyText="true" 
     ValidationGroup="MyValidationGroup">
     </asp:CustomValidator>

Or it could also work for a dropdownlist in which a selection is required. The CustomValidator would look the same as above, but with the ControlToValidate pointing to the dropdownlist.

For the client-side script, make use of JQuery. The ValidateInput method would look like this:

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

The “validation” class is a CSS class that contains the markup when the validator is fired. It could look like this:

.validation { border: solid 2px red; }

PS: to make the border color work for the dropdown list in IE, add the following meta tag to the page's heading: <meta http-equiv="X-UA-Compatible" content="IE=edge" />.

[*]This is the same as the “InitialValue” of a RequiredFieldValidator. This is the item that is selected as default when the user hasn’t selected anything yet.​




回答9:


I know this is old, but I have another modified combination from Dillie-O and Alexander. This uses jQuery with the blur event to remove the style when validation succeeds.

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");
    }
}



回答10:


I too liked Alexanders and Steves answer but I wanted the same as in codebehind. I think this code might do it but it differes depending on your setup. My controls are inside a contentplaceholder.

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;
}



回答11:


Another way,

$(document).ready(function() {
    HighlightControlToValidate();
    $('#<%=btnSave.ClientID %>').click(function() {
        if (typeof (Page_Validators) != "undefined") {
            for (var i = 0; i < Page_Validators.length; i++) {
                if (!Page_Validators[i].isvalid) {
                    $('#' + Page_Validators[i].controltovalidate).css("background", "#f3d74f");
                }
                else {
                    $('#' + Page_Validators[i].controltovalidate).css("background", "white");
                }
            }
        }
    });
});

Reference: http://www.codedigest.com/Articles/ASPNET/414_Highlight_Input_Controls_when_Validation_fails_in_AspNet_Validator_controls.aspx




回答12:


I made a working one pager example of this for regular asp.net, no .control-group

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html>
<!-- http://stackoverflow.com/questions/196859/change-text-box-color-using-required-field-validator-no-extender-controls-pleas -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
    <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;
            }
        }

        /**
        * 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).removeClass('error');
                } else {
                    // reset invalid controls so they display as valid
                    //$('#' + val.controltovalidate).parents('.control-group:first').addClass('error');
                    var t = $('#' + val.controltovalidate);
                    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);
    </script>
    <style>
        .error {
            border: 1px solid red;
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <div>

        <asp:TextBox ID="TextBox1" runat="server" ></asp:TextBox>
        <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="TextBox1" ErrorMessage="RequiredFieldValidator"></asp:RequiredFieldValidator>
        <asp:Button ID="Button1" runat="server" Text="Button" />

        <br />
        <asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
        <asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server" ControlToValidate="TextBox2" ErrorMessage="RegularExpressionValidator" ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"></asp:RegularExpressionValidator>
        <br />
        <asp:TextBox ID="TextBox3" runat="server"></asp:TextBox>
        <asp:RangeValidator ID="RangeValidator1" runat="server" ControlToValidate="TextBox3" ErrorMessage="RangeValidator" MaximumValue="100" MinimumValue="0"></asp:RangeValidator>

    </div>
    </form>
</body>
</html>



回答13:


Here's some self-contained HTML/JS that does the trick:

<html>
  <head>
    <script type="text/javascript">
      function mkclr(cntl,clr) {
        document.getElementById(cntl).style.backgroundColor = clr;
      };
    </script>
  </head>
  <body>
    <form>
      <input type="textbox" id="tb1"></input>
      <input type="submit" value="Go"
        onClick="javascript:mkclr('tb1','red');">
      </input>
    </form>
  </body>
</html>



回答14:


I had to make a few changes to Steve's suggestion to get mine working,

 function ValidateTextBox(source, args) {
    var controlId = document.getElementById(source.controltovalidate).id;
    var control = $("#" + controlId);
    var value = control.val();
    var is_valid = value != "";
    is_valid ? control.removeClass("error") : control.addClass("error");
    args.IsValid = is_valid;
  }

great example though, exactly what I needed.




回答15:


<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Custemvalidatin.aspx.cs" Inherits="AspDotNetPractice.Custemvalidatin" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script type="text/javascript">
        function vali(source, args) {
            if (document.getElementById(source.controltovalidate).value.length > 0) {
                args.IsValid = true;
                document.getElementById(source.controltovalidate).style.borderColor = 'green';
            }
            else {
                args.IsValid = false;
                document.getElementById(source.controltovalidate).style.borderColor = 'red';
            }

        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:TextBox ID="TextBox1" Style="border:1px solid gray; width:270px; height:24px ; border-radius:6px;"   runat="server"></asp:TextBox>

            <asp:CustomValidator ID="CustomValidator1" runat="server" ControlToValidate="TextBox1"
                ErrorMessage="Enter First Name" SetFocusOnError="True" Display="Dynamic" ClientValidationFunction="vali" 
                ValidateEmptyText="True" Font-Size="Small" ForeColor="Red">Enter First Name</asp:CustomValidator><br /><br /><br />

            <asp:TextBox ID="TextBox2" Style="border:1px solid gray; width:270px; height:24px ; border-radius:6px;"  runat="server"></asp:TextBox>

            <asp:CustomValidator ID="CustomValidator2" runat="server" ClientValidationFunction="vali"
                ControlToValidate="TextBox2" Display="Dynamic" ErrorMessage="Enter Second Name"
                SetFocusOnError="True" ValidateEmptyText="True" Font-Size="Small" ForeColor="Red">Enter Second Name</asp:CustomValidator><br />
            <br />
            <br />

            <asp:Button ID="Button1" runat="server" Text="Button" />
        </div>
    </form>
</body>
</html>



回答16:


It is not exactly without changing controls user used to, but I think this way is easier (not writing the full example, I think it is not necessary):

ASP.NET:

    <asp:TextBox ID="TextBox1" runat="server" ></asp:TextBox>
    <asp:CustomValidator runat="server" ControlToValidate="TextBox1" Display="Dynamic" Text="TextBox1 Not Set" ValidateEmptyText="true" OnServerValidate="ServerValidate" />
    <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Execute" />

Code:

protected void Execute(object sender, EventArgs e)
{
   Page.Validate();
   if (Page.IsValid)
   {
       *some code*
   }
}

protected void ServerValidate(object source, ServerValidateEventArgs args)
{
    CustomValidator cval = source as CustomValidator;
    if (cval == null)
    {
        args.IsValid = false;
        return;
    }

    if (string.IsNullOrEmpty(args.Value))
    {
        args.IsValid = false;
        string _target = cval.ControlToValidate;
        TextBox tb = cval.Parent.FindControl(_target) as TextBox;
        tb.BorderColor = System.Drawing.Color.Red;
    }
    else
    {
        args.IsValid = true;
    }
}


来源:https://stackoverflow.com/questions/196859/change-text-box-color-using-required-field-validator-no-extender-controls-pleas

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!