1

I have a regular expression control that validates an email address. It validates as expected except that it does it when the control loses focus. I want it to validate only when the form is being submitted.

<asp:TextBox ID="txtRegisterEmailAddress" type="email" ValidationGroup="UserProfile" runat="server" CssClass="form-control " Style="text-transform: lowercase" />  
<asp:RegularExpressionValidator ID="revRegisterEmailAddress" runat="server" ControlToValidate="txtRegisterEmailAddress" ErrorMessage="* Invalid Email Address" Display="Dynamic" SetFocusOnError="true" ValidateRequestMode="Disabled" ForeColor="Red" ValidationGroup="UserProfile" ValidationExpression="^(([a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9]{2,10}(?:[a-z0-9-]*[a-z0-9])?)\s*?,?\s*?)+$" />  
<asp:Button runat="server" ID="btnRegister" ClientIDMode="Static" ValidationGroup="UserProfile" CssClass="btn btn-default" OnClick="btnRegister_Click" Text="Register" OnClientClick="DisableReg();" UseSubmitBehavior="false" />

Please help.

EDIT:
The validation should only happen when I submit, and should not submit if validation fails. Currently it validates when losing focus of the control. I do not want to rewrite the validation process, only change WHEN it validates.

RealSollyM
  • 1,530
  • 1
  • 22
  • 35
  • No Utility, it's not the same question. It's totally different. – RealSollyM Jul 03 '15 at 09:33
  • Call the validation method as one of the first things in `btnRegister_Click`, that way you can make sure that it will only submit if it passes validation. And the validation gets done when submitted. – Malte R Jul 03 '15 at 09:34
  • Please give me guidance in that regard @Malte. Are there any attributes to RegularExpressionValidator that I need? – RealSollyM Jul 03 '15 at 09:36
  • answered here http://stackoverflow.com/questions/3102346/how-can-i-turn-off-asp-net-required-field-validator-lost-focus-behaviour - use ValidatorEnable – Krishna Jul 03 '15 at 09:36
  • See my answer. Does this help you? – Malte R Jul 03 '15 at 09:43
  • Thanks @Krishna, this answer works. Except it adds another problem - once the ValidationGroup has been activated again, it goes back to what we had before. I now need a way to turn then off when I set focus of the control. – RealSollyM Jul 03 '15 at 10:07
  • hmmm. is it not an option to turnoff all valiation groups that you dont want to be fired "on blur" by default and enable on click? – Krishna Jul 03 '15 at 10:39
  • Also, just to understand, why dont you want the validation to fire on lost focus? is it because the focus doesnt go further to the next form element?. IF that is the reason, turn off SetFocusOnError. – Krishna Jul 03 '15 at 10:41
  • Situation is that once the user moves away the validation fires, and if the content is not valid it shows the error just below the box. Problem now is when they go back to fixing the problem but the error message doesn't disappear and uses end up complaining that their email address/web address/ etc are valid but system still think they are invalid. – RealSollyM Jul 03 '15 at 13:00
  • @Krishna please post your link as an answer because I'd like to use mark it as a solution. – RealSollyM Jul 03 '15 at 13:12

2 Answers2

1

You could make a method for validating the email, which could return a bool:

    public class RegexUtilities
    {
        bool invalid = false;

        public bool IsValidEmail(string strIn)
        {
            invalid = false;
            if (String.IsNullOrEmpty(strIn))
                return false;

            // Use IdnMapping class to convert Unicode domain names. 
            try
            {
                strIn = Regex.Replace(strIn, @"(@)(.+)$", this.DomainMapper,
                                      RegexOptions.None, TimeSpan.FromMilliseconds(200));
            }
            catch (RegexMatchTimeoutException)
            {
                return false;
            }

            if (invalid)
                return false;

            // Return true if strIn is in valid e-mail format. 
            try
            {
                return Regex.IsMatch(strIn,
                      @"^(?("")("".+?(?<!\\)""@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))" +
                      @"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))$",
                      RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250));
            }
            catch (RegexMatchTimeoutException)
            {
                return false;
            }
        }

        private string DomainMapper(Match match)
        {
            // IdnMapping class with default property values.
            IdnMapping idn = new IdnMapping();

            string domainName = match.Groups[2].Value;
            try
            {
                domainName = idn.GetAscii(domainName);
            }
            catch (ArgumentException)
            {
                invalid = true;
            }
            return match.Groups[1].Value + domainName;
        }
    }

Taken directly from MSDN

And then run this method as the first thing in btnRegister_Click and use the return value to determine whether to continue or not.

If the method returns false, you could inform the user through a textbox, or in some other way, and then stop the submit method by returning:

public void btnRegister_Click( ... )
{
    var emailValidator = new RegexUtilities();
    bool validEmail = emailValidator.IsValidEmail( ..textbox-input.. );

    if (!validEmail)
    {
        txtError.Text = "Enter a valid email please";
        return;
    }
    //...
    //...
    //(Your submit code)
}

Edit: Corrected missing code

Malte R
  • 468
  • 5
  • 16
1

partially answered here

On init, disable all validationgroups that you dont want to be fired "onblur" and use ValidatorEnable for onclick.

another option is to turn off SetFocusOnError if you want the users to move to the next form element but still show something is wrong with the expression. The form cant be submitted until the email address is corrected

UPDATE from OP: On Page_Load, the Validation would be disabled. But after enabling it, there was no way of disabling it again. I have added the below code to disable it again onFocus of the textbox, and it's textbox specific.

function TurnOffValidator(ControlToValidate) {
    for (var i = 0; i < Page_Validators.length; i++) {
        if (Page_Validators[i].controltovalidate === ControlToValidate) {
            ValidatorEnable(Page_Validators[i], false);
        }
    }
}

function TurnOnValidator(ControlToValidate) {
    for (var i = 0; i < Page_Validators.length; i++) {
        if (Page_Validators[i].controltovalidate === ControlToValidate) {
            ValidatorEnable(Page_Validators[i], true);
        }
    }
}

$('#<%= txtTextbox.ClientID %>').focus(function () {
    TurnOffValidator("<%= txtTextbox.ClientID %>");
});
Community
  • 1
  • 1
Krishna
  • 2,451
  • 1
  • 26
  • 31