I am using Knockout-Validation's sample and added 2 child collections which contain validation rules.
var Item = function(id, name) {
var self = this;
self.id = ko.observable(id).extend({required: {message: 'item id required'}});
self.name = ko.observable(name).extend(
{
minLength: {message :'item name must be at least 5 characters', params: 5},
maxLength: 10
});
ko.validation.group(self, { live: true });
};
var itemsList = [new Item(1, 'test'), new Item(2, 'item 2'), new Item(0, '1')];
var viewModel = {
items : ko.observableArray(itemsList),
items2: ko.observableArray(itemsList),
firstName: ko.observable().extend({minLength: 2, maxLength: 10}),
lastName: ko.observable().extend({required: true}),
emailAddress: ko.observable().extend({
// custom message
required: {
message: 'Please supply your email address.'
}
}),
age: ko.observable().extend({min: 1, max: 100}),
location: ko.observable()
};
Using
ko.validation.group(viewmodel, { deep: true });
my child collections display the validation messages correctly, but I only want 1 child collection validated. The documentation says to pass in the items I want validated like:
ko.validation.group([viewModel.firstName, viewModel.lastName, viewModel.items]);
but when I do that, the child collection no longer displays the validation message.
To reproduce, go to the sample I linked above and click submit. Item 0 and Item 2 in both groups will have validation messages. Change
viewModel.errors = ko.validation.group(viewModel, {deep: true});
to
viewModel.errors = ko.validation.group([viewModel.lastName, viewModel.items]);
Run again and click submit.
When you create the ViewModel:
var itemsList = [new Item(1, 'test'), new Item(2, 'item 2'), new Item(0, '1')];
var viewModel = {
items : ko.observableArray(itemsList),
items2: ko.observableArray(itemsList),
you are sharing the same observables in the two observable arrays, that is, items
and items2
.
You could solve it by adding new observables (I add itemsList2
and then I use it to initialize items2
):
var itemsList = [new Item(1, 'test'), new Item(2, 'item 2'), new Item(0, '1')];
var itemsList2 = [new Item(1, 'test'), new Item(2, 'item 2'), new Item(0, '1')]; <---
var viewModel = {
items : ko.observableArray(itemsList),
items2: ko.observableArray(itemsList2), <---
...
};
Finally, you need to add {deep: true}
in this sentence:
viewModel.errors = ko.validation.group([viewModel.lastName, viewModel.items], {deep: true});
Here it is a fiddle as an example, and the full ViewModel.
var Item = function(id, name) {
var self = this;
self.id = ko.observable(id).extend({required: {message: 'item id required'}});
self.name = ko.observable(name).extend(
{
minLength: {message :'item name must be at least 5 characters', params: 5},
maxLength: 10
});
ko.validation.group(self, { live: true });
};
var itemsList = [new Item(1, 'test'), new Item(2, 'item 2'), new Item(0, '1')];
var itemsList2 = [new Item(1, 'test'), new Item(2, 'item 2'), new Item(0, '1')];
var viewModel = {
items : ko.observableArray(itemsList),
items2: ko.observableArray(itemsList2),
firstName: ko.observable().extend({minLength: 2, maxLength: 10}),
lastName: ko.observable().extend({required: true}),
emailAddress: ko.observable().extend({
// custom message
required: {
message: 'Please supply your email address.'
}
}),
age: ko.observable().extend({min: 1, max: 100}),
location: ko.observable()
};