Comparing two fields with knockout-validation

Matt picture Matt · Jan 29, 2013 · Viewed 11.3k times · Source

I have a viewmodel for a form that I'm trying to add validation to using knockout-validation.

fromDate: ko.observable(
            moment().subtract('days', 1).startOf('day').format(dateFormat)
          ),
toDate: ko.observable(
            moment().startOf('day').format(dateFormat)
        ),

I need to make sure that the from date is less than the to date. I can't seem to get any form of custom validator to pick up the reference to the second observable. I need something along the lines of:

toDate: ko.observable(moment().startOf('day').format(dateFormat)).extend({
          validation: {
            validator: function (val, someOtherVal) {
                return moment(val) >= moment(someOtherVal);
            },
            message: 'Must be greater or equal to From Date',
            params: viewModel.fromDate()
          }
        }),

Any ideas?

Update

I'm sure I'd already tried this, but moving the extension method into the onload function works.

$(function () {
    ko.validation.configure({ decorateElement: true });

    viewModel.toDate.extend({
    validation: {
            validator: function (val, someOtherVal) {
                return moment(val) >= moment(viewModel.fromDate());
            },
            message: 'To date must be greater than from date',
        }
    });

    ko.applyBindings(viewModel);
});

Answer

delixfe picture delixfe · Jan 30, 2013

knockout-validation's core rules are not able to handle observables as parameters for validations. But there is already a push request which should fix that: https://github.com/ericmbarnard/Knockout-Validation/pull/217

Therefore you have to use a custom role for that. You should insert the param as a function (by omitting the parenthesis). That will enable knockout-validation to react to changes in the param.

function ViewModel() {
    var self = this; // capture this to be able to reference properties

    self.fromDate = ko.observable(
        moment().subtract('days', 1).startOf('day').format(dateFormat)
    );
    self.toDate = ko.observable(
        moment().startOf('day').format(dateFormat)
    ).extend({
      validation: {
        validator: function (val, someOtherVal) {
            return moment(val) >= moment(someOtherVal());
        },
        message: 'Must be greater or equal to From Date',
        params: self.fromDate
      }
    }),
}