Unobtrusive validation with dynamic content
HTML
<script src="https://github.com/jquery/jquery-tmpl/raw/master/jquery.tmpl.js"></script>
<script src="http://cloud.github.com/downloads/SteveSanderson/knockout/knockout-1.2.0.debug.js"></script>
<script src="https://github.com/brandonaaron/livequery/raw/master/jquery.livequery.js"></script>
<script src="https://github.com/jzaefferer/jquery-validation/raw/master/jquery.validate.js"></script>
<script src="//ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.validate.unobtrusive.js"></script>
<script id="rowTmpl" type="text/html">
<tr>
<td>
<input name="rowInput${Id}" type="text" data-bind="value: inputVal" data-val="true" data-val-required="Required input!"/>
<span class="field-validation-valid" data-valmsg-for="rowInput${Id}" data-valmsg-replace="true" data-bind="text: error">
No error
</span>
</td>
<td>
<select name="rowSelect${Id}" data-bind="options: ViewModel.list, optionsValue: 'key', optionsText: 'value', optionsCaption: 'Choose...', value: selected" data-val="true" data-val-required="Required select!"></select>
<span class="field-validation-valid" data-valmsg-for="rowSelect${Id}" data-valmsg-replace="true">No Error</span>
</td>
</tr>
</script>
<form id="myForm">
<div>
Does not work in IE9 at the moment. Seems to be linked to jsfiddle and the https protocol of some resources.
</div>
<table>
<thead>
<tr>
<td>Input</td>
<td>Select</td>
</tr>
</thead>
<tbody data-bind="template: { name: 'rowTmpl', foreach: rows, afterAdd: reparse }"></tbody>
</table>
<button data-bind="click: addRow">Add row</button>
<button data-bind="click: validate">Validate</button>
</form>
CSS
.field-validation-valid, .field-validation-error {
display: none;
}
.input-validation-error {
border: 1px solid #f00;
background: #fee;
}
JavaScript
(function ($) {
$.validator.unobtrusive.parseDynamicContent = function (selector) {
//use the normal unobstrusive.parse method
$.validator.unobtrusive.parse(selector);
//get the relevant form
var form = $(selector).first().closest('form');
//get the collections of unobstrusive validators, and jquery validators
//and compare the two
var unobtrusiveValidation = form.data('unobtrusiveValidation');
var validator = form.validate();
$.each(unobtrusiveValidation.options.rules, function (elname, elrules) {
if (validator.settings.rules[elname] === undefined) {
var args = {};
$.extend(args, elrules);
args.messages = unobtrusiveValidation.options.messages[elname];
$('[name=' + elname + ']').rules("add", args);
} else {
$.each(elrules, function (rulename, data) {
if (validator.settings.rules[elname][rulename] === undefined) {
var args = {};
args[rulename] = data;
args.messages = unobtrusiveValidation.options.messages[elname][rulename];
$('[name=' + elname + ']').rules("add", args);
}
});
}
});
};
})($);
var viewModel = {
list: ko.observableArray([
{ key: "1", value: "Eins" },
{ key: "2", value: "Zwei" },
{ key: "3", value: "Drei" }
]),
rows: ko.observableArray(),
mainInput: ko.observable()
};
var Row = function(viewModel, id) {
this.ViewModel = viewModel;
this.Id = id;
this.inputVal = ko.observable();
this.selected = ko.observable();
};
var counter = 0;
viewModel.addRow = function() {
this.rows.push(new Row(viewModel, ++counter));
};
viewModel.reparse = function (element) {
$.validator.unobtrusive.parseDynamicContent($(element));
};
viewModel.validate = function() {
$('#myForm').valid();
};
$(document).ready(function() {
ko.applyBindings(viewModel);
});