Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Knockout ViewModel isValid error when using Knockout validation plugin

I'm new to using knockout and I'm trying to use the knockout validation plugin along with the mapping plugin. I'm having an issue with the isValid function on the view model object. According to the documentation isValid should return a bool to determine whether any of the observables on the view model are in valid but when I call it I get an error saying that isValid is not a function. However if I call isValid on the observables themselves it works fine. The problem is I'm using the mapping plugin with some dynamic data objects that I get from the server so I don't necessarily know the names of the observables I need to validate so it's not feasible to validate them individually. The example below is simplified but in the real implementation I don't know the names of the observables. Maybe I've just missed some documentation?

Thanks for your time.

This does work

    var dataItem = { FirstName: '', LastName: '', Age: '', Email: '' }


    var viewModel = function(data) {

        var self = this;
        this.Email = ko.observable().extend({ email: true });
        this.LastName = ko.observable().extend({ required: true });
        this.Age = ko.observable().extend({ required: true, min: 0 });
        this.saveClick = function () {

            if (!self.Email.isValid() || !self.Age.isValid() || !self.LastName.isValid()) {
                alert('Not valid');
            else {

                alert('Valid');
            }
        };
        this.cancelClick = function () {

            ko.mapping.fromJS(dataItem, null, this);
        }

        ko.mapping.fromJS(data, {}, this);
    };

    var viewModelInstance = new viewModel(dataItem);
    ko.applyBindings(viewModelInstance, document.getElementById('bindingDiv'));

But this doesn't work

        var dataItem = { FirstName: '', LastName: '', Age: '', Email: '' }


        var viewModel = function(data) {

            var self = this;
            this.Email = ko.observable().extend({ email: true });
            this.LastName = ko.observable().extend({ required: true });

            this.Age = ko.observable().extend({ required: true, min: 0 });
            this.saveClick = function () {
                //TODO: according to the documentation you should be able to just
                //check self.isValid() but that throws an error that there is no
                //such method on the object? dunno why.
                if (!self.isValid()) {
                    alert('Not Valid');
                }
                else {
                    alert('Valid');
                }
            };
            this.cancelClick = function () {

                ko.mapping.fromJS(dataItem, null, this);
            }

            ko.mapping.fromJS(data, {}, this);
        };

        var viewModelInstance = new viewModel(dataItem);
        ko.applyBindings(viewModelInstance, document.getElementById('bindingDiv'));
like image 547
Cam Langsford Avatar asked Jan 13 '23 06:01

Cam Langsford


2 Answers

Just thought I'd post the actual code I needed to use. Thanks to ragnarok56 for pointing me in the right direction. I'd obviously spent too little time on the documentation.

I just added this line of code above the call to check isValid() on the view model

var result = ko.validation.group(viewModelInstance, { deep: true });
like image 179
Cam Langsford Avatar answered Jan 31 '23 06:01

Cam Langsford


Call ko.validation.group in your VM to group all the validatable observables at the VM level. Then isValid will be true only if no child observables have errors.

Some other SO answers about ko.validation.group

How to use ko.validation.group function

Knockout Validation ko.validation.group vs ko.validatedObservable

like image 29
Kevin Nacios Avatar answered Jan 31 '23 07:01

Kevin Nacios