Reputation: 2743
I'm currently using knockout validation to do validation on a form as such:
html
<div>
<span>Client</span><input type="text" data-bind="value:Client" />
</div>
<div>
<span>IsMarried</span><input type="checkbox" data-bind="value:IsMarried" />
</div>
<div>
<span>Spouse</span><input type="text" data-bind="value:Spouse" />
</div>
JS
function HouseHold() {
var self = this;
self.Client = ko.observable().extend({required:true});
self.IsMarried = ko.observable();
self.Spouse = ko.observable().extend({required:{ onlyIf:function(){ return self.IsMarried();}}});
}
Currently, when the IsMarried checkbox gets checked, the spouse field wont validate properly until a value has been entered then cleared.
Is there any way I can modify the bindings on my knockout viewmodel based on an event or otherwise make the validation happen sooner?
Upvotes: 2
Views: 5325
Reputation: 141
You could use ko.validation.group or ko.validatedObservable, which enables you checking for errors and manually trigger validation.
This is one way you could resolve this:
JS
var HouseHold = function(){
var self = this;
self.Client = ko.observable().extend({required:true});
self.IsMarried = ko.observable();
self.Spouse = ko.observable().extend({required:{ onlyIf:function(){ return self.IsMarried();}}});
}
var houseHold = new HouseHold();
ko.validation.group(houseHold);
var forceValidation = function(){
//is viewmodel valid?
if(!houseHold.isValid())
{
//shows error messages for invalid properties
houseHold.errors.showAllMessages();
}
//it looks like you need to return true else checkbox doesn't stay checked
return true;
}
var vm = {
houseHold: houseHold,
forceValidation: forceValidation
}
ko.applyBindings(vm);
HTML
<div>
<span>Client</span><input type="text" data-bind="value:houseHold.Client, valueUpdate: 'afterkeydown'" />
</div>
<div>
<span>IsMarried</span><input type="checkbox" data-bind="checked:houseHold.IsMarried, click:forceValidation" />
</div>
<div>
<span>Spouse</span><input type="text" data-bind="value:houseHold.Spouse, valueUpdate: 'afterkeydown'" />
</div>
So what this code does:
Upvotes: 5