Reputation: 9342
I use ko.validation to check valid data on my page like this:
var postcode = ko.observable(),
name = ko.observable();
var validationModel = ko.validatedObservable({
postcode: postcode.extend({ required: true }),
name: name.extend({ required: true })
});
Then in my OK button I check the validation before submitting:
var buttonOk = function () {
if (!validationModel.isValid()) {
validationModel.errors.showAllMessages();
return false;
}
...
It works pretty well: If the user don't type something for postcode and name the validation failed.
Now I added some more validation rules:
postcodeMustNotAlreadyExists + denominationMustNotAlreadyExists like this:
var validationModel = ko.validatedObservable({
postcode: postcode.extend({ required: true }),
name: name.extend({ required: true })
}).extend({
postcodeMustNotAlreadyExists: cities,
denominationMustNotAlreadyExists: cities
});
ko.validation.rules['postcodeMustNotAlreadyExists'] = {
validator: function (val, cities) {
// Try to find a match between the typed postcode and the postcode in the list of cities
var match = ko.utils.arrayFirst(cities(), function (item) {
return (val.postcode() === item.postCode());
});
return !match;
},
message: 'This postcode already exists!'
};
ko.validation.rules['denominationMustNotAlreadyExists'] = {
validator: function (val, cities) {
// Try to find a match between the typed denomination and the denomination in the list of cities
var match = ko.utils.arrayFirst(cities(), function (item) {
return (val.name() === item.name());
});
return !match;
},
message: 'This denomination already exists!'
};
ko.validation.registerExtenders();
Now validationModel.isValid()
returns always true when the user don't type anything for postcode or name. And I noticed that validationModel().postcode.isValid()
is false thus this is not logic to have validationModel.isValid() set to True.
Now with my new implementation I have to test on 2 things: (!validationModel.isValid() || validationModel().errors().length>0)
Any idea?
Thanks.
Upvotes: 3
Views: 9220
Reputation: 3215
isValid property is only redefined in the validationObservable in observable.subscribe handler, which means it most likely won't be redefined with .extend, and with previous version of ko.validation it wouldn't be updated even with the object changes.
There are also issues with initializing the validated observable with undefined / null, and not passing objects -> then the isValid definition is never updated to match new observable object.
Last but not least the options that Tom Studee proposed in his answer could and should be defined in ko.validation.init (app level) or at ko.validationObservable definition level. Its definitely more readable and maintainable. Here the 'deep: true' most likely fails for you, because you have a circular reference in your view model.
Additionally calling showAllMessages on isValid computing will prevent showing messages only after modification (one of ko.validation cool features), which causes ex. typical create new Entity form to be fully covered with validation messages. While normally you would see them only incorrect values are passed or trying to save them.
To sum up: make sure you have updated ko.validation, pass options at validationObservsable or app level, call showAllMessages when needed only. Create ko.validationObservable passing empty options object {} as a second constructor argument; If not other option works redefine isValid property to a new call of ko.validation.group.
Upvotes: 0
Reputation: 10452
Try overriding your isValid()
function inside your viewModel with:
self.isValid = ko.computed(function () {
return ko.validation.group(
self,
{
observable: true,
deep: true
}).showAllMessages(true);
}, self);
Upvotes: 7