Knockout-validation group error checking

user1852176 picture user1852176 · Oct 16, 2013 · Viewed 12.1k times · Source

I have a knockout form that is comprised of 2 parts. When the first part is being filled out the second part is hidden. Upon completing the first part and clicking "Continue" the first part is then hidden and the second part is shown. I want to be able to validate the first set of inputs, and if there are no errors then continue to the next part.

I found this on the official github page which I is what I'm attempting to do.

When I do this no errors are detected. It continues to the second part

function ReserveViewModel(){

    self.firstName = ko.observable("").extend({ required: true });

    self.continue = function(){
        var errors = ko.validation.group([ReserveViewModel.firstName]);
        if (errors.length == 0) {
            //display  second div
        }
        else{
             self.errors.showAllMessages();
        }
    }
}

However, if I do this it works but tries to validate everything. Since the second set of inputs are empty it just hangs there.

self.continue = function(){
    self.errors = ko.validation.group(self);
    if (self.errors().length == 0) {

    }
    else{
        self.errors.showAllMessages();
    }
}

Answer

PW Kad picture PW Kad · Oct 16, 2013

There are a few fundamental reasons that your code isn't working. In the first example, you are already within the context of your view model so you don't need to use ReserveViewModel.firstName, and in the second you are saying to check everything within 'self' which is to say check everything within me for validation. There are two ways easy ways to skin this cat (as I see it, having only briefly worked with KO.Validation) -

Deep validation -

function Person(firstname, lastname) {
    var firstName = ko.observable(firstname).extend({ required: true });
    var lastName = ko.observable(lastname).extend({ required: true });
}

function ReserveViewModel(){

    self.person = ko.observable(new Person('John', 'Jingleheimer'));

    self.continue = function(){
        var errors = ko.validation.group(self.person, { deep: true });
        if (errors.length == 0) {
            //display  second div
        }
        else{
             self.errors.showAllMessages();
        }
    }
}

This will validate all of the properties of person and it's 'child' properties to ensure validation.

The next example would be to simply create an array of objects to check against -

function myViewModel() {
    var self = this;
    self.firstName = ko.observable().extend({ required: true });
    self.lastName = ko.observable().extend({ required: true });
    self.someOtherProperty = ko.observable().extend({ required: true });

    var firstStepValidation = [
        self.firstName,
        self.lastName
    ];

    var secondStepValidation = [
        self.someOtherProperty
    ];

    self.continue = function(){
        var errors = ko.validation.group(firstStepValidation);
        if (errors.length == 0) {
            //display  second div
        }
        else{
             self.errors.showAllMessages();
        }
    }
}

This will allow you to 'chunk' your observables into arrays to test against. This would probably be easier than trying to create separate view models.