Knockout-Contrib / Knockout-Validation

A validation library for Knockout JS
1.02k stars 379 forks source link

Best practices for inter-field validation rules? #132

Closed fbuchinger closed 11 years ago

fbuchinger commented 12 years ago

I'm using knockout-validation in a highly-configurable form environment, in which the validation rules are specified by third parties. We extended the validation rules of knockout-validation with a lot of "inter-field" rules that not just parse the content of one field but rather compare the inputs of two different fields (e.g. eqDate("DATEFIELD2") makes sure that the date entered in the current text field and the one of DATEFIELD2 match).

Right now, I experience problems with these inter-field validators:

ericmbarnard commented 12 years ago

@fbuchinger

This is how I normally recommend setting up validation like you are describing: http://jsfiddle.net/8LWCh/16/

Also, Validators can have state if you would like. We support the notion of doing something ala:

var vm = {
    test: ko.observable(),
    testTwo: ko.observable()
};

function Validator(prop, otherProp){
    var self = this;

    this.message = '';
    this.validator = function(){ // doesn't care about params bc it already has them
        self.message = 'something dynamic';
        return prop() === otherProp();
    };
};

vm.test.extend({
    validation: new Validator(vm.test, vm.testTwo);
});
fbuchinger commented 12 years ago

thanks for the hints and the really helpful solution, Eric!

unfortunately I have two constraints that prevent the direct application of your approach:

The form configuration (including validation) is a JSON dict, so I can't use variable references in this structure like you did. Here is a sample validation config for a datepicker field {"required":true,"eqDate":"eqField2"}. (eqField2 is the id of another form field/observable)

The second requirement is to provide an extensible API for comparative validators that are registered by an identifier, like the example below. Your Validator function seems to override validation for a form field as a whole, which is not exactly what I want.

addComparisonValidator('ltDate', function (dateField1, dateField2) {
      //dateField1, dateField2 are 2 "unwrapped observable" objects 
      //with something like {parsedValue: <javascript date object>, rawValue: "1.11.2012"} 
        return dateField1.parsedValue < dateField2.parsedValue;
    }, 'This date must be before  the date <a href="#{0}">{0}</a>.');

the validator function should receive 2 plain javascript objects, each representing one of the to-be compared form fields. I don't want to add knockout-specific constructs to the validation api, so calls to ko.utils.unwrapObservable etc. should happen in some private function.

ericmbarnard commented 12 years ago

@fbuchinger

I think I'm following what you are saying, but could possibly put together an example scenario of what you're trying to accomplish in a fiddle? I'm not sure I understand what you mean by

I don't want to add knockout-specific constructs to the validation api

So maybe just showing me where you are at in a fiddle, and then describing where you want to end up would help me solve this faster for you..

fbuchinger commented 11 years ago

thanks for your advice and patience, but I could solve this issue in the meantime.