Knockoutjs.com - Cart editor example
http://knockoutjs.com/examples/cartEditor.html
by alansouzati
HTML
<script src="http://knockoutjs.com/examples/resources/sampleProductCategories.js"></script>
<script src="http://knockoutjs.com/downloads/knockout-3.0.0.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout-validation/1.0.2/knockout.validation.min.js"></script>
<div class="field" data-bind="visible: activeErrors().length > 0">
You have <span data-bind="text: activeErrors().length"></span> errors on your form!
</div>
<div class="field">
<p class="validationMessage" data-bind="errorMessageDisplay: firstName"></p>
First Name: <input type="text" data-bind="value: firstName, valueUpdate: 'afterkeydown', event : { change: validate.bind($data, firstName)}" class="textBox"/>
</div>
<div class="field">
<p class="validationMessage" data-bind="errorMessageDisplay: lastName"></p>
Last Name: <input type="text" data-bind="value: lastName, valueUpdate: 'afterkeydown', event : { change: validate.bind($data, lastName)}" class="textBox"/>
</div>
<div class="field">
Age: <input type="text" data-bind="value: age" class="textBox"/>
</div>
<div class="button">
<input type="button" data-bind="click: save, enable: errors().length === 0" value="Save" />
</div>
CSS
div.field {
padding: 5px;
}
div.field .textBox{
height: 20px;
}
div.button {
padding: 5px;
}
JavaScript
ko.bindingHandlers.errorMessageDisplay = {
update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var value = valueAccessor();
var jQueryElement = $(element);
if (viewModel.activeErrors().length > 0 && ko.validation.utils.isValidatable(value) && value.isModified() && !(value.isValid())) {
jQueryElement.text(viewModel.getErrorField(value).error);
jQueryElement.show();
} else {
jQueryElement.hide();
}
}
}
ko.validation.init({
decorateElement: true, // will add the css class 'validationElement' to the field with error
errorsAsTitle: false, // will not add 'title' attribute
messageOnModified: false, // displaying of error message is handled separately
insertMessages: false // displaying of error message is handled separately
}, true);
var Person = function() {
var self = this;
self.firstName = ko.observable().extend({ required: true, minLength: 3 });
self.lastName = ko.observable().extend({ required: true });;
self.age = ko.observable();
self.save = function () {
alert('Save!');
}
//validation related code
self.activeErrors = ko.observable([]);
self.activeErrors.add = function(field) {
var existingField = false;
$.each(self.activeErrors(), function(index, currentField) {
if(currentField === field) {
existingField = true;
return false;
}
});
if(!existingField) {
var array = self.activeErrors();
array.push(field);
self.activeErrors(array);
}
}
self.activeErrors.remove = function(field) {
var activeFields = $.grep(self.activeErrors(), function(currentField) {
return currentField !== field;
});
self.activeErrors(activeFields);
}
self.getErrorField =...