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?
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()));
});