Ensures tree directive is using the icon filters (which we'll need to change later) Added

custom validation directives.
This commit is contained in:
Shannon
2013-06-10 12:56:32 -02:00
parent 6e83541e05
commit 3bd7fbfa9a
5 changed files with 216 additions and 1 deletions

View File

@@ -12,7 +12,7 @@ angular.module("umbraco.directives")
template: '<li><div ng-style="setTreePadding(node)">' +
'<ins ng-class="{\'icon-caret-right\': !node.expanded, \'icon-caret-down\': node.expanded}" ng-click="load(node)"></ins>' +
'<i class="icon umb-tree-icon sprTree {{node.icon}}"></i>' +
'<i class="{{node | umbTreeIconClass:\'icon umb-tree-icon sprTree\'}}" style="{{node | umbTreeIconStyle}}"></i>' +
'<a ng-click="select(this, node, $event)" ng-href="#{{node.view}}">{{node.name}}</a>' +
'<i class="umb-options" ng-click="options(this, node, $event)"><i></i><i></i><i></i></i>' +
'</div>'+

View File

@@ -0,0 +1,39 @@
/**
* @ngdoc directive
* @name umbraco.directive:valRegex
* @restrict A
* @description A custom directive to allow for matching a value against a regex string.
* NOTE: there's already an ng-pattern but this requires that a regex expression is set, not a regex string
**/
function valRegex() {
return {
require: 'ngModel',
restrict: "A",
link: function (scope, elm, attrs, ctrl) {
var regex = new RegExp(scope.$eval(attrs.valRegex));
var patternValidator = function (viewValue) {
//NOTE: we don't validate on empty values, use required validator for that
if (!viewValue || regex.test(viewValue)) {
// it is valid
ctrl.$setValidity('valRegex', true);
//assign a message to the validator
ctrl.errorMsg = "";
return viewValue;
}
else {
// it is invalid, return undefined (no model update)
ctrl.$setValidity('valRegex', false);
//assign a message to the validator
ctrl.errorMsg = "Value is invalid, it does not match the correct pattern";
return undefined;
}
};
ctrl.$formatters.push(patternValidator);
ctrl.$parsers.push(patternValidator);
}
};
}
angular.module('umbraco.directives').directive("valRegex", valRegex);

View File

@@ -0,0 +1,53 @@
/**
* @ngdoc directive
* @name umbraco.directive:valServer
* @restrict A
* @description This directive is used to associate a field with a server-side validation response
* so that the validators in angular are updated based on server-side feedback.
**/
function valServer() {
return {
require: 'ngModel',
restrict: "A",
link: function (scope, element, attr, ctrl) {
if (!scope.model || !scope.model.alias)
throw "valServer can only be used in the scope of a content property object";
var parentErrors = scope.$parent.serverErrors;
if (!parentErrors) return;
var fieldName = scope.$eval(attr.valServer);
//subscribe to the changed event of the element. This is required because when we
// have a server error we actually invalidate the form which means it cannot be
// resubmitted. So once a field is changed that has a server error assigned to it
// we need to re-validate it for the server side validator so the user can resubmit
// the form. Of course normal client-side validators will continue to execute.
element.keydown(function () {
if (ctrl.$invalid) {
ctrl.$setValidity('valServer', true);
}
});
element.change(function () {
if (ctrl.$invalid) {
ctrl.$setValidity('valServer', true);
}
});
//TODO: DO we need to watch for other changes on the element ?
//subscribe to the server validation changes
parentErrors.subscribe(scope.model, fieldName, function (isValid, propertyErrors, allErrors) {
if (!isValid) {
ctrl.$setValidity('valServer', false);
//assign an error msg property to the current validator
ctrl.errorMsg = propertyErrors[0].errorMsg;
}
else {
ctrl.$setValidity('valServer', true);
//reset the error message
ctrl.errorMsg = "";
}
}, true);
}
};
}
angular.module('umbraco.directives').directive("valServer", valServer);

View File

@@ -0,0 +1,74 @@
/**
* @ngdoc directive
* @name umbraco.directive:valSummary
* @restrict E
* @description This directive will display a validation summary for the current form based on the
content properties of the current content item.
**/
function valSummary() {
return {
scope: true, // create a new scope for this directive
replace: true, // replace the html element with the template
restrict: "E", // restrict to an element
template: '<ul class="validation-summary"><li ng-repeat="model in validationSummary">{{model}}</li></ul>',
link: function (scope, element, attr, ctrl) {
//create properties on our custom scope so we can use it in our template
scope.validationSummary = [];
//create a flag for us to be able to reference in the below closures for watching.
var showValidation = false;
//add a watch to update our waitingOnValidation flag for use in the below closures
scope.$watch("$parent.ui.waitingOnValidation", function (isWaiting, oldValue) {
showValidation = isWaiting;
if (scope.validationSummary.length > 0 && showValidation) {
element.show();
}
else {
element.hide();
}
});
//if we are to show field property based errors.
//this requires listening for bubbled events from valBubble directive.
scope.$parent.$on("valBubble", function (evt, args) {
var msg = "The value assigned for the property " + args.scope.model.label + " is invalid";
var exists = _.contains(scope.validationSummary, msg);
//we need to check if the entire property is valid, even though the args says this field is valid there
// may be multiple values attached to a content property. The easiest way to do this is check the DOM
// just like we are doing for the property level validation message.
var propertyHasErrors = args.element.closest(".content-property").find(".ng-invalid").length > 0;
if (args.isValid && exists && !propertyHasErrors) {
//it is valid but we have a val msg for it so we'll need to remove the message
scope.validationSummary = _.reject(scope.validationSummary, function (item) {
return item == msg;
});
}
else if (!args.isValid && !exists) {
//it is invalid and we don't have a msg for it already
scope.validationSummary.push(msg);
}
//show the summary if there are errors and the form has been submitted
if (showValidation && scope.validationSummary.length > 0) {
element.show();
}
});
//listen for form invalidation so we know when to hide it
scope.$watch("contentForm.$error", function (errors) {
//check if there is an error and hide the summary if not
var hasError = _.find(errors, function (err) {
return (err.length && err.length > 0);
});
if (!hasError) {
element.hide();
}
}, true);
}
};
}
angular.module('umbraco.directives').directive("valSummary", valSummary);

View File

@@ -0,0 +1,49 @@
/**
* @ngdoc directive
* @name umbraco.directive:valToggleMsg
* @restrict A
* @description This directive will show/hide an error based on: is the value + the given validator invalid? AND, has the form been submitted ?
**/
function valToggleMsg(umbFormHelper) {
return {
restrict: "A",
link: function (scope, element, attr, ctrl) {
if (!attr.valToggleMsg)
throw "valToggleMsg requires that a reference to a validator is specified";
if (!attr.valMsgFor)
throw "valToggleMsg requires that the attribute valMsgFor exists on the element";
//create a flag for us to be able to reference in the below closures for watching.
var showValidation = false;
var hasError = false;
var currentForm = umbFormHelper.getCurrentForm(scope);
if (!currentForm || !currentForm.$name)
throw "valToggleMsg requires that a name is assigned to the ng-form containing the validated input";
//add a watch to the validator for the value (i.e. $parent.myForm.value.$error.required )
scope.$watch(currentForm.$name + "." + attr.valMsgFor + ".$error." + attr.valToggleMsg, function (isInvalid, oldValue) {
hasError = isInvalid;
if (hasError && showValidation) {
element.show();
}
else {
element.hide();
}
});
//add a watch to update our waitingOnValidation flag for use in the above closure
scope.$watch("$parent.ui.waitingOnValidation", function (isWaiting, oldValue) {
showValidation = isWaiting;
if (hasError && showValidation) {
element.show();
}
else {
element.hide();
}
});
}
};
}
angular.module('umbraco.directives').directive("valToggleMsg", valToggleMsg);