0

I would like my field validation to occur ONLY when the user leaves the field. I've tried the techniques in jQuery validation onblur (see francios wahl's response), but the user experience is that the validation is onblur the FIRST TIME and then reverts to onchange. Is this expected behavior? I can't see why the even would changed.

The entire page can be seen at http://ginof.users.sonic.net/part4-wOutFunction.html

$(function() {

$("#inputForm").validate({
onfocusout: function (valueToBeTested) {
    $(valueToBeTested).valid();
},
rules:
    {
    valueToBeTested: { required: true, digits: true, minlength: 5, maxlength: 5 }
}
}); 

});
Community
  • 1
  • 1
spike
  • 19
  • 1
  • 6
  • Did you try the suggestion in comment of answer you are referring? `I had to add "onkeyup: false," to get the desired behavior` – A. Wolff Feb 22 '15 at 15:33

3 Answers3

1

This is the default behaviour of the jQuery validation plugin as described on this page

In addition, once a field was highlighted as being invalid, it is validated whenever the user types something in the field (option onkeyup).

If you add the option onkeyup set to false then this will cancel this default behaviour as in the snippet below.

Also, the validation plugin has a method for evaluating a single element called element (Details here), which you may want to consider instead of using .valid() on the element.

$(function() {

  $("#inputForm").validate({
    onfocusout: function(valueToBeTested) {
      $(valueToBeTested).valid();
    },
    onkeyup: false,
    rules: {
      valueToBeTested: {
        required: true,
        digits: true,
        minlength: 5,
        maxlength: 5
      }
    }
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.13.1/jquery.validate.js"></script>
<div class="space">
  <h1>After the first validation, this reverts from onblur to onchange.  Why?</h1>
</div>

<form id="inputForm">
  <label class="center" for="valueToBeTested">Enter the number:</label>
  <input name="valueToBeTested" type="number" class="center" id="valueToBeTested">
  <div id="outputText"></div>
  <input type="submit" value="calculate" id="triggerButton" class="center">
</form>
wnbates
  • 743
  • 7
  • 16
  • Technically, it should be `this.element(valueToBeTested)`, not `$(valueToBeTested).valid()`. And your `"valueToBeTested"` name is somewhat misleading, this argument _generically_ represents the particular "element" to be tested, not its value and not the name of any particular field. Please see [plugin source code](http://ajax.aspnetcdn.com/ajax/jquery.validate/1.13.1/jquery.validate.js). – Sparky Feb 22 '15 at 17:01
  • What's the advantage of that? – wnbates Feb 22 '15 at 17:04
  • The advantage of what? Correctly using the native code built into the plugin, instead of an external plugin method? Basically, calling `.valid()` is overkill... `element` validation simply returns a `true/false` which is all you need in this case. – Sparky Feb 22 '15 at 17:05
  • Is using valid on a specific element less efficient then? I wasn't aware of the .element method hence the confusion, but will remember in future. Will edit to include this. – wnbates Feb 22 '15 at 17:19
  • 1
    The `.valid()` method returns a `true/false` but it also triggers any validation messages. `element` simply returns a `true/false`, which is all that's needed here. Messages follow as per `.validate()`. – Sparky Feb 22 '15 at 17:23
0

You have a few issues in your code...

$("#inputForm").validate({
    onfocusout: function (valueToBeTested) {
        $(valueToBeTested).valid();
    },
    rules: {
        valueToBeTested: { 
            required: true,
            digits: true,
            minlength: 5,
            maxlength: 5
        }
    }
});
  1. You should not use .valid() within .validate(). Calling .valid() is overkill... .element() validation simply returns a true/false which is all you need in this case, and the this.element() method is how the plugin's internal default function is written.

  2. The argument valueToBeTested which is passed into your onfocusout function only generically represents the element being tested... it is not supposed to represent one particular element. In other words, the argument passed into this function only represents the field being evaluated at any particular time... it does not represent a specific field name.

  3. The name valueToBeTested that you've used for your field and to declare your rules is misleading because it only represents the name of the field, not the value of anything. Technically functional, semantically misleading.

the user experience is that the validation is onblur the FIRST TIME and then reverts to onchange

  1. Technically, it's onkeyup. The validation is "lazy" by default, which is why you only see certain event triggers after the "first time". You've already overridden part of the "lazy" validation with your custom onfocusout function. If you want to disable onkeyup set it to false, otherwise, you can override this function with your own as well.

    $("#inputForm").validate({
        onfocusout: function (element) { // <- any "element" being evaluated
            this.element(element);  // <- use '.element()' method
        },
        onkeyup: false,  // <- disables all key-up validation
        rules: {
            elementName: { // <- NAME of input element
                required: true,
                digits: true,
                minlength: 5,
                maxlength: 5
            }
        }
    });
    

DEMO: http://jsfiddle.net/jen8fgts/

Sparky
  • 98,165
  • 25
  • 199
  • 285
  • Can you explain what you mean by generically represents? – wnbates Feb 22 '15 at 17:24
  • @wnbates, It means that this particular function is used for any/all fields on the form and the `element` argument simply represents whatever field is being evaluated at one particular time. It does **not** represent a specific field name. – Sparky Feb 22 '15 at 17:26
0

Thanks! Adding onkeyup: false,

fixed the code. Also appreciate the style comments.

spike
  • 19
  • 1
  • 6