0

I have a very simple newsletter subscription form :

    @using (Ajax.BeginForm("Register", "Home", new AjaxOptions
{
    Confirm = "confirm?",
    HttpMethod = "Post",
    InsertionMode = InsertionMode.Replace,
    UpdateTargetId = "response"
}))
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)
    <div id="response">
        <div class="form-group">
            @Html.TextBoxFor(model => model.Email, new { @class = "form-control", @placeholder = "insert email" })
            @Html.ValidationMessageFor(model => model.Email)
        </div>
        <div class="form-group">
            <input type="submit" id="submit" value="subscribe" class="btn btn-default" />
        </div>
    </div>
}

The email field needs to be filled, and be a valid email. The problem is that as soon as I start typing inside the textbox, validation fires, and the message "email is invalid" pops out. This is quite annoying. Is there a way to fire validation when clicking on submit button, instead of every single textbox change? Thank you.

Sparky
  • 98,165
  • 25
  • 199
  • 285
Cuttlefish
  • 187
  • 1
  • 3
  • 10
  • I can't replicate this problem. I think you might need to include more of your page code/content in your question. – sanepete Apr 27 '15 at 09:59
  • What you claim is not the default behavior. Validation is 'lazy' will not be triggered until the control loses focus. If you refocus the control, validation is 'eager'. You have something else in your code causing this issue –  Apr 27 '15 at 10:18
  • Actually, it seems to be the default behaviour... As Prasanth says below, validation is triggered as soon as I type, not when field loses focus. – Cuttlefish Apr 27 '15 at 10:30
  • 1
    Rubbish. You should read the [documentation](http://jqueryvalidation.org/documentation#A_few_things_to_look_for_when_playing_around_with_the_demo) to confirm it. you are doing something else wring to cause this behavior. –  Apr 27 '15 at 11:26
  • Ok, this is what I came up to: ValidationMessageFor triggers error when the field changes its state to invalid, and this happens on every field change. So I removed ValidationMessageFor and replaced it with a ValidationSummary, that triggers only on submit click. Thank you everyone for support. – Cuttlefish Apr 28 '15 at 08:57

2 Answers2

1

If you use ValidationMessageFor then the MVC will trigger immediately when you type. Instead use Jquery or javascript validation.

HTML:

@Html.TextBoxFor(model => model.Email, new { @class = "form-control", @placeholder = "insert email" })
<div id="emailerror" class="hide">The email is required</div>

JQuery:

var pattern = /^([\w\-\.]+)@@((\[([0-9]{1,3}\.){3}[0-9]{1,3}\])|(([\w\-]+\.)+)([a-zA-Z]{2,3}))$/;
        var email = $('#Email').val();
        if (email == "") {
            $('#emailerror').removeClass('hide');
            $('#emailerror').addClass('error');
            return false;
        } else if (!pattern.test(email)) {
            $('#emailerror').removeClass('hide');
            $('#emailerror').addClass('error');
            document.getElementById("emailerror").innerHTML = "The Email is not valid";
            return false;
        }
        else {
            $('#emailerror').addClass('hide');
            $('#emailerror').removeClass('error');
            return true;
        }

CSS:

.hide {
display:none;
}

.error {
position: absolute; 
margin-top:48px; 
margin-left:-300px;
z-index: 1060;
max-width: 276px;
padding: 10px;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 13px;
font-weight: 400;
line-height: 1.42857143;
text-align: left;
white-space: normal;
color: #fff;
background-color: #c14a4a;
-webkit-background-clip: padding-box;
background-clip: padding-box;
border: 1px solid #ccc;
border: 1px solid rgba(0, 0, 0, .2);
border-radius: 0px;
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
}
Prasanth Jaya
  • 4,407
  • 2
  • 23
  • 33
  • Didn't know about that... So the only way to avoid this issue is to use a "custom" jquery validation? – Cuttlefish Apr 27 '15 at 10:35
  • No @Cuttlefish.. You have another alternative where you can avoid it.. :) But even Prashanth's answer works well.. :) – Guruprasad J Rao Apr 27 '15 at 10:58
  • 2
    _"MVC will trigger immediately when you type."_! Complete rubbish. Read the documentation. It does not trigger validation until the control loses focus, and only then if the value has been modified. –  Apr 27 '15 at 11:28
1

As an alternative a more straightforward way you can pass a function to the onfocusout and onkeyup settings of the jquery.validator to decide if an element has to be validated in those events or not, as this :

jQuery.validator.defaults.onfocusout = function (element, event) {
    // detectect if is the element you dont want validate
    // the element has to have the attribute 'data-control="mycitycontrol"'
    // you can also identify your element as you please
    if ($(element).data("control") === "mycitycontrol") return;
    if (!this.checkable(element) && (element.name in this.submitted || !this.optional(element))) {
        this.element(element);
    }
}
jQuery.validator.defaults.onkeyup = function (element, event) {
    // detectect if is the element you dont want validate
    // the element has to have the attribute 'data-control="mycitycontrol"'
    // you can also identify your element as you please
    if ($(element).data("control") === "mycitycontrol") return;
    if (event.which === 9 && this.elementValue(element) === "") {
        return;
    } 
    else if (element.name in this.submitted || element === this.lastElement) {
        this.element(element);
    }
}

SOURCE

Community
  • 1
  • 1
Guruprasad J Rao
  • 29,410
  • 14
  • 101
  • 200