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?