2
votes

I am building a CustomValidator to handle my own application's logic on time fields ("09:00", "15:35", ...) but I am stumbling on a behaviour that I haven't found any explanation for online.

My focus right now is the validation logic that gets executed client-side.

The problem is, as said in the title, that, if and only if I set the ControlToValidate property in the Validator with the ID of the textbox I am validating, the validation gets fired as soon as focus leaves the textbox; it even fires before the onblur event, which is absolutely detrimental for me, since I am using the onblur event to standardize the time formats (eg "9:00" -> "09:00", "11.45" -> "11:45") and thus, the validation logic potentially receives an incorrect value. If, on the other hand, the ControlToValidate property remains blank, the ClientValidationFunction is fired only on a submit/postback.

The only related answer I've found is this https://stackoverflow.com/a/8649697/450684, but still, to me it makes no sense at all. Why should the presence of a ControlToValidate indicate that I want client-side validation to execute before onblur? I don't want it! Is there any way to supress this behaviour?

Here is an example page:

<asp:TextBox runat="server" AutoPostBack="false" ID="txtBox1" onblur="FormatText(this);" />
<asp:CustomValidator runat="server" ID="CV1" ControlToValidate="txtBox1" ClientValidationFunction="Test1" />
<asp:CustomValidator runat="server" ID="CV2" ClientValidationFunction="Test2" />
<asp:Button ID="btn1" Text="postback" runat="server" OnClick="btn1_Click" />
<asp:Label ID="lbl1" runat="server" />
<script type="text/javascript">
    function FormatText(txtBox1)
    {
        alert('FormatText');
    }
    function Test1(val, args)
    {
        alert('Test1');

    }
    function Test2(val, args)
    {
        alert('Test2');
    }</script>

What I want is both Test1 and Test2 to execute only on btn1's click; instead on txtBox1's onblur event I get Test1 and FormatText executing in this order

ASP.NET's client validation was really fun for me to write and study, don't let this ruin everything :-)

Thx

PS: .NET framework's version is 4.0. Plus, the server-side language is C#, if it matters

2

2 Answers

2
votes

I think what is going on is this:

The standard behavior for ASP.NET client-side validation is to validate when the field is exited. That's an observation, not a reference to a published standard (although there may be one.) The out-of-the-box validators all behave this way. All of them require specifying a particular field to validate.

The custom validator allows you to validate a single control (by specifying it with ControlToValidate), or lets you validate a combination of controls, in which case you set ControlToValidate to an empty string. Unless things have changed, you do have to specify it; if you omit the attribute, no validation will occur.

So ... if you specify a control to validate, the custom validator behaves like every other validator and reacts to the user exiting the field. If you don't specify a control to validate, it doesn't know what controls you're interested in, and doesn't do that.

You may be able to work around this by writing a truly custom validator: inherit from BaseValidator. That can actually be a lot of fun.

1
votes

How to manage events of validation for your control. You can remove ControlToValidate property from your validator and bind validation for your textbox on textbox event as you wish. You can add some function logic before or after validation also. On button click event validation stay the same without change.

function BindValidation(){$('#txtBox1').on('blur keyup change',function(){ValidatorValidate($('#CV1').get(0));});}
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(BindValidation);


//validation function  example for CV1 validator
function Test1(val, args)
{                  

    args.IsValid=$('#txtBox1').val().length>0&&$('#txtBox1').val().match(/^\s+$/g)==null;
}