Scott
Scott

Reputation: 1872

knockout validation - custom validators

I'm trying to validate entries for a child's age. Valid values are '<1' and 1-29.

For this, I'm trying to create custom validators like below.

I'm assuming that these validators work in order, so I've been moving them around.

Use Cases I"m testing:

  1. User enters 30, throw 'needs to be less than 29' error
  2. User enters 0 or nothing, throw 'please say how old' error
  3. User enters '6 months', throw error for them to change value to '<1'
  4. User enters '<1' no error
  5. User enters 1 or 2 or 3 or 4..., no error

I have not been able to make it through all of these tests. #5 fails.

var ChildModel = function(cookieAge){
    var self = this,
        age = cookieAge || "";
    self.age = ko.observable(age).extend({
        validation: [{
            validator: function (val) {
                return val !== "" || parseInt(val,10) === 0;
            },
            message: 'Please say how old this child is.'
        },{
            validator: function (val, someOtherVal) {
                return val=== "<1" || val <= someOtherVal;
            },
            message: "This child's age must be less than or equal to 29.",
            params: 29
        },{
            validator: function (val) {
                var text = val.match(/(\D+)/g);
                log(text);
                return val.match(/^[0-9].$/) || text && text.length > 0;
            },
            message: "(contains text) For Children less than 1, please use '<1'"
        }]
    });
};

Upvotes: 1

Views: 4850

Answers (1)

Kevin Nacios
Kevin Nacios

Reputation: 2853

I found that combining two of the validation rules into one helped ease some of the complication. The combined validation rule short-circuits out and returns true if the value provided is a number, that way it won't inadvertently attempt to check if the value matches '<1'.

I also took advantage of the isEmptyVal utility method to help detect if the value was empty. I tried using some of the built in validation rules alongside the validation: but found they weren't working, I guess there's some limitation to that.

    validation: [{
        validator: function (val) {
            return !ko.validation.utils.isEmptyVal(val) && parseInt(val,10) !== 0;
        },
        message: 'Please say how old this child is.'
    },{
        validator: function (val, someOtherVal) {
            if (!isNaN(val)) {
                if (val > someOtherVal) {
                    this.message = "This child's age must be less than or equal to 29.";
                    return false;
                }
                return true;
            }

            if (val !== '<1') {
                this.message = "(contains text) For Children less than 1, please use '<1'";
                return false;
            }
            return true;
        },
        params: 29
    }]

Fiddle: http://jsfiddle.net/Rkkha/

Upvotes: 3

Related Questions