Knockout.js -Extender Demo

by nitronic

HTML

<script src="https://github.com/SteveSanderson/knockout/raw/master/build/output/knockout-latest.js"></script>
<script src="https://github.com/downloads/SteveSanderson/knockout/jquery.tmpl.js"></script>
<div id="bookform">
    <h3>Title</h3>
    <p data-bind="css: { error: title.hasError }">
        <input data-bind='value: title, valueUpdate: "afterkeydown"' />
        <span data-bind='visible: title.hasError, text: title.validationMessage'> </span>
    </p>
    <h3>Author</h3>
    <p data-bind="css: { error: author.hasError }">
        <input data-bind='value: author, valueUpdate: "afterkeydown"' />
        <span data-bind='visible: author.hasError, text: author.validationMessage'> </span>
    </p>
    <h3>Pages</h3>
    <p data-bind="css: { error: pages.hasError }">
        <input data-bind='value: pages, valueUpdate: "afterkeydown"' />
        <span data-bind='visible: pages.hasError, text: pages.validationMessage'> </span>
    </p>
</div>

CSS

h3 {
  font-size: 120%;
  font-weight: bold;  
  margin-top: 5px;
}

.error {
 color: red;   
}

#bookform {
  margin: 10px;
  padding: 20px 20px 25px 20px;  
  background-color: #eee;
}

input {
  width: 250px;   
}

JavaScript

ko.extenders.requiredField = function(target, message) {   
    target.hasError = ko.observable();
    target.validationMessage = ko.observable();
 
    function validate(newValue) {
       target.hasError(newValue ? false : true);
       target.validationMessage(newValue ? "" : message || "* required");
    }
 
    validate(target());
    target.subscribe(validate);
 
    return target;
};
 
function BookViewModel(title, author, pages) {
    this.title = ko.observable(title).extend({ requiredField: "Please enter a title" });
    this.author = ko.observable(author).extend({ requiredField: "Please enter an author" });
    this.pages = ko.observable(pages).extend({ requiredField: "" });
}

var viewModel = new BookViewModel("Windows Presentation Foundation 4.5 - EinfĂĽhrung und Praxis", "Norbert Eder", 400);
ko.applyBindings(viewModel);