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.
-
init
isn't really part of the rule, it's part of the extender, so the method doesn't make sense. -
init
is misleading if the rule has no registered extender (it would never be called). -
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). - 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 simpleparseRule
function.
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.