Knockout-Validation icon indicating copy to clipboard operation
Knockout-Validation copied to clipboard

parseRule function to allow creating custom extenders

Open chilversc opened this issue 9 years ago • 2 comments

I want to be able to create my own extenders (e.g. 'date') that adds validation rules. Currently to do this I would be required to call knockout.validation.addRule which means duplicating all the logic from knockout.validation.addExtender to handle parsing the rule.

I think a new method should be added, knockout.validation.parseRule(name, params). The addExtender method would become kv.addRule(observable, kv.parseRule(ruleName, params))

As a workaround I'm currently using

(function() {
    ko.validation.addExtender('date');
    var base = ko.extenders['date'];

    ko.extenders['date'] = function(observable, params) {
        observable.iso = ko.pureComputed(formatISODate, observable);
        base(observable, params);
    }
});

With parseRule this could be changed to

(function() {
ko.extenders['date'] = function(observable, params) {
    observable.iso = ko.pureComputed(formatISODate, observable);
    ko.validation.addRule(observable, ko.validation.parseRule('date', params));
}

I did consider adding an init option to the validation rules that would be called when setting up the extender but I discounted that option for 4 reasons.

  1. init isn't really part of the rule, it's part of the extender, so the method doesn't make sense.
  2. init is misleading if the rule has no registered extender (it would never be called).
  3. init is less flexible, you might want your extender to take custom parameters, where the validation parameters is a nested property (perhaps only conditionally adding the validation).
  4. I feel this scenario while useful to support is not common. Having a dedicated init method to support it would be unnecessary if there was a simple parseRule function.

chilversc avatar Feb 12 '15 11:02 chilversc

Although having the library expose such functionality might not be a bad idea I think you actually need an extender instead. I might be wrong but here's how you might achive the same result using an extender:

ko.extenders.custom = function(target) {
  target.iso = ko.pureComputed(formatISODate, target);
  return target.extend({date: true});
});

var obs = ko.observable().extend({custom: true});

The same technique can help you with defining multiple rules with just one extender. For instance:

ko.extendes.myEmail = function(target) {
 return target.extend({email: true, required: true, maxLength: 128});
 // You may also use validation extender to add annonymous rules also
}

crissdev avatar Mar 02 '15 15:03 crissdev

My problem was that I wanted to name the extender date as that's the expected name, but that conflicts with the extender for the validation rule date. Access to the parseRule function (or some alternative form of addRule) would let me chain the validation rule from my custom extender.

chilversc avatar Mar 03 '15 09:03 chilversc