0

I'm using the jQuery Validation Plugin and I am adding my own methods like so:

jQuery.validator.addMethod("num", function(num) {
    if(isNaN(num))
        return false;

    return true;
}, "Please enter a valid number");

However, even if I don't add the required class to a form element, this validation method will still be called and evaluate to false if the user entered nothing. But I would like the behavior to be that if an element does not have the required class, it is only called if the user has entered something. Is there anyway to do this? Thanks!

UPDATE

So the actual code that I posted above was meant to be a simple example to demonstrate the problem, however now I am putting up the specific example that is giving me issues. Here is the jsfiddle link:

http://jsfiddle.net/SVwmH/2/

The HTML

<form method="post">
    <li>
        <label for="2">Mileage</label>
        <input type="text" name="2" id="attr_2" class="non_neg_int"
        value="" />
    </li>
    <li>
        <label for="3">VIN (Vehicle Identification Number)</label>
        <input type="text" name="3"
        id="attr_3" class="vin" maxlength="17" value="" />
    </li>
    <li>
        <input type="submit" />
    </li>
</form>

The JS

$(document).ready(function () {
    var validator = $("form").validate({
        onkeyup: false,
        onblur: true,
        ignore: "",
        submitHandler: function (form) { // for demo
            alert('valid form submitted'); // for demo
            return false; // for demo
        }
    });
});

jQuery.validator.addMethod("vin", function (vin) {
    if (!(/^[A-HJ-NP-Z0-9]{17}$/.test(vin))) return false;
    return true;
}, "Must be a valid VIN");

jQuery.validator.addMethod("non_neg_int", function (non_neg_int) {
    if (isNaN(non_neg_int) || non_neg_int == null || non_neg_int == "" || non_neg_int < 0 || !is_int(non_neg_int)) return false;

    return true;
}, "Must be a nonnegative integer");

function is_int(value) {
    if ((parseFloat(value) == parseInt(value)) && !isNaN(value)) {
        return true;
    } else {
        return false;
    }
}
srchulo
  • 5,143
  • 4
  • 43
  • 72
  • Please post the rest of your code... `.validate()` along with the form's HTML. I cannot reproduce the problem as you describe it. – Sparky Mar 15 '13 at 06:14

1 Answers1

5

Quote OP:

"However, even if I don't add the required class to a form element, this validation method will still be called and evaluate to false if the user entered nothing."

I cannot reproduce the problem as you describe it.

As posted, an empty field does not call your custom method, nor is the field required.

DEMO: http://jsfiddle.net/mJvA8/

HTML:

<form id="myform">
    <input type="text" name="field1" />
    <input type="submit" />
</form>

jQuery:

$(document).ready(function () {

    jQuery.validator.addMethod("num", function (num) {
        if (isNaN(num)) return false;
        return true;
    }, "Please enter a valid number");

    $('#myform').validate({ // initialize the plugin
        rules: {
            field1: {
                num: true
            }
        }
    });

});

EDIT based on edited OP:

I've found the following issues with your code. Only some of these items were breaking your code. The rest are just a matter of good practice. You can test these one at a time to see for yourself.

1) There is no such option called onblur. There's one called onfocusout and it's enabled by default. If you pass true into this, you will break it. You can only pass false to disable it, or pass a custom function to over-ride it. To keep the default onfocusout option enabled, just leave it out entirely.

2) Every input element must have a valid name, and name="2" is invalid. It cannot start with a number.

3) If you want to validate any hidden fields, the ignore option must be set to ignore: [] and not ignore: "". Otherwise, leave this option out and hidden fields are ignored by default. See: https://stackoverflow.com/a/8565769/594235

4) I don't understand the point of specifying value="" on each element. Simply leave out the value attribute if you're not using it.

5) Instead of writing out all of this...

 if (test) return false;
 return true;

... you can more simply write one short line: return !(test); (I simply added the ! to flip your particular test logic to return false, just as you wrote it.)

6) As per documentation, you only pass value, element, and optional params into the customMethod function like this: .addMethod("myrule", function(value, element, params) { ... }, "message").

This syntax alleviates any confusion. Also, using the rule's name, "non_neg_int" in place of the word "value" was completely breaking your non_neg_int custom method.

If you don't want these rules to be "required", then you have to fix the logic inside the rules. For example, the non_neg_int method is looking for an empty or null field, so of course it's going to give the error message when the field is empty.

On the two rules, I simply added this.optional(element) which makes the rule optional. In other words, if you leave it blank, the rule will do nothing.

return this.optional(element) || !(test);

There's a working demo below you can tweak as you see fit.

New Demo: http://jsfiddle.net/gVVa8/

Community
  • 1
  • 1
Sparky
  • 98,165
  • 25
  • 199
  • 285
  • I've posted a jsfiddle link in my question to show the issue I'm having. The example is slightly different than the one I originally posted. – srchulo Mar 15 '13 at 06:35
  • Interestingly, here is a new example that mixes my example and yours: http://jsfiddle.net/SVwmH/3/, where your form field does the desired functionality and mine do not. – srchulo Mar 15 '13 at 06:38
  • @srchulo, you have a bunch of little syntax errors I'm working through. – Sparky Mar 15 '13 at 06:50