JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://rawgithub.com/ericmbarnard/Knockout-Validation/master/Src/knockout.validation.js"></script>
<div>
<div class="panel" data-bind="foreach: contacts">
<div>
<h4>Visitor 1</h4>
</div>
<div>
<!-- ## Panel Content -->
<div>
<label>First Name</label>
<input type="text" data-bind='value: firstName, valueUpdate: "afterkeydown"' />
</div>
<div>
<label>Last Name</label>
<input type="text" data-bind='value: fathersLast, valueUpdate: "afterkeydown"' />
</div>
<div>
<label>Country</label>
<input type="text" data-bind='value: country, valueUpdate: "afterkeydown"' />
</div>
<button data-bind='click: $root.removeContact'>Delete</button>
<button data-bind='click: $root.addContact, disable: !isValid()'>Add New</button>
<!-- ## / Panel Content -->
</div>
</div>
</div>
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
});
var initialData = [{
firstName: "John",
fathersLast: "Smith",
country: ""
}];
var Contact = function (contact) {
var self = this;
self.firstName = ko.observable(contact.firstName).extend({
required: true
});;
self.fathersLast = ko.observable(contact.fathersLast).extend({
required: { message: '* required'}
});;
self.country = ko.observable(contact.country).extend({
required: true,
minLength: 2,
});
ko.validation.group(self).showAllMessages();
return self;
}
var ContactsModel = function (contacts) {
var self = this;
self.contacts = ko.observableArray(ko.utils.arrayMap(contacts, function (i) {
return new Contact(i);
}));
self.addContact = function () {
self.contacts.push(new Contact({
firstName: "",
fathersLast: "",
country: ""
}));
};
self.removeContact = function (contact) {
self.contacts.remove(contact);
};
};
var vm = new ContactsModel(initialData)
ko.applyBindings(vm);