Knockout-Validation
Knockout-Validation copied to clipboard
parseRule function to allow creating custom extenders
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.
initisn't really part of the rule, it's part of the extender, so the method doesn't make sense.initis misleading if the rule has no registered extender (it would never be called).initis 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).- I feel this scenario while useful to support is not common. Having a dedicated
initmethod to support it would be unnecessary if there was a simpleparseRulefunction.
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
}
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.