JeffreyABecker
JeffreyABecker

Reputation: 2743

How can I change knockout validation based on an event

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

Answers (1)

sauperl
sauperl

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>

Working jsfiddle sample.

So what this code does:

  • starts validating text inputs on keydown
  • triggers validation on checkbox click

Upvotes: 5

Related Questions