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,...