Demonstration of Knockout Validation Bug
HTML
<script src="https://raw.github.com/SteveSanderson/knockout/master/build/output/knockout-latest.debug.js"></script>
<script src="https://raw.github.com/SteveSanderson/knockout.mapping/master/knockout.mapping.js"></script>
<script src="https://raw.github.com/ericmbarnard/Knockout-Validation/master/Dist/knockout.validation.js"></script>
<button class="btn" data-bind="click: loadData">Reload</button>
<div class="span10">
<div class="row">
<div class="row">
<div class="span10">
<hr />
</div>
</div>
<div class="span10">
<div class="row">
<div class="span3">
<select data-bind="options: personFields, optionsText: 'Name', value: selectedPersonField"
size="5">
</select>
</div>
<div class="span6 well form-inline" data-bind="visible: selectedPersonField()">
<div data-bind="template: {if: selectedPersonField, name: 'attributes-template', data: selectedPersonField}">
</div>
</div>
<script type="text/html" id="attributes-template">
<div class="row control-group form-inline" data-bind="validationElement: Name">
<div class="controls">
<label class="span2">Name:</label>
<input type="text" class="span4" data-bind="value: Name, valueUpdate: 'afterkeydown'" />
<div class="row">
<label data-bind="validationMessage: Name" class="span4 offset2 help-inline">
</label>
</div>
...
JavaScript
ko.validation.configure({
registerExtenders: true,
messagesOnModified: false,
insertMessages: false,
parseInputAttributes: true,
messageTemplate: null,
grouping: {
deep: true
},
errorClass: "error",
decorateElement: true
});
function PersonAttributeListViewModel() {
var self = this;
self.personFields = ko.observableArray([]);
self.selectedPersonField = ko.observable();
self.customFieldTypes = ko.observable([]);
self.mapping = {
fieldMapping: {
create: function(options) {
// Start with the standard mapping
var newPersonField = ko.mapping.fromJS(options.data);
// Add validation rules
newPersonField.Name.extend({
required: true
})
// For text fields, if they were passed in as nulls, convert to empty string because that is what
// textboxes return
if (!newPersonField.Name()) newPersonField.Name("");
// Add fields that aren't part of the mapping
newPersonField.validationDisabled = ko.observable(false);
// Writeable computed observable to handle radio button options
newPersonField.RequirementType = ko.computed({
read: function() {
var returnVal = "NotRequired";
if (newPersonField.IsRequired()) {
returnVal = "Required"
} else if (newPersonField.IsLateRequirement) {
returnVal = "LateRequired"
}
return returnVal;
},
write: function(value) {
if (value === "Required") {
newPersonField.IsRequired(true);
newPersonField.IsLateRequirement(false);
}...