check this fiddle:
I was trying to do 2 things:
First: Dont validate when the field is empty. I know there is a onlyif option.. but is there something easier?
Second: I need something to run the validation when i click on submit (If you test my fiddle, the error messages will pop, but wont apply the errorClass css)
Thanks :D
css:
input.error {
color: red;
border-color: red;
}
js:
ko.validation.configure({
insertMessages: false,
decorateElement: true,
errorElementClass: 'error',
messagesOnModified: false
});
function SignInViewModel() {
var self = this;
self.userName = ko.observable().extend({
required: true
});
self.password = ko.observable().extend({
required: true
});
self.errors = ko.validation.group(self);
self.login = function (e) {
if (self.errors().length == 0) {
alert('No errors');
} else {
this.errors().forEach(function(data) {
alert(data);
});
//self.errors.showAllMessages(true);
}
}
}
$(function () {
ko.applyBindings(new SignInViewModel());
});
html :
<form>
<fieldset>
<legend>User: <span data-bind='text: errors().length'></span> errors</legend>
<label>User name: <input data-bind='value: userName' type="text"/></label><br/>
<label>Password: <input data-bind='value: password' type="password"/></label>
</fieldset>
<button type="button" data-bind='click: login'>Login</button>
</form>
The first solution will do 90% of what you are asking. It will not display any validation until the user hits submit, or until they delete a previously populated field. Once they break the seal (so to speak), they will receive real time validation feedback for that field. This is the solution I would use because it is how knockout validation was intended to behave.
self.login = function (e) {
if (self.errors().length > 0) {
self.errors.showAllMessages(true);
this.errors().forEach(function(data) {
alert(data);
});
}
}
If for some reason you have to defer all validation feedback until they click, then you could mess with the isModified flag to get the behavior you want. It seems a little kludgy to me though.
ko.extenders.deferValidation = function (target, option) {
if (option) {
target.subscribe(function(){
target.isModified(false);
});
}
return target;
};
self.userName = ko.observable().extend({
required: {message: 'User name is required' },
deferValidation: true
});
self.password = ko.observable().extend({
required: {message: "Password is required" },
deferValidation: true
});