Categorised directives into seperate folders
This commit is contained in:
@@ -1,2 +1,4 @@
|
||||
angular.module("umbraco.directives", ["umbraco.directives.editors"]);
|
||||
angular.module("umbraco.directives.editors", []);
|
||||
angular.module("umbraco.directives", ["umbraco.directives.editors", "umbraco.directives.html", "umbraco.directives.validation"]);
|
||||
angular.module("umbraco.directives.editors", []);
|
||||
angular.module("umbraco.directives.html", []);
|
||||
angular.module("umbraco.directives.validation", []);
|
||||
@@ -0,0 +1,2 @@
|
||||
The html directives does nothing but display html, with simple one-way binding
|
||||
and is therefore simpler to use then alot of the strict property bound ones
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name umbraco.directives.directive:umbProperty
|
||||
* @restrict E
|
||||
**/
|
||||
angular.module("umbraco.directives.html")
|
||||
.directive('umbControlGroup', function () {
|
||||
return {
|
||||
scope: {
|
||||
label: "@",
|
||||
description: "@",
|
||||
hideLabel: "@",
|
||||
alias: "@"
|
||||
},
|
||||
transclude: true,
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
templateUrl: 'views/directives/html/umb-control-group.html'
|
||||
};
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name umbraco.directives.directive:umbProperty
|
||||
* @restrict E
|
||||
**/
|
||||
angular.module("umbraco.directives.html")
|
||||
.directive('umbPane', function () {
|
||||
return {
|
||||
transclude: true,
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
templateUrl: 'views/directives/html/umb-pane.html'
|
||||
};
|
||||
});
|
||||
@@ -1,14 +1,14 @@
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name umbraco.directives.directive:umbPanel
|
||||
* @restrict E
|
||||
**/
|
||||
angular.module("umbraco.directives")
|
||||
.directive('umbPanel', function(){
|
||||
return {
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
transclude: 'true',
|
||||
templateUrl: 'views/directives/umb-panel.html'
|
||||
};
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name umbraco.directives.directive:umbPanel
|
||||
* @restrict E
|
||||
**/
|
||||
angular.module("umbraco.directives.html")
|
||||
.directive('umbPanel', function(){
|
||||
return {
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
transclude: 'true',
|
||||
templateUrl: 'views/directives/html/umb-panel.html'
|
||||
};
|
||||
});
|
||||
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* General-purpose validator for ngModel.
|
||||
* angular.js comes with several built-in validation mechanism for input fields (ngRequired, ngPattern etc.) but using
|
||||
* an arbitrary validation function requires creation of a custom formatters and / or parsers.
|
||||
* The ui-validate directive makes it easy to use any function(s) defined in scope as a validator function(s).
|
||||
* A validator function will trigger validation on both model and input changes.
|
||||
*
|
||||
* @example <input val-custom=" 'myValidatorFunction($value)' ">
|
||||
* @example <input val-custom="{ foo : '$value > anotherModel', bar : 'validateFoo($value)' }">
|
||||
* @example <input val-custom="{ foo : '$value > anotherModel' }" val-custom-watch=" 'anotherModel' ">
|
||||
* @example <input val-custom="{ foo : '$value > anotherModel', bar : 'validateFoo($value)' }" val-custom-watch=" { foo : 'anotherModel' } ">
|
||||
*
|
||||
* @param val-custom {string|object literal} If strings is passed it should be a scope's function to be used as a validator.
|
||||
* If an object literal is passed a key denotes a validation error key while a value should be a validator function.
|
||||
* In both cases validator function should take a value to validate as its argument and should return true/false indicating a validation result.
|
||||
*/
|
||||
|
||||
/*
|
||||
This code comes from the angular UI project, we had to change the directive name and module
|
||||
but other then that its unmodified
|
||||
*/
|
||||
angular.module('umbraco.directives.validation')
|
||||
.directive('valCustom', function () {
|
||||
|
||||
return {
|
||||
restrict: 'A',
|
||||
require: 'ngModel',
|
||||
link: function (scope, elm, attrs, ctrl) {
|
||||
var validateFn, watch, validators = {},
|
||||
validateExpr = scope.$eval(attrs.valCustom);
|
||||
|
||||
if (!validateExpr){ return;}
|
||||
|
||||
if (angular.isString(validateExpr)) {
|
||||
validateExpr = { validator: validateExpr };
|
||||
}
|
||||
|
||||
angular.forEach(validateExpr, function (exprssn, key) {
|
||||
validateFn = function (valueToValidate) {
|
||||
var expression = scope.$eval(exprssn, { '$value' : valueToValidate });
|
||||
if (angular.isObject(expression) && angular.isFunction(expression.then)) {
|
||||
// expression is a promise
|
||||
expression.then(function(){
|
||||
ctrl.$setValidity(key, true);
|
||||
}, function(){
|
||||
ctrl.$setValidity(key, false);
|
||||
});
|
||||
return valueToValidate;
|
||||
} else if (expression) {
|
||||
// expression is true
|
||||
ctrl.$setValidity(key, true);
|
||||
return valueToValidate;
|
||||
} else {
|
||||
// expression is false
|
||||
ctrl.$setValidity(key, false);
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
validators[key] = validateFn;
|
||||
ctrl.$formatters.push(validateFn);
|
||||
ctrl.$parsers.push(validateFn);
|
||||
});
|
||||
|
||||
function apply_watch(watch)
|
||||
{
|
||||
//string - update all validators on expression change
|
||||
if (angular.isString(watch))
|
||||
{
|
||||
scope.$watch(watch, function(){
|
||||
angular.forEach(validators, function(validatorFn){
|
||||
validatorFn(ctrl.$modelValue);
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
//array - update all validators on change of any expression
|
||||
if (angular.isArray(watch))
|
||||
{
|
||||
angular.forEach(watch, function(expression){
|
||||
scope.$watch(expression, function()
|
||||
{
|
||||
angular.forEach(validators, function(validatorFn){
|
||||
validatorFn(ctrl.$modelValue);
|
||||
});
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
//object - update appropriate validator
|
||||
if (angular.isObject(watch))
|
||||
{
|
||||
angular.forEach(watch, function(expression, validatorKey)
|
||||
{
|
||||
//value is string - look after one expression
|
||||
if (angular.isString(expression))
|
||||
{
|
||||
scope.$watch(expression, function(){
|
||||
validators[validatorKey](ctrl.$modelValue);
|
||||
});
|
||||
}
|
||||
|
||||
//value is array - look after all expressions in array
|
||||
if (angular.isArray(expression))
|
||||
{
|
||||
angular.forEach(expression, function(intExpression)
|
||||
{
|
||||
scope.$watch(intExpression, function(){
|
||||
validators[validatorKey](ctrl.$modelValue);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
// Support for val-custom-watch
|
||||
if (attrs.valCustomWatch){
|
||||
apply_watch( scope.$eval(attrs.valCustomWatch) );
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -1,30 +1,30 @@
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name umbraco.directives.directive:valHighlight
|
||||
* @restrict A
|
||||
* @description Used on input fields when you want to signal that they are in error, this will highlight the item for 1 second
|
||||
**/
|
||||
function valHighlight($timeout) {
|
||||
return {
|
||||
restrict: "A",
|
||||
link: function (scope, element, attrs, ctrl) {
|
||||
|
||||
scope.$watch(function() {
|
||||
return scope.$eval(attrs.valHighlight);
|
||||
}, function(newVal, oldVal) {
|
||||
if (newVal === true) {
|
||||
element.addClass("highlight-error");
|
||||
$timeout(function () {
|
||||
//set the bound scope property to false
|
||||
scope[attrs.valHighlight] = false;
|
||||
}, 1000);
|
||||
}
|
||||
else {
|
||||
element.removeClass("highlight-error");
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name umbraco.directives.directive:valHighlight
|
||||
* @restrict A
|
||||
* @description Used on input fields when you want to signal that they are in error, this will highlight the item for 1 second
|
||||
**/
|
||||
function valHighlight($timeout) {
|
||||
return {
|
||||
restrict: "A",
|
||||
link: function (scope, element, attrs, ctrl) {
|
||||
|
||||
scope.$watch(function() {
|
||||
return scope.$eval(attrs.valHighlight);
|
||||
}, function(newVal, oldVal) {
|
||||
if (newVal === true) {
|
||||
element.addClass("highlight-error");
|
||||
$timeout(function () {
|
||||
//set the bound scope property to false
|
||||
scope[attrs.valHighlight] = false;
|
||||
}, 1000);
|
||||
}
|
||||
else {
|
||||
element.removeClass("highlight-error");
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
angular.module('umbraco.directives').directive("valHighlight", valHighlight);
|
||||
@@ -0,0 +1,22 @@
|
||||
angular.module('umbraco.directives.validation')
|
||||
.directive('valCompare',function () {
|
||||
return {
|
||||
require: "ngModel",
|
||||
link: function(scope, elem, attrs, ctrl) {
|
||||
var otherInput = elem.inheritedData("$formController")[attrs.valCompare];
|
||||
|
||||
ctrl.$parsers.push(function(value) {
|
||||
if(value === otherInput.$viewValue) {
|
||||
ctrl.$setValidity("valCompare", true);
|
||||
return value;
|
||||
}
|
||||
ctrl.$setValidity("valCompare", false);
|
||||
});
|
||||
|
||||
otherInput.$parsers.push(function(value) {
|
||||
ctrl.$setValidity("valCompare", value === ctrl.$viewValue);
|
||||
return value;
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -1,151 +1,151 @@
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name umbraco.directives.directive:valPropertyMsg
|
||||
* @restrict A
|
||||
* @element textarea
|
||||
* @requires formController
|
||||
* @description This directive is used to control the display of the property level validation message.
|
||||
* We will listen for server side validation changes
|
||||
* and when an error is detected for this property we'll show the error message
|
||||
**/
|
||||
function valPropertyMsg(serverValidationManager) {
|
||||
return {
|
||||
scope: {
|
||||
property: "=property"
|
||||
},
|
||||
require: "^form", //require that this directive is contained within an ngForm
|
||||
replace: true, //replace the element with the template
|
||||
restrict: "E", //restrict to element
|
||||
template: "<div ng-show=\"errorMsg != ''\" class='alert alert-error property-error' >{{errorMsg}}</div>",
|
||||
|
||||
/**
|
||||
Our directive requries a reference to a form controller
|
||||
which gets passed in to this parameter
|
||||
*/
|
||||
link: function (scope, element, attrs, formCtrl) {
|
||||
|
||||
//assign the form control to our isolated scope so we can watch it's values
|
||||
scope.formCtrl = formCtrl;
|
||||
|
||||
//if there's any remaining errors in the server validation service then we should show them.
|
||||
var showValidation = serverValidationManager.items.length > 0;
|
||||
var hasError = false;
|
||||
|
||||
//create properties on our custom scope so we can use it in our template
|
||||
scope.errorMsg = "";
|
||||
|
||||
//listen for error changes
|
||||
scope.$watch("formCtrl.$error", function () {
|
||||
if (formCtrl.$invalid) {
|
||||
|
||||
//first we need to check if the valPropertyMsg validity is invalid
|
||||
if (formCtrl.$error.valPropertyMsg && formCtrl.$error.valPropertyMsg.length > 0) {
|
||||
//since we already have an error we'll just return since this means we've already set the
|
||||
// hasError and errorMsg properties which occurs below in the serverValidationManager.subscribe
|
||||
return;
|
||||
}
|
||||
else if (element.closest(".umb-control-group").find(".ng-invalid").length > 0) {
|
||||
//check if it's one of the properties that is invalid in the current content property
|
||||
hasError = true;
|
||||
//update the validation message if we don't already have one assigned.
|
||||
if (showValidation && scope.errorMsg === "") {
|
||||
var err;
|
||||
//this can be null if no property was assigned
|
||||
if (scope.property) {
|
||||
err = serverValidationManager.getPropertyError(scope.property.alias, "");
|
||||
}
|
||||
scope.errorMsg = err ? err.errorMsg : "Property has errors";
|
||||
}
|
||||
}
|
||||
else {
|
||||
hasError = false;
|
||||
scope.errorMsg = "";
|
||||
}
|
||||
}
|
||||
else {
|
||||
hasError = false;
|
||||
scope.errorMsg = "";
|
||||
}
|
||||
}, true);
|
||||
|
||||
//listen for the forms saving event
|
||||
scope.$on("saving", function (ev, args) {
|
||||
showValidation = true;
|
||||
if (hasError && scope.errorMsg === "") {
|
||||
var err;
|
||||
//this can be null if no property was assigned
|
||||
if (scope.property) {
|
||||
err = serverValidationManager.getPropertyError(scope.property.alias, "");
|
||||
}
|
||||
scope.errorMsg = err ? err.errorMsg : "Property has errors";
|
||||
}
|
||||
else if (!hasError) {
|
||||
scope.errorMsg = "";
|
||||
}
|
||||
});
|
||||
|
||||
//listen for the forms saved event
|
||||
scope.$on("saved", function (ev, args) {
|
||||
showValidation = false;
|
||||
scope.errorMsg = "";
|
||||
formCtrl.$setValidity('valPropertyMsg', true);
|
||||
});
|
||||
|
||||
//We need to subscribe to any changes to our model (based on user input)
|
||||
// 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.
|
||||
scope.$watch("property.value", function (newValue) {
|
||||
//we are explicitly checking for valServer errors here, since we shouldn't auto clear
|
||||
// based on other errors. We'll also check if there's no other validation errors apart from valPropertyMsg, if valPropertyMsg
|
||||
// is the only one, then we'll clear.
|
||||
|
||||
var errCount = 0;
|
||||
for (var e in scope.formCtrl.$error) {
|
||||
errCount++;
|
||||
}
|
||||
|
||||
if ((errCount === 1 && scope.formCtrl.$error.valPropertyMsg !== undefined) ||
|
||||
(formCtrl.$invalid && scope.formCtrl.$error.valServer !== undefined)) {
|
||||
scope.errorMsg = "";
|
||||
formCtrl.$setValidity('valPropertyMsg', true);
|
||||
}
|
||||
}, true);
|
||||
|
||||
//listen for server validation changes
|
||||
// NOTE: we pass in "" in order to listen for all validation changes to the content property, not for
|
||||
// validation changes to fields in the property this is because some server side validators may not
|
||||
// return the field name for which the error belongs too, just the property for which it belongs.
|
||||
// It's important to note that we need to subscribe to server validation changes here because we always must
|
||||
// indicate that a content property is invalid at the property level since developers may not actually implement
|
||||
// the correct field validation in their property editors.
|
||||
|
||||
if (scope.property) { //this can be null if no property was assigned
|
||||
serverValidationManager.subscribe(scope.property.alias, "", function(isValid, propertyErrors, allErrors) {
|
||||
hasError = !isValid;
|
||||
if (hasError) {
|
||||
//set the error message to the server message
|
||||
scope.errorMsg = propertyErrors[0].errorMsg;
|
||||
//flag that the current validator is invalid
|
||||
formCtrl.$setValidity('valPropertyMsg', false);
|
||||
}
|
||||
else {
|
||||
scope.errorMsg = "";
|
||||
//flag that the current validator is valid
|
||||
formCtrl.$setValidity('valPropertyMsg', true);
|
||||
}
|
||||
});
|
||||
|
||||
//when the element is disposed we need to unsubscribe!
|
||||
// NOTE: this is very important otherwise when this controller re-binds the previous subscriptsion will remain
|
||||
// but they are a different callback instance than the above.
|
||||
element.bind('$destroy', function() {
|
||||
serverValidationManager.unsubscribe(scope.property.alias, "");
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name umbraco.directives.directive:valPropertyMsg
|
||||
* @restrict A
|
||||
* @element textarea
|
||||
* @requires formController
|
||||
* @description This directive is used to control the display of the property level validation message.
|
||||
* We will listen for server side validation changes
|
||||
* and when an error is detected for this property we'll show the error message
|
||||
**/
|
||||
function valPropertyMsg(serverValidationManager) {
|
||||
return {
|
||||
scope: {
|
||||
property: "=property"
|
||||
},
|
||||
require: "^form", //require that this directive is contained within an ngForm
|
||||
replace: true, //replace the element with the template
|
||||
restrict: "E", //restrict to element
|
||||
template: "<div ng-show=\"errorMsg != ''\" class='alert alert-error property-error' >{{errorMsg}}</div>",
|
||||
|
||||
/**
|
||||
Our directive requries a reference to a form controller
|
||||
which gets passed in to this parameter
|
||||
*/
|
||||
link: function (scope, element, attrs, formCtrl) {
|
||||
|
||||
//assign the form control to our isolated scope so we can watch it's values
|
||||
scope.formCtrl = formCtrl;
|
||||
|
||||
//if there's any remaining errors in the server validation service then we should show them.
|
||||
var showValidation = serverValidationManager.items.length > 0;
|
||||
var hasError = false;
|
||||
|
||||
//create properties on our custom scope so we can use it in our template
|
||||
scope.errorMsg = "";
|
||||
|
||||
//listen for error changes
|
||||
scope.$watch("formCtrl.$error", function () {
|
||||
if (formCtrl.$invalid) {
|
||||
|
||||
//first we need to check if the valPropertyMsg validity is invalid
|
||||
if (formCtrl.$error.valPropertyMsg && formCtrl.$error.valPropertyMsg.length > 0) {
|
||||
//since we already have an error we'll just return since this means we've already set the
|
||||
// hasError and errorMsg properties which occurs below in the serverValidationManager.subscribe
|
||||
return;
|
||||
}
|
||||
else if (element.closest(".umb-control-group").find(".ng-invalid").length > 0) {
|
||||
//check if it's one of the properties that is invalid in the current content property
|
||||
hasError = true;
|
||||
//update the validation message if we don't already have one assigned.
|
||||
if (showValidation && scope.errorMsg === "") {
|
||||
var err;
|
||||
//this can be null if no property was assigned
|
||||
if (scope.property) {
|
||||
err = serverValidationManager.getPropertyError(scope.property.alias, "");
|
||||
}
|
||||
scope.errorMsg = err ? err.errorMsg : "Property has errors";
|
||||
}
|
||||
}
|
||||
else {
|
||||
hasError = false;
|
||||
scope.errorMsg = "";
|
||||
}
|
||||
}
|
||||
else {
|
||||
hasError = false;
|
||||
scope.errorMsg = "";
|
||||
}
|
||||
}, true);
|
||||
|
||||
//listen for the forms saving event
|
||||
scope.$on("saving", function (ev, args) {
|
||||
showValidation = true;
|
||||
if (hasError && scope.errorMsg === "") {
|
||||
var err;
|
||||
//this can be null if no property was assigned
|
||||
if (scope.property) {
|
||||
err = serverValidationManager.getPropertyError(scope.property.alias, "");
|
||||
}
|
||||
scope.errorMsg = err ? err.errorMsg : "Property has errors";
|
||||
}
|
||||
else if (!hasError) {
|
||||
scope.errorMsg = "";
|
||||
}
|
||||
});
|
||||
|
||||
//listen for the forms saved event
|
||||
scope.$on("saved", function (ev, args) {
|
||||
showValidation = false;
|
||||
scope.errorMsg = "";
|
||||
formCtrl.$setValidity('valPropertyMsg', true);
|
||||
});
|
||||
|
||||
//We need to subscribe to any changes to our model (based on user input)
|
||||
// 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.
|
||||
scope.$watch("property.value", function (newValue) {
|
||||
//we are explicitly checking for valServer errors here, since we shouldn't auto clear
|
||||
// based on other errors. We'll also check if there's no other validation errors apart from valPropertyMsg, if valPropertyMsg
|
||||
// is the only one, then we'll clear.
|
||||
|
||||
var errCount = 0;
|
||||
for (var e in scope.formCtrl.$error) {
|
||||
errCount++;
|
||||
}
|
||||
|
||||
if ((errCount === 1 && scope.formCtrl.$error.valPropertyMsg !== undefined) ||
|
||||
(formCtrl.$invalid && scope.formCtrl.$error.valServer !== undefined)) {
|
||||
scope.errorMsg = "";
|
||||
formCtrl.$setValidity('valPropertyMsg', true);
|
||||
}
|
||||
}, true);
|
||||
|
||||
//listen for server validation changes
|
||||
// NOTE: we pass in "" in order to listen for all validation changes to the content property, not for
|
||||
// validation changes to fields in the property this is because some server side validators may not
|
||||
// return the field name for which the error belongs too, just the property for which it belongs.
|
||||
// It's important to note that we need to subscribe to server validation changes here because we always must
|
||||
// indicate that a content property is invalid at the property level since developers may not actually implement
|
||||
// the correct field validation in their property editors.
|
||||
|
||||
if (scope.property) { //this can be null if no property was assigned
|
||||
serverValidationManager.subscribe(scope.property.alias, "", function(isValid, propertyErrors, allErrors) {
|
||||
hasError = !isValid;
|
||||
if (hasError) {
|
||||
//set the error message to the server message
|
||||
scope.errorMsg = propertyErrors[0].errorMsg;
|
||||
//flag that the current validator is invalid
|
||||
formCtrl.$setValidity('valPropertyMsg', false);
|
||||
}
|
||||
else {
|
||||
scope.errorMsg = "";
|
||||
//flag that the current validator is valid
|
||||
formCtrl.$setValidity('valPropertyMsg', true);
|
||||
}
|
||||
});
|
||||
|
||||
//when the element is disposed we need to unsubscribe!
|
||||
// NOTE: this is very important otherwise when this controller re-binds the previous subscriptsion will remain
|
||||
// but they are a different callback instance than the above.
|
||||
element.bind('$destroy', function() {
|
||||
serverValidationManager.unsubscribe(scope.property.alias, "");
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
angular.module('umbraco.directives').directive("valPropertyMsg", valPropertyMsg);
|
||||
@@ -1,45 +1,45 @@
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name umbraco.directives.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;
|
||||
try {
|
||||
regex = new RegExp(scope.$eval(attrs.valRegex));
|
||||
}
|
||||
catch(e) {
|
||||
regex = new RegExp(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);
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name umbraco.directives.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;
|
||||
try {
|
||||
regex = new RegExp(scope.$eval(attrs.valRegex));
|
||||
}
|
||||
catch(e) {
|
||||
regex = new RegExp(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);
|
||||
@@ -1,63 +1,63 @@
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name umbraco.directives.directive:valServer
|
||||
* @restrict A
|
||||
* @description This directive is used to associate a content property with a server-side validation response
|
||||
* so that the validators in angular are updated based on server-side feedback.
|
||||
**/
|
||||
function valServer(serverValidationManager) {
|
||||
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 currentProperty = scope.model;
|
||||
|
||||
//default to 'value' if nothing is set
|
||||
var fieldName = "value";
|
||||
if (attr.valServer) {
|
||||
fieldName = scope.$eval(attr.valServer);
|
||||
if (!fieldName) {
|
||||
//eval returned nothing so just use the string
|
||||
fieldName = attr.valServer;
|
||||
}
|
||||
}
|
||||
|
||||
//subscribe to the changed event of the view model. 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.
|
||||
ctrl.$viewChangeListeners.push(function () {
|
||||
if (ctrl.$invalid) {
|
||||
ctrl.$setValidity('valServer', true);
|
||||
}
|
||||
});
|
||||
|
||||
//subscribe to the server validation changes
|
||||
serverValidationManager.subscribe(currentProperty.alias, 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 = "";
|
||||
}
|
||||
});
|
||||
|
||||
//when the element is disposed we need to unsubscribe!
|
||||
// NOTE: this is very important otherwise when this controller re-binds the previous subscriptsion will remain
|
||||
// but they are a different callback instance than the above.
|
||||
element.bind('$destroy', function () {
|
||||
serverValidationManager.unsubscribe(currentProperty.alias, fieldName);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name umbraco.directives.directive:valServer
|
||||
* @restrict A
|
||||
* @description This directive is used to associate a content property with a server-side validation response
|
||||
* so that the validators in angular are updated based on server-side feedback.
|
||||
**/
|
||||
function valServer(serverValidationManager) {
|
||||
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 currentProperty = scope.model;
|
||||
|
||||
//default to 'value' if nothing is set
|
||||
var fieldName = "value";
|
||||
if (attr.valServer) {
|
||||
fieldName = scope.$eval(attr.valServer);
|
||||
if (!fieldName) {
|
||||
//eval returned nothing so just use the string
|
||||
fieldName = attr.valServer;
|
||||
}
|
||||
}
|
||||
|
||||
//subscribe to the changed event of the view model. 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.
|
||||
ctrl.$viewChangeListeners.push(function () {
|
||||
if (ctrl.$invalid) {
|
||||
ctrl.$setValidity('valServer', true);
|
||||
}
|
||||
});
|
||||
|
||||
//subscribe to the server validation changes
|
||||
serverValidationManager.subscribe(currentProperty.alias, 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 = "";
|
||||
}
|
||||
});
|
||||
|
||||
//when the element is disposed we need to unsubscribe!
|
||||
// NOTE: this is very important otherwise when this controller re-binds the previous subscriptsion will remain
|
||||
// but they are a different callback instance than the above.
|
||||
element.bind('$destroy', function () {
|
||||
serverValidationManager.unsubscribe(currentProperty.alias, fieldName);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
angular.module('umbraco.directives').directive("valServer", valServer);
|
||||
@@ -1,54 +1,54 @@
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name umbraco.directives.directive:valServerField
|
||||
* @restrict A
|
||||
* @description This directive is used to associate a content field (not user defined) with a server-side validation response
|
||||
* so that the validators in angular are updated based on server-side feedback.
|
||||
**/
|
||||
function valServerField(serverValidationManager) {
|
||||
return {
|
||||
require: 'ngModel',
|
||||
restrict: "A",
|
||||
link: function (scope, element, attr, ctrl) {
|
||||
|
||||
if (!attr.valServerField) {
|
||||
throw "valServerField must have a field name for referencing server errors";
|
||||
}
|
||||
|
||||
var fieldName = attr.valServerField;
|
||||
|
||||
//subscribe to the changed event of the view model. 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.
|
||||
ctrl.$viewChangeListeners.push(function () {
|
||||
if (ctrl.$invalid) {
|
||||
ctrl.$setValidity('valServerField', true);
|
||||
}
|
||||
});
|
||||
|
||||
//subscribe to the server validation changes
|
||||
serverValidationManager.subscribe(null, fieldName, function (isValid, fieldErrors, allErrors) {
|
||||
if (!isValid) {
|
||||
ctrl.$setValidity('valServerField', false);
|
||||
//assign an error msg property to the current validator
|
||||
ctrl.errorMsg = fieldErrors[0].errorMsg;
|
||||
}
|
||||
else {
|
||||
ctrl.$setValidity('valServerField', true);
|
||||
//reset the error message
|
||||
ctrl.errorMsg = "";
|
||||
}
|
||||
});
|
||||
|
||||
//when the element is disposed we need to unsubscribe!
|
||||
// NOTE: this is very important otherwise when this controller re-binds the previous subscriptsion will remain
|
||||
// but they are a different callback instance than the above.
|
||||
element.bind('$destroy', function () {
|
||||
serverValidationManager.unsubscribe(null, fieldName);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name umbraco.directives.directive:valServerField
|
||||
* @restrict A
|
||||
* @description This directive is used to associate a content field (not user defined) with a server-side validation response
|
||||
* so that the validators in angular are updated based on server-side feedback.
|
||||
**/
|
||||
function valServerField(serverValidationManager) {
|
||||
return {
|
||||
require: 'ngModel',
|
||||
restrict: "A",
|
||||
link: function (scope, element, attr, ctrl) {
|
||||
|
||||
if (!attr.valServerField) {
|
||||
throw "valServerField must have a field name for referencing server errors";
|
||||
}
|
||||
|
||||
var fieldName = attr.valServerField;
|
||||
|
||||
//subscribe to the changed event of the view model. 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.
|
||||
ctrl.$viewChangeListeners.push(function () {
|
||||
if (ctrl.$invalid) {
|
||||
ctrl.$setValidity('valServerField', true);
|
||||
}
|
||||
});
|
||||
|
||||
//subscribe to the server validation changes
|
||||
serverValidationManager.subscribe(null, fieldName, function (isValid, fieldErrors, allErrors) {
|
||||
if (!isValid) {
|
||||
ctrl.$setValidity('valServerField', false);
|
||||
//assign an error msg property to the current validator
|
||||
ctrl.errorMsg = fieldErrors[0].errorMsg;
|
||||
}
|
||||
else {
|
||||
ctrl.$setValidity('valServerField', true);
|
||||
//reset the error message
|
||||
ctrl.errorMsg = "";
|
||||
}
|
||||
});
|
||||
|
||||
//when the element is disposed we need to unsubscribe!
|
||||
// NOTE: this is very important otherwise when this controller re-binds the previous subscriptsion will remain
|
||||
// but they are a different callback instance than the above.
|
||||
element.bind('$destroy', function () {
|
||||
serverValidationManager.unsubscribe(null, fieldName);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
angular.module('umbraco.directives').directive("valServerField", valServerField);
|
||||
@@ -1,32 +1,32 @@
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name umbraco.directives.directive:valShowValidation
|
||||
* @restrict A
|
||||
* @description Used to toggle the show-validation class on the element containing the form elements to validate.
|
||||
* This is used because we don't want to show validation messages until after the form is submitted and then reset
|
||||
* the process when the form is successful. We do this by listening to the current controller's saving and saved events.
|
||||
**/
|
||||
function valShowValidation(serverValidationManager) {
|
||||
return {
|
||||
restrict: "A",
|
||||
link: function (scope, element, attr, ctrl) {
|
||||
|
||||
//we should show validation if there are any msgs in the server validation collection
|
||||
if (serverValidationManager.items.length > 0) {
|
||||
element.addClass("show-validation");
|
||||
}
|
||||
|
||||
//listen for the forms saving event
|
||||
scope.$on("saving", function (ev, args) {
|
||||
element.addClass("show-validation");
|
||||
});
|
||||
|
||||
//listen for the forms saved event
|
||||
scope.$on("saved", function (ev, args) {
|
||||
element.removeClass("show-validation");
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name umbraco.directives.directive:valShowValidation
|
||||
* @restrict A
|
||||
* @description Used to toggle the show-validation class on the element containing the form elements to validate.
|
||||
* This is used because we don't want to show validation messages until after the form is submitted and then reset
|
||||
* the process when the form is successful. We do this by listening to the current controller's saving and saved events.
|
||||
**/
|
||||
function valShowValidation(serverValidationManager) {
|
||||
return {
|
||||
restrict: "A",
|
||||
link: function (scope, element, attr, ctrl) {
|
||||
|
||||
//we should show validation if there are any msgs in the server validation collection
|
||||
if (serverValidationManager.items.length > 0) {
|
||||
element.addClass("show-validation");
|
||||
}
|
||||
|
||||
//listen for the forms saving event
|
||||
scope.$on("saving", function (ev, args) {
|
||||
element.addClass("show-validation");
|
||||
});
|
||||
|
||||
//listen for the forms saved event
|
||||
scope.$on("saved", function (ev, args) {
|
||||
element.removeClass("show-validation");
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
angular.module('umbraco.directives').directive("valShowValidation", valShowValidation);
|
||||
@@ -1,40 +1,40 @@
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name umbraco.directives.directive:valTab
|
||||
* @restrict A
|
||||
* @description Used to show validation warnings for a tab to indicate that the tab content has validations errors in its data.
|
||||
**/
|
||||
function valTab() {
|
||||
return {
|
||||
require: "^form",
|
||||
restrict: "A",
|
||||
link: function (scope, element, attr, formCtrl) {
|
||||
|
||||
var tabId = "tab" + scope.tab.id;
|
||||
|
||||
//assign the form control to our isolated scope so we can watch it's values
|
||||
scope.formCtrl = formCtrl;
|
||||
scope.tabHasError = false;
|
||||
|
||||
//watch the current form's validation for the current field name
|
||||
scope.$watch("formCtrl.$valid", function () {
|
||||
var tabContent = element.closest(".umb-panel").find("#" + tabId);
|
||||
|
||||
if (formCtrl.$invalid) {
|
||||
//check if the validation messages are contained inside of this tabs
|
||||
if (tabContent.find(".ng-invalid").length > 0) {
|
||||
scope.tabHasError = true;
|
||||
}
|
||||
else {
|
||||
scope.tabHasError = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
scope.tabHasError = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name umbraco.directives.directive:valTab
|
||||
* @restrict A
|
||||
* @description Used to show validation warnings for a tab to indicate that the tab content has validations errors in its data.
|
||||
**/
|
||||
function valTab() {
|
||||
return {
|
||||
require: "^form",
|
||||
restrict: "A",
|
||||
link: function (scope, element, attr, formCtrl) {
|
||||
|
||||
var tabId = "tab" + scope.tab.id;
|
||||
|
||||
//assign the form control to our isolated scope so we can watch it's values
|
||||
scope.formCtrl = formCtrl;
|
||||
scope.tabHasError = false;
|
||||
|
||||
//watch the current form's validation for the current field name
|
||||
scope.$watch("formCtrl.$valid", function () {
|
||||
var tabContent = element.closest(".umb-panel").find("#" + tabId);
|
||||
|
||||
if (formCtrl.$invalid) {
|
||||
//check if the validation messages are contained inside of this tabs
|
||||
if (tabContent.find(".ng-invalid").length > 0) {
|
||||
scope.tabHasError = true;
|
||||
}
|
||||
else {
|
||||
scope.tabHasError = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
scope.tabHasError = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
angular.module('umbraco.directives').directive("valTab", valTab);
|
||||
@@ -1,64 +1,64 @@
|
||||
function valToggleMsg(serverValidationManager) {
|
||||
return {
|
||||
require: "^form",
|
||||
restrict: "A",
|
||||
|
||||
/**
|
||||
Our directive requries a reference to a form controller which gets passed in to this parameter
|
||||
*/
|
||||
link: function (scope, element, attr, formCtrl) {
|
||||
|
||||
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";
|
||||
}
|
||||
if (!formCtrl[attr.valMsgFor]) {
|
||||
throw "valToggleMsg cannot find field " + attr.valMsgFor + " on form " + formCtrl.$name;
|
||||
}
|
||||
|
||||
//assign the form control to our isolated scope so we can watch it's values
|
||||
scope.formCtrl = formCtrl;
|
||||
|
||||
//if there's any remaining errors in the server validation service then we should show them.
|
||||
var showValidation = serverValidationManager.items.length > 0;
|
||||
|
||||
//add a watch to the validator for the value (i.e. myForm.value.$error.required )
|
||||
scope.$watch("formCtrl." + attr.valMsgFor + ".$error." + attr.valToggleMsg, function () {
|
||||
if (formCtrl[attr.valMsgFor].$error[attr.valToggleMsg] && showValidation) {
|
||||
element.show();
|
||||
}
|
||||
else {
|
||||
element.hide();
|
||||
}
|
||||
});
|
||||
|
||||
scope.$on("saving", function(ev, args) {
|
||||
showValidation = true;
|
||||
if (formCtrl[attr.valMsgFor].$error[attr.valToggleMsg]) {
|
||||
element.show();
|
||||
}
|
||||
else {
|
||||
element.hide();
|
||||
}
|
||||
});
|
||||
|
||||
scope.$on("saved", function (ev, args) {
|
||||
showValidation = false;
|
||||
element.hide();
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name umbraco.directives.directive:valToggleMsg
|
||||
* @restrict A
|
||||
* @element input
|
||||
* @requires formController
|
||||
* @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(serverValidationManager) {
|
||||
return {
|
||||
require: "^form",
|
||||
restrict: "A",
|
||||
|
||||
/**
|
||||
Our directive requries a reference to a form controller which gets passed in to this parameter
|
||||
*/
|
||||
link: function (scope, element, attr, formCtrl) {
|
||||
|
||||
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";
|
||||
}
|
||||
if (!formCtrl[attr.valMsgFor]) {
|
||||
throw "valToggleMsg cannot find field " + attr.valMsgFor + " on form " + formCtrl.$name;
|
||||
}
|
||||
|
||||
//assign the form control to our isolated scope so we can watch it's values
|
||||
scope.formCtrl = formCtrl;
|
||||
|
||||
//if there's any remaining errors in the server validation service then we should show them.
|
||||
var showValidation = serverValidationManager.items.length > 0;
|
||||
|
||||
//add a watch to the validator for the value (i.e. myForm.value.$error.required )
|
||||
scope.$watch("formCtrl." + attr.valMsgFor + ".$error." + attr.valToggleMsg, function () {
|
||||
if (formCtrl[attr.valMsgFor].$error[attr.valToggleMsg] && showValidation) {
|
||||
element.show();
|
||||
}
|
||||
else {
|
||||
element.hide();
|
||||
}
|
||||
});
|
||||
|
||||
scope.$on("saving", function(ev, args) {
|
||||
showValidation = true;
|
||||
if (formCtrl[attr.valMsgFor].$error[attr.valToggleMsg]) {
|
||||
element.show();
|
||||
}
|
||||
else {
|
||||
element.hide();
|
||||
}
|
||||
});
|
||||
|
||||
scope.$on("saved", function (ev, args) {
|
||||
showValidation = false;
|
||||
element.hide();
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name umbraco.directives.directive:valToggleMsg
|
||||
* @restrict A
|
||||
* @element input
|
||||
* @requires formController
|
||||
* @description This directive will show/hide an error based on: is the value + the given validator invalid? AND, has the form been submitted ?
|
||||
**/
|
||||
angular.module('umbraco.directives').directive("valToggleMsg", valToggleMsg);
|
||||
@@ -0,0 +1,28 @@
|
||||
<form name="passwordForm" ng-controller="Umbraco.Dashboard.StartupChangePasswordController">
|
||||
<umb-pane>
|
||||
<umb-control-group label="Old password">
|
||||
<input type="text" name="oldpass" ng-model="profile.oldPassword" required/>
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group label="New password">
|
||||
<input type="text" name="pass" ng-model="profile.newPassword" required/>
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group label="Repeat new password">
|
||||
<input type="text" name="passcompare"
|
||||
val-custom="{compare: '$value === profile.newPassword'}"
|
||||
ng-model="profile.repeatNewPassword" required/>
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group hideLabel="1">
|
||||
<button class="btn btn-primary"
|
||||
ng-disabled="!passwordForm.$valid"
|
||||
ng-click="changePassword(profile)">Change</button>
|
||||
</umb-control-group>
|
||||
</umb-pane>
|
||||
|
||||
{{profile | json}} ---
|
||||
{{passwordForm.$error | json}}
|
||||
|
||||
{{passwordForm | json}}
|
||||
</form>
|
||||
@@ -0,0 +1,13 @@
|
||||
<div class="umb-property">
|
||||
<div class="control-group umb-control-group" ng-class="{hidelabel:hideLabel, error: propertyForm.$invalid}" >
|
||||
<div class="umb-el-wrap">
|
||||
<label class="control-label" ng-hide="hideLabel" for="{{alias}}">
|
||||
{{label}}
|
||||
<small>{{description}}</small>
|
||||
</label>
|
||||
|
||||
<div class="controls controls-row" ng-transclude>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
<div class="umb-pane" ng-transclude>
|
||||
|
||||
</div>
|
||||
@@ -1,3 +1,3 @@
|
||||
<div class="umb-panel tabbable" ng-transclude>
|
||||
|
||||
</div>
|
||||
<div class="umb-panel tabbable" ng-transclude>
|
||||
|
||||
</div>
|
||||
@@ -1,3 +0,0 @@
|
||||
<div class="umb-pane">
|
||||
|
||||
</div>
|
||||
Reference in New Issue
Block a user