I need to make sure each observable is valid and also make sure all the observables are valid together. In my simplified example I have a modelNumber and stockNumber that are each required, but together they must also form a valid partNumber. My attempt gives me this error:
"Uncaught Error: Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters."
What's the problem?
https://jsfiddle.net/yekr2ov2/18/
// enable validation
ko.validation.init();
ko.validation.rules['partNumberValid'] = {
validator: function(partInfo, otherVal) {
return partInfo.modelNumber() + partInfo.stockNumber() == "m1s1";
},
message: 'part number is invalid'
};
ko.validation.registerExtenders();
function VM() {
var self = this;
self.modelNumber = ko.observable().extend({ required: true });
self.stockNumber = ko.observable().extend({ required: true });
self.vinNumber = ko.observable().extend({ required: true });
self.isPartNumberValid = ko.validatedObservable({
modelNumber: self.modelNumber,
stockNumber: self.stockNumber,
vinNumber: self.vinNumber
}).extend({ partNumberValid: true });
self.message = ko.observable();
self.save = function() {
if (self.isPartNumberValid.isValid()) {
self.message("saved");
}
else {
debugger;
//self.isPartNumberValid.errors.showAllMessages();
self.message("not saved");
}
};
}
ko.applyBindings(new VM());
i have modified the code and the following code works fine.
ko.validation.init();
ko.validation.rules['partNumberValid'] = {
validator: function (partInfo, otherVal) {
return partInfo.modelNumber() +''+ partInfo.stockNumber() === "m1s1";
},
message: 'part number is invalid'
};
ko.validation.registerExtenders();
function VM() {
var self = this;
self.modelNumber = ko.observable().extend({required: true});
self.stockNumber = ko.observable().extend({required: true});
self.isPartNumberValid = ko.observable({
modelNumber:self.modelNumber,
stockNumber:self.stockNumber
}).extend({partNumberValid:true});
self.validateMe = ko.computed(function(){
write:{
var tes = ko.validation.group([self.modelNumber,self.stockNumber,self.isPartNumberValid]);
tes.showAllMessages(true);
}
});
}
ko.applyBindings(new VM());
Fiddle :https://jsfiddle.net/yekr2ov2/7/
i used ko.validation.group to validate observables and computed to validate immediately. you can replace the computed with button click or any other custom function. Let me know if that helps.
thank you
I think the answer is you can't extend validation on Knockout Validation's validatedObservable. I think the right answer here is to create an observable
for each thing or group of things that needs validation and then create a validatedObservable
to validate all of those observables
.
https://jsfiddle.net/yekr2ov2/17/
ko.validation.init();
ko.validation.rules['partNumberValid'] = {
validator: function(partInfo, otherVal) {
return partInfo.modelNumber() + partInfo.stockNumber() === "m1s1";
},
message: 'part number is invalid'
};
ko.validation.registerExtenders();
function VM() {
var self = this;
self.modelNumber = ko.observable().extend({ required: true });
self.stockNumber = ko.observable().extend({ required: true });
self.vinNumber = ko.observable().extend({ required: true });
self.partNumber = ko.observable({
modelNumber: self.modelNumber,
stockNumber: self.stockNumber
}).extend({ partNumberValid: true });
self.isPartNumberValid = ko.validatedObservable({
modelNumber: self.modelNumber,
stockNumber: self.stockNumber,
vinNumber: self.vinNumber,
partNumber: self.partNumber
});
self.message = ko.observable();
self.save = function() {
if (self.isPartNumberValid.isValid()) {
self.message("saved");
}
else {
debugger;
self.isPartNumberValid.errors.showAllMessages();
self.message("not saved");
}
};
}
ko.applyBindings(new VM());