Knockout Custom Validation with an observable parameter

javascript, knockout-validation, knockout.js, validation

Solution

I have now managed to figure this out using the following code:

Create a custom validator function

var customMax = function(val, max) {
    return val <= max();
};

Pass the validation function and wrap the message in a function

var SpecifiedValuablesViewModel  = function (maxSpecifiedItemAmount) {
    var self = this;

    self.maxSpecifiedItemAmount = ko.observable(maxSpecifiedItemAmount);

    self.amountToAdd = ko.observable().extend({
        validation: {
            validator: customMax,
            message: function () { return 'The maximum allowed is ' + self.maxSpecifiedItemAmount(); },
            params: self.maxSpecifiedItemAmount
        }
    });

    self.maxSpecifiedItemAmount.subscribe(function (amount) {
        self.amountToAdd.isModified(false);
    });
};

var specifiedValuablesViewModel = new SpecifiedValuablesViewModel($('#ContentsReplacementAmount').val());
ko.applyBindings(ko.validatedObservable(specifiedValuablesViewModel), document.getElementById('SpecifiedValuables'));

$('#ContentsReplacementAmount').on('change', function () {
    specifiedValuablesViewModel.maxSpecifiedItemAmount(parseInt($(this).val()));
});

JSFiddle example

Problem

I have a situation where I need to validate the max amount of a field in my view model. However the max amount has to be variable and is calculated depending on a UI item selected outside of this model. I have attempted to include the observable as a parameter in my custom validator but it appears not to update when the value is changed. I have a feeling that once the validation code is executed first time it holds on to the parameters. The HTML of the list that's not using Knockout ``` <select id="ContentsReplacementAmount"> <option value="25000">£25000</option> <option value="50000">£50000</option> <option value="75000">£75000</option> </select> ``` Here is a dummed down version of the code I'm using. ``` var SpecifiedValuablesViewModel = function (maxSpecifiedItemAmount) { var self = this; self.maxSpecifiedItemAmount = ko.observable(maxSpecifiedItemAmount); self.amountToAdd = ko.observable().extend({ validation: { validator: function (val, max) { return val <= max; }, message: 'The amount must be a maximum of £{0}', params: self.maxSpecifiedItemAmount() } }); }; var specifiedValuablesViewModel = new SpecifiedValuablesViewModel($('#ContentsReplacementAmount').val()); ko.applyBindings(ko.validatedObservable(specifiedValuablesViewModel), document.getElementById('SpecifiedValuables')); ``` Event outside of the maxSpecifiedAmount ``` $('#ContentsReplacementAmount').on('change', function () { specifiedValuablesViewModel.maxSpecifiedItemAmount(parseInt($(this).val())); }); ``` My question is, how can I achieve this?

Original source