Validating Observable Array, using Knockout.Validation

6k Views Asked by At

We are building a Single Page Application using Knockout, Durandal & Breeze.

We have a observable array, & want to validate whether it contains any value or not i.e. the text box accepting values has been provided with any value or not. I am trying to achieve this using Knockout.Validation plugin.

Code for view model is-

withs = ko.observableArray([]).extend({ required: true }),

and HTML is

<div class="col-lg-9">
   <select multiple="true" 
        data-bind="options: entities, optionsValue: 'Id', optionsText: 'Name', 
                   selectedOptions: withs, select2: {}" 
        style="width: 249px; border-radius: 4px;"></select>
</div>
2

There are 2 best solutions below

3
On

Here is an alternate approach.

ko.validation.rules['minArrayLength'] = {
    validator: function (obj, params) {
        return obj.length >= params.minLength;
    },
    message: "Array does not meet minimum length requirements"
};

//Must call registerExtenders() or there will be no validation.
//It won't throw any errors either, it will just be ignored
ko.validation.registerExtenders();

//if you use this commented binding, the minLength will not come through correctly
//ko.observableArray([]).extend({ minArrayLength: { minLength: 1, message: 'Must select at least one item'} });
ko.observableArray([]).extend({ minArrayLength: { params: { minLength: 1 }, message: 'Must specify at least one unit per part number' } });

Thewad's solution is certainly valid, but if you don't have a call to registerExtenders() after your custom validation rule it could explain why the validation wasn't working for you.

1
On

You could write a custom validator like:

ko.validation.rules['arrayMustContainAtLeastOne'] = {
    validator: function (val, required) {
        if (required) {
            if (val.length > 0) {
                return true;
            }
            return false;
        }
        return true;
    },
    message: 'Require at least one item in list'
}

Would double check the docs to see if this is included first though