JSFiddle - React, Tailwind, and code Playground
by manchagnu
HTML
<script src="https://github.com/SteveSanderson/knockout/raw/master/build/output/knockout-latest.debug.js"></script>
Subject <em data-bind='text: subject.error()'></em> <br/>
<input data-bind='value: subject'/> <br/>
Body <em data-bind='text: body.error()'></em> <br/>
<textarea data-bind='value: body'></textarea> <br/>
<button type="button" data-bind='click: submit'>Validate</button>
CSS
em {
color: Red;
}
JavaScript
// updated version, please see http://jsfiddle.net/andybooth/2GUyX/
ko.utils.isString = function (obj) { // _.isString
return !!(obj === '' || (obj && obj.charCodeAt && obj.substr));
};
ko.validation = function () {
var rules = [];
function required(value) {
return value != null && value !== "";
}
function minLength(value, length) {
return value.length >= length;
}
function maxLength(value, length) {
return value.length <= length;
}
function regex(value, pattern) {
return value.match(pattern) != null;
}
function exclude(value, pattern) { // negative regex
return value.match(pattern) == null;
}
function addRule(field, validator, message, option) {
if (!ko.isObservable(field)) {
throw "field must be observable";
}
if (!field['error']) { // reuse existing observable error
field['error'] = ko.observable(null);
field.subscribe(function () {
validateField(field);
});
}
var rule = {
field: field,
validator: validator,
message: message,
error: field['error'],
option: option
};
rules.push(rule);
}
function validateField(field) {
var fieldRuleSet = ko.utils.arrayFilter(rules, function (rule) {
return field == rule.field;
});
if (applyRuleSet(fieldRuleSet)) {
field.error(null);
}
}
function applyRule(rule) {
var value = rule.field();
if (ko.utils.isString(value)) { // always pre trim strings
value = ko.utils.stringTrim(value);
}
if (!rule.validator(value, rule.option)) {
rule.error(rule.message);
return false;
}
return true;
}
function applyRuleSet(ruleset) {
var isValid = true;
ko.utils.arrayForEach(ruleset,...