21

How can I execute some javascript when a Required Field Validator attached to a textbox fails client-side validation? What I am trying to do is change the css class of the textbox, to make the textbox's border show red.

I am using webforms and I do have the jquery library available to me.

    6 Answers 6

    25

    Here is quick and dirty thing (but it works!)

    <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> 
    6
    • I think your v1 and v2 variables are unused :P
      – billy
      CommentedJul 23, 2012 at 14:35
    • yep, but this is quick and dirty :D. just commented them.CommentedJul 24, 2012 at 17:43
    • maybe dirty, but I haven't found a better solution !! :P
      – billy
      CommentedJul 24, 2012 at 20:58
    • What is the reason to write the var i = 0 statement outside of the for loop?CommentedNov 30, 2012 at 11:14
    • Because the only variable scope delimiter in js is the function. So declaring it inside the for declaration is misleading.CommentedSep 13, 2013 at 14:57
    21

    You could use the following script:

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

    This code decorates the original ValidatorUpdateDisplay function responsible for updating the display of your validators, updating the controltovalidate as necessary.

    Hope this helps,

    2
    • 8
      To enable easier custom styling, you can do: $("#" + val.controltovalidate).toggleClass('error', !val.isvalid);CommentedMar 5, 2013 at 12:44
    • +1 saved me some Google time here, thank you gsimoes and @GrimaceofDespair
      – CResults
      CommentedJul 29, 2013 at 4:52
    2

    I think you would want to use a Custom Validator and then use the ClientValidationFunction... Unless it helpfully adds a css class upon fail.

    1
    • 1
      Important notice: this won't work for trying to check whether a field is empty or not; the CustomValidator isn't triggered if the field to check is empty. :-(
      – Jez
      CommentedDec 13, 2010 at 15:52
    0

    Some time ago I spend a few hours on it and since then I have been using some custom js magic to accomplish this.

    In fact is quite simple and in the way that ASP.NET validation works. The basic idea is add a css class to attach a javascript event on each control you want quick visual feedback.

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

    For instance, that will be the code to add on an ASP.Net textbox control. Yes, you can put as many as you want and it will only imply add a CssClass value.

    <asp:TextBox ID="txtBxEmail" runat="server" CssClass="validateColor" /> 

    What it does is trigger ASP.Net client side validation when there is a change on working control and apply a css class if it's not valid. So to customize visualization you can rely on css.

    .novalid { border: 2px solid #D00000; } 

    It's not perfect but almost :) and at least your code won't suffer from extra stuff. And the best, works with all kind of Asp.Net validators, event custom ones.

    I haven't seen something like this googling so I wan't to share my trick with you. Hope it helps.

    extra stuff on server side:

    After some time using this I also add this ".novalid" css class from code behind when need some particular validation on things that perhaps could be only checked on server side this way:

    Page.Validate(); if (!requiredFecha.IsValid || !CustomValidateFecha.IsValid) txtFecha.CssClass = "validateColor novalid"; else txtFecha.CssClass = "validateColor"; 
    4
    • What if user doesnt input anything and posts the page. This code won't validate on submit...
      – HasanG
      CommentedJun 29, 2014 at 14:26
    • @HasanG&#252;rsoy I wrote this long time ago but the idea was mainly to add some behavior on standard ASP.net controls. I guess you can add some onClick behavior over any submit elements to trigger calling the function as well.
      – guillem
      CommentedJun 29, 2014 at 18:01
    • Hmm yes, thank you. But I guess it will cause the same bug as I asked here: stackoverflow.com/questions/24477219/…
      – HasanG
      CommentedJun 30, 2014 at 9:18
    • @HasanGürsoy sure as you then will need a custom validator probably
      – guillem
      CommentedJun 30, 2014 at 10:41
    0

    Here is my solution.

    Advantages over other solutions:

    • Integrates seamlessly with ASP.NET - NO changes required to code. Just call the method on page load in a master page.
    • Automatically changes the CSS class when the text box or control changes

    Disadvantages:

    • Uses some internal features of ASP.NET JavaScript code
    • Tested only on ASP.NET 4.0

    HOW TO USE:

    • Requires JQuery
    • Call the "Validation_Load" function when the page loads
    • Declare a "control_validation_error" CSS class

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

      Alternatively, just iterate through the page controls as follows: (needs a using System.Collections.Generic reference)

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

      Should work for most cases, and means you dont have to update it when you add validators. Ive added this code into a cstom Pageclass so it runs site wide on any page I have added validators to.

      1
      • 1
        Its very inefficient to iterate through every control on a page, I don't think you should do this.CommentedAug 30, 2012 at 10:06

      Start asking to get answers

      Find the answer to your question by asking.

      Ask question

      Explore related questions

      See similar questions with these tags.