Knockout Validation - Dont validate input when empty + evaluate when submit
Asked Answered
U

1

5

check this fiddle:

http://jsfiddle.net/bhzrw01s/

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>
Ugly answered 10/9, 2014 at 16:49 Comment(3)
Your first question doesn't really make sense. You want the fields to be required, but ONLY validate if they are not empty. That defeats the purpose of the required check; it will ONLY fail WHEN the field is empty. So please clarify a bit more :) The second question can be solved through the use of a ko.validatedObservable on your group of fields, and calling isValid() on it before you submit. This will check if the form was filled correctly, but also show the existing errors and add the error classes and such. See github.com/Knockout-Contrib/Knockout-Validation#getting-startedParris
Thanks for the answer, my first question is about how can I apply the css only when i check isValid()? Because i can deal the messages setting false to insertMessages (elements losing focus wont show validation). Do you have any idea? :DUgly
Ah, now I understand. But unfortunately I have no idea how you could achieve that.Parris
B
8

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.

http://jsfiddle.net/k08m4dfx/

    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.

http://jsfiddle.net/zd97gjg4/

    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
    });
Boldface answered 4/11, 2014 at 16:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.