ko-validation demo

by Semmel

HTML

<link rel="stylesheet" href="http://preview3.visisoft.de/jsFiddleLibs/bootstrap.css">
<script src="http://preview3.visisoft.de/jsFiddleLibs/bootstrap.js"></script>
<script src="http://preview3.visisoft.de/jsFiddleLibs/knockout.js"></script>
<script src="http://preview3.visisoft.de/jsFiddleLibs/knockout.validation.js"></script>
<script id="customMessageTemplate" type="text/html">
    <em class="customMessage" data-bind='validationMessage: field'></em>
</script>
<fieldset>
    <legend>User: <span data-bind='text: errors().length'></span> errors</legend>
    
    <div class="control-group" data-bind="validationElement: firstName">
        <div class="controls">
            <label>First name: <input data-bind='value: firstName' required /></label>
        </div>
    </div>
    
    <div class="control-group" data-bind="validationElement: lastName">
        <div class="controls">
            <label>Last name: <input data-bind='value: lastName' required /></label>  
        </div>
    </div>
    
    <div data-bind='validationOptions: { messageTemplate: "customMessageTemplate" }'>
        <label>Email: <input data-bind='value: emailAddress' required pattern="@"/></label>
        <label>Location: <input data-bind='value: location'/></label>
   </div>
   <div class="control-group" data-bind="validationElement: age">
       <div class="controls">
            <label>Age: <input data-bind='value: age' required /> </label>
         </div>
    </div>
       
    <label>
        Subscriptions: 
        <select data-bind='value: subscription, options: subscriptionOptions, optionsCaption: "Choose one..."'></select>
    </label>
       
    <label>Password: <input data-bind='value: password' type="password"/></label>
    <label>Retype password: <input data-bind='value: confirmPassword' type="password"/></label>
     <div class="control-group" data-bind="validationElement: captcha">
        <div class="controls">
            <label>10 + 1 = <input data-bind='value:...

CSS

label { display: block; }
.validationMessage { color: Red; }
.customMessage { color: Orange; }

JavaScript

ko.validation.rules.pattern.message = 'Invalid.';
    

ko.validation.configure({
    registerExtenders: true,
    messagesOnModified: true,
    insertMessages: true,
    parseInputAttributes: true,
    messageTemplate: null,
    errorMessageClass: 'help-inline', /// standard Bootstrap way
    errorElementClass: 'error',
    decorateElement: true
});

var viewModel = {
    firstName: ko.observable().extend({ minLength: 2, maxLength: 10 }),
    lastName: ko.observable(),
    emailAddress: ko.observable().extend({  // custom message
        required: { message: 'Please supply your email address!' }
    }),
    age: ko.observable().extend({ min: 1, max: 100 }),
    location: ko.observable(),
    subscriptionOptions: ['Technology', 'Music'],
    subscription: ko.observable().extend({ required: true }),
    password: ko.observable(),
    captcha: ko.observable().extend({  // custom validator
        validation: { validator: function (val) {
            return val == 11;
        }, message: 'Please check.' }
    }),
    submit: function () {
        if (viewModel.errors().length == 0) {
            alert('Thank you.');
        } else {
            viewModel.errors.showAllMessages();
        }
    }
};

viewModel.confirmPassword = ko.observable().extend({
    validation: { validator: function (val, other) {
            return val == other();
        }, message: 'Passwords do not match.', params: viewModel.password 
    }
}),

viewModel.errors = ko.validation.group(viewModel);

viewModel.requireLocation = function () {
    viewModel.location.extend({ required: true });
};

ko.applyBindings(viewModel);

/// for debugging
window.viewModel = viewModel;