Knockout ValidateAble Extender
by straeger
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-debug.js"></script>
<span data-bind="text: a"></span>
<br/>
<input type="text" data-bind="textInput: a" />
<br/>
<span data-bind="text: a.hasvalidationMessages"></span>
<hr/>
<span data-bind="text: b"></span>
<br/>
<span data-bind="text: b.hasvalidationMessages"></span>
<hr/>
<span data-bind="text: c().aax"></span>
<br/>
<span data-bind="text: c().aax.hasvalidationMessages"></span>
<hr/>
<span data-bind="text: x"></span>
<br/>
<span data-bind="text: typeof x.hasvalidationMessages"></span>
JavaScript
ko.extenders.validateable = function(target, rules) {
target.hasError = ko.observable(false);
target.validationMessages = ko.observableArray();
target.hasvalidationMessages = ko.computed(function() {
return target.validationMessages().length > 0;
});
target.resetValidationMessages = function() {
target.validationMessages([]);
};
target.combinedValidationMessages = ko.computed(function() {
var ret = "";
ko.utils.arrayForEach(target.validationMessages(), function(message) {
ret += message;
});
return ret;
});
target.rules = ko.observableArray(rules);
target.addValidationMessage = function(message) {
if (!_.contains(target.validationMessages(), message)) {
target.validationMessages.push(message);
}
};
target.hasValidationRules = ko.computed(function() {
return target.rules().length !== 0;
});
var _validate = function(newValue) {
if (target.hasValidationRules()) {
var rules = target.rules();
rules.map(function(rule) {
var validationResult = rule(newValue);
target.hasError(!validationResult.isValid);
target.validationMessages.push(validationResult.message);
});
}
};
target.validate = _validate;
_validate(target());
// attach to value change
target.subscribe(_validate);
return target;
};
var vm = {};
vm.a = ko.observable("Init");
vm.b = ko.computed(function() {
return vm.a() + ' <---- a value';
})
vm.x = ko.observable("x");
vm.c = ko.computed(function() {
return {
aax: ko.observable("Init aax").extend({
validateable: []
})
}
})
vm.a.extend({
validateable: []
});
vm.b.extend({
validateable: []
});
ko.applyBindings(vm);