Musical Shore
Musical Shore

Reputation: 1381

Knockout Validation custom rules are not working

I am unable to get custom rules to work. I'm afraid I'm failing to understand something fundamental. In this example, b, bvm and berr all validated as expected off of the required extender. Against my custom extender foo, a,avm and aerr do not fail validation as expected.

Calling console.log() from within validator demonstrates that the validator is not being fired. The only way I was able to get the validator function to fire is by calling ko.registerExtenders after the init (although there is no reason to do this, registerExtenders is enabled by default. If it is called, validator is triggered when I reference the extender creating the observable array.

Here's my fiddle.

ko.validation.init({
    grouping: {
        deep: true,
        live: true,
        observable: true
    }
});

ko.validation.rules['foo'] = {
    validator: function(arr) {
        if (!arr.length) {
            return false;
        } else {
            return true;
        }
    },
    message: 'Please foo.'
};
var a = ko.observableArray().extend({ foo: true });
var avm = ko.validatedObservable({
    a: a
});
var aerr = ko.validation.group([a]);

var b = ko.observableArray().extend({ required: true });
var bvm = ko.validatedObservable({
    b: b
});
var berr = ko.validation.group([b]);    

Upvotes: 0

Views: 1971

Answers (2)

Derpy
Derpy

Reputation: 1528

The placement of the init isn't as critical as having a call to registerExtenders after your custom extender. If you omit that line the custom extenders will just be ignored, as you've experienced.

https://jsfiddle.net/c7xynchp/12/

var log = console.debug.bind(console, '[Debug]');
ko.validation.rules['foo'] = {
    validator: function(arr) {
        log('validator', arguments);
        if (!arr.length) {
            log('invalid');
            return false;
        } else {
            log('valid', arr);
            return true;
        }
    },
    message: 'Please select at least one vendor.'
};
ko.validation.registerExtenders();
var a = ko.observableArray().extend({ foo: true });
var avm = ko.validatedObservable({
    a: a
});
var aerr = ko.validation.group([a]);

var b = ko.observableArray().extend({ required: true });
var bvm = ko.validatedObservable({
    b: b
});
var berr = ko.validation.group([b]);
ko.validation.init({
    grouping: {
        deep: true,
        live: true,
        observable: true
    }
});

log('a', a.isValid());
log('avm', avm.isValid());
log('aerr', aerr());
log('b', b.isValid());
log('bvm', bvm.isValid());
log('berr', berr());

// just for laughs
log('aberr', ko.validation.group([a,b])());

Upvotes: 1

elbecita
elbecita

Reputation: 2664

I think you need to initialize the validation plugin after you have registered all your custom validation rules (call the ko.validation.init fn after you register your foo validation rule).

My guess is that when you initialize the plugin, it will work with the configuration and rules registered before, so all the custom rules registered after will not be taken into account (unless, as you pointed out, you call registerExtenders, which will force to register again all custom extenders).

Also see that, for custom rules registered specifically for one object (see my modification on your fiddle: https://jsfiddle.net/elbecita/c7xynchp/10/), they are always taken into account no matter when you initialize the validation plugin.

Hope it helps!

Upvotes: 0

Related Questions