Add valServerMatch which we now use to highlight block rows if they have errors.
This commit is contained in:
@@ -288,7 +288,7 @@ function valPropertyMsg(serverValidationManager, localizationService, angularHel
|
||||
"",
|
||||
serverValidationManagerCallback,
|
||||
currentSegment,
|
||||
{ matchPrefix: true } // match property validation path prefix
|
||||
{ matchType: "suffix" } // match property validation path prefix
|
||||
));
|
||||
}
|
||||
|
||||
@@ -298,9 +298,7 @@ function valPropertyMsg(serverValidationManager, localizationService, angularHel
|
||||
//when the scope is disposed we need to unsubscribe
|
||||
scope.$on('$destroy', function () {
|
||||
stopWatch();
|
||||
for (var u in unsubscribe) {
|
||||
unsubscribe[u]();
|
||||
}
|
||||
unsubscribe.forEach(u => u());
|
||||
});
|
||||
|
||||
onInit();
|
||||
|
||||
@@ -13,14 +13,14 @@ function valServer(serverValidationManager) {
|
||||
link: function (scope, element, attr, ctrls) {
|
||||
|
||||
var modelCtrl = ctrls[0];
|
||||
var umbPropCtrl = ctrls.length > 1 ? ctrls[1] : null;
|
||||
var umbPropCtrl = ctrls[1];
|
||||
if (!umbPropCtrl) {
|
||||
//we cannot proceed, this validator will be disabled
|
||||
return;
|
||||
}
|
||||
|
||||
// optional reference to the varaint-content-controller, needed to avoid validation when the field is invariant on non-default languages.
|
||||
var umbVariantCtrl = ctrls.length > 2 ? ctrls[2] : null;
|
||||
var umbVariantCtrl = ctrls[2];
|
||||
|
||||
var currentProperty = umbPropCtrl.property;
|
||||
var currentCulture = currentProperty.culture;
|
||||
@@ -121,9 +121,7 @@ function valServer(serverValidationManager) {
|
||||
|
||||
scope.$on('$destroy', function () {
|
||||
stopWatch();
|
||||
for (var u in unsubscribe) {
|
||||
unsubscribe[u]();
|
||||
}
|
||||
unsubscribe.forEach(u => u());
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
|
||||
function valServerMatch(serverValidationManager) {
|
||||
return {
|
||||
require: ['form', '^^umbProperty', '?^^umbVariantContent'],
|
||||
restrict: "A",
|
||||
scope: {
|
||||
valServerMatch: "="
|
||||
},
|
||||
link: function (scope, element, attr, ctrls) {
|
||||
|
||||
var formCtrl = ctrls[0];
|
||||
var umbPropCtrl = ctrls[1];
|
||||
if (!umbPropCtrl) {
|
||||
//we cannot proceed, this validator will be disabled
|
||||
return;
|
||||
}
|
||||
|
||||
// optional reference to the varaint-content-controller, needed to avoid validation when the field is invariant on non-default languages.
|
||||
var umbVariantCtrl = ctrls[2];
|
||||
|
||||
var currentProperty = umbPropCtrl.property;
|
||||
var currentCulture = currentProperty.culture;
|
||||
var currentSegment = currentProperty.segment;
|
||||
|
||||
if (umbVariantCtrl) {
|
||||
//if we are inside of an umbVariantContent directive
|
||||
|
||||
var currentVariant = umbVariantCtrl.editor.content;
|
||||
|
||||
// Lets check if we have variants and we are on the default language then ...
|
||||
if (umbVariantCtrl.content.variants.length > 1 && (!currentVariant.language || !currentVariant.language.isDefault) && !currentCulture && !currentSegment && !currentProperty.unlockInvariantValue) {
|
||||
//This property is locked cause its a invariant property shown on a non-default language.
|
||||
//Therefor do not validate this field.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// if we have reached this part, and there is no culture, then lets fallback to invariant. To get the validation feedback for invariant language.
|
||||
currentCulture = currentCulture || "invariant";
|
||||
|
||||
var unsubscribe = [];
|
||||
|
||||
//subscribe to the server validation changes
|
||||
function serverValidationManagerCallback(isValid, propertyErrors, allErrors) {
|
||||
if (!isValid) {
|
||||
formCtrl.$setValidity('valServerMatch', false, formCtrl);
|
||||
}
|
||||
else {
|
||||
formCtrl.$setValidity('valServerMatch', true, formCtrl);
|
||||
}
|
||||
}
|
||||
|
||||
if (Utilities.isObject(scope.valServerMatch)) {
|
||||
var allowedKeys = ["contains", "prefix", "suffix"];
|
||||
Object.keys(scope.valServerMatch).forEach(k => {
|
||||
if (allowedKeys.indexOf(k) === -1) {
|
||||
throw "valServerMatch dictionary keys must be one of " + allowedKeys.join();
|
||||
}
|
||||
|
||||
unsubscribe.push(serverValidationManager.subscribe(
|
||||
scope.valServerMatch[k],
|
||||
currentCulture,
|
||||
"",
|
||||
serverValidationManagerCallback,
|
||||
currentSegment,
|
||||
{ matchType: k } // specify the match type
|
||||
));
|
||||
|
||||
});
|
||||
}
|
||||
else if (Utilities.isString(scope.valServerMatch)) {
|
||||
unsubscribe.push(serverValidationManager.subscribe(
|
||||
scope.valServerMatch,
|
||||
currentCulture,
|
||||
"",
|
||||
serverValidationManagerCallback,
|
||||
currentSegment));
|
||||
}
|
||||
else {
|
||||
throw "valServerMatch value must be a string or a dictionary";
|
||||
}
|
||||
|
||||
scope.$on('$destroy', function () {
|
||||
unsubscribe.forEach(u => u());
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
angular.module('umbraco.directives.validation').directive("valServerMatch", valServerMatch);
|
||||
@@ -129,9 +129,9 @@
|
||||
var prop = tab.properties[p];
|
||||
|
||||
// Watch value of property since this is the only value we want to keep synced.
|
||||
// Do notice that it is not performing a deep watch, meaning that we are only watching primatives and changes directly to the object of property-value.
|
||||
// But we like to sync non-primative values as well! Yes, and this does happen, just not through this code, but through the nature of JavaScript.
|
||||
// Non-primative values act as references to the same data and are therefor synced.
|
||||
// Do notice that it is not performing a deep watch, meaning that we are only watching primitive and changes directly to the object of property-value.
|
||||
// But we like to sync non-primitive values as well! Yes, and this does happen, just not through this code, but through the nature of JavaScript.
|
||||
// Non-primitive values act as references to the same data and are therefor synced.
|
||||
blockObject.__watchers.push(isolatedScope.$watch("blockObjects._" + blockObject.key + "." + field + ".variants[0].tabs[" + t + "].properties[" + p + "].value", watcherCreator(blockObject, prop)));
|
||||
|
||||
// We also like to watch our data model to be able to capture changes coming from other places.
|
||||
|
||||
@@ -63,8 +63,20 @@ angular.module("umbraco")
|
||||
}
|
||||
}
|
||||
|
||||
vm.close = function() {
|
||||
vm.close = function () {
|
||||
if (vm.model && vm.model.close) {
|
||||
// TODO: At this stage there could very well have been server errors that have been cleared
|
||||
// but if we 'close' we are basically cancelling the value changes which means we'd want to cancel
|
||||
// all of the server errors just cleared. It would be possible to do that but also quite annoying.
|
||||
// The rudimentary way would be to:
|
||||
// * Track all cleared server errors here by subscribing to the prefix validation of controls contained here
|
||||
// * If this is closed, re-add all of those server validation errors
|
||||
// A more robust way to do this would be to:
|
||||
// * Add functionality to the serverValidationManager whereby we can remove validation errors and it will
|
||||
// maintain a copy of the original errors
|
||||
// * It would have a 'commit' method to commit the removed errors - which we would call in the formHelper.submitForm when it's successful
|
||||
// * It would have a 'rollback' method to reset the removed errors - which we would call here
|
||||
|
||||
// TODO: check if content/settings has changed and ask user if they are sure.
|
||||
vm.model.close(vm.model);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
<button type="button" class="btn-reset umb-outline blockelement-labelblock-editor blockelement__draggable-element"
|
||||
ng-click="api.editBlock(block, block.hideContentInOverlay, index)"
|
||||
ng-focus="block.focus"
|
||||
ng-class="{'--active':block.active}">
|
||||
<i class="icon {{block.content.icon}}"></i>
|
||||
<span>{{block.label}}</span>
|
||||
</button>
|
||||
<ng-form name="blockRowForm" val-server-match="{ 'contains' : block.content.key }">
|
||||
<button type="button" class="btn-reset umb-outline blockelement-labelblock-editor blockelement__draggable-element"
|
||||
ng-click="api.editBlock(block, block.hideContentInOverlay, index)"
|
||||
ng-focus="block.focus"
|
||||
ng-class="{ '--active': block.active || blockRowForm.$invalid }"
|
||||
val-server-property-class="">
|
||||
<i class="icon {{block.content.icon}}"></i>
|
||||
<span>{{block.label}}</span>
|
||||
</button>
|
||||
</ng-form>
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
});
|
||||
|
||||
|
||||
it('getBlockObject syncs primative values', function (done) {
|
||||
it('getBlockObject syncs primitive values', function (done) {
|
||||
|
||||
var propertyModel = angular.copy(propertyModelMock);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user