Skip to content

Instantly share code, notes, and snippets.

@fjeldstad
Created April 25, 2012 15:00
Show Gist options
  • Save fjeldstad/2490381 to your computer and use it in GitHub Desktop.
Save fjeldstad/2490381 to your computer and use it in GitHub Desktop.
SetValidationResult helper function for updating a Knockout view model with validation errors from a simplified modelstate dictionary
SetValidationResult: function (viewModel, modelState) {
var trySetErrors = function (modelStateKey, modelStateErrors) {
var keySeparator = new RegExp("[.\\[\\]]+");
var propertyChain = modelStateKey.split(keySeparator);
var currentObject = viewModel;
var currentPropertyName = propertyChain.shift();
var targetObject = null;
while (currentObject && currentObject[currentPropertyName]) {
if (propertyChain.length === 0) {
targetObject = currentObject[currentPropertyName];
break;
}
currentObject = ko.utils.unwrapObservable(currentObject[currentPropertyName]);
currentPropertyName = propertyChain.shift();
}
// If a property that matches the key is found, update the Errors observable
// array on that property and remove the key from the modelState object.
if (targetObject && targetObject.Errors && ko.isObservable(targetObject.Errors)) {
targetObject.Errors(modelStateErrors);
return true;
}
return false;
};
// For each key in the previous modelstate that is not included in the current one, try to reset the error collection
var lastModelState = viewModel._lastModelState;
if (lastModelState) {
for (var oldKey in lastModelState) {
if (!modelState[oldKey] || modelState[oldKey].length === 0) {
trySetErrors(oldKey, []);
}
}
}
// Save the current modelstate to be able to clear old errors on the next validation
viewModel._lastModelState = $.extend(true, { }, modelState); // Deep-clone with jQuery
// Set error collection for all keys in the current modelstate
for (var key in modelState) {
if (trySetErrors(key, modelState[key])) {
delete modelState[key];
}
}
// All remaining current modelstate errors are "global" - add them to the ValidationSummary
// observable array of the view model itself.
var globalErrors = [];
for (key in modelState) {
globalErrors = globalErrors.concat(modelState[key]);
}
if (!viewModel || !viewModel.ValidationSummary || !ko.isObservable(viewModel.ValidationSummary)) {
throw new Error("The view model does not have a 'ValidationSummary' property of type ko.observableArray, which is required to handle general validation errors.");
}
viewModel.ValidationSummary(globalErrors);
},
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment