Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML

Using Observable And Computed for Validation in Knockout

4.64/5 (4 votes)
4 Jul 2014CPOL1 min read 17.1K   112  
Using Observable and Computed for validation in Knockout

Introduction

If we check out https://github.com/Knockout-Contrib/Knockout-Validation, we will find out how the knockout's basic and custom validations work. But sometimes, we may want to use one of the observables value to take part in the validation process. To do so, we have to use a little trick.

Background

For a quick review, check out http://jsfiddle.net/ZfUWH/.

Now let’s say we have two observables at the view model, first number and second number. And the validator should work for the validation where the first number needs to be less than the second number (first number < second number).

So we have to pass the first numbers' value to the the second numbers' validator rules, for validation.

Using the Code

Let’s say we made a custom validator rule "isLargerThan" for the validation, now we are going to use it in secondNumber observable like this.

Here, using ko.computed is important, because it is working with the observable firstNumber.

If you don't use ko.computed, the custom validator would become a regular static validator, where changeable firstNumber values would not be considered in the validation process, every time when its value changes.

JavaScript
/*fields*/
self.firstNumber = ko.observable('').extend({ required: true, min: 0, digit: true});
self.secondNumber = ko.observable('').extend({
    required: true,
    min: 0,
    digit: true,
    isLargerThan: ko.computed(function () {  //custom validation
        return self.firstNumber();           //assigning observable
    })
});

Here is our custom validator rule where reassigning otherVal = otherVal() is important, as we sent ko.computed function, and value is stored inside the function itself.

JavaScript
/*Validation: 1*/
ko.validation.rules['isLargerThan'] = {
    validator: function (val, otherVal) {
        /*important to use otherValue(), because ko.computed returns a function,
        and the value is inside that function*/
        otherVal = otherVal();                
        return parseFloat(val) > parseFloat(otherVal);
    },
    message: 'This need to be larger than the First Number '
};
ko.validation.registerExtenders();

If we want to use more observables for validation, we just only need to use more of them at the return session of ko.computed with property names, as we did in here:

JavaScript
self.thirdNumber = ko.observable('').extend({
    required: true,
    min: 0,
    digit: true,
    isBetween: ko.computed(function () {
        return {                            //assigning multiple observables
            firstNumber: self.firstNumber(),
            secondNumber: self.secondNumber()
        };
    })
});

/*Validation: 2*/
ko.validation.rules['isBetween'] = {
    validator: function (val, otherVal) {
        /*important to use otherValue(), because ko.computed returns a function,
        and the value is inside that function*/
        otherVal = otherVal();
        return parseFloat(val) >= parseFloat(otherVal.firstNumber)
            && parseFloat(val) <= parseFloat(otherVal.secondNumber);
    },
    message: 'This need to be between than the First Number and Second number'
};
ko.validation.registerExtenders();

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)