diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/umbproperty.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/umbproperty.directive.js
index cd84a3b2ca..d84bb8e24d 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/umbproperty.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/umbproperty.directive.js
@@ -13,8 +13,18 @@ angular.module("umbraco.directives")
restrict: 'E',
replace: true,
templateUrl: 'views/directives/umb-property.html',
- link: function (scope, element, attrs, ctrl) {
+ //Define a controller for this directive to expose APIs to other directives
+ controller: function ($scope, $timeout) {
+
+ var self = this;
+
+ //set the API properties/methods
+
+ self.property = $scope.property;
+ self.setPropertyError = function(errorMsg) {
+ $scope.property.propertyErrorMessage = errorMsg;
+ };
}
};
});
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valpropertymsg.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valpropertymsg.directive.js
index ea4b1b82c8..d37f4c5271 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valpropertymsg.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valpropertymsg.directive.js
@@ -9,22 +9,86 @@
* and when an error is detected for this property we'll show the error message.
* In order for this directive to work, the valStatusChanged directive must be placed on the containing form.
**/
-function valPropertyMsg(serverValidationManager) {
+function valPropertyMsg(serverValidationManager) {
+
return {
scope: {
- property: "=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: "
{{errorMsg}}
",
-
+ template: "
{{errorMsg}}
",
+
/**
Our directive requries a reference to a form controller
which gets passed in to this parameter
*/
link: function (scope, element, attrs, formCtrl) {
+ var watcher = null;
+
+ // Gets the error message to display
+ function getErrorMsg() {
+ //this can be null if no property was assigned
+ if (scope.property) {
+ //first try to get the error msg from the server collection
+ var err = serverValidationManager.getPropertyError(scope.property.alias, "");
+ //if there's an error message use it
+ if (err && err.errorMsg) {
+ return err.errorMsg;
+ }
+ else {
+ return scope.property.propertyErrorMessage ? scope.property.propertyErrorMessage : "Property has errors";
+ }
+
+ }
+ return "Property has errors";
+ }
+
+ // 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.
+ function startWatch() {
+ //if there's not already a watch
+ if (!watcher) {
+ watcher = scope.$watch("property.value", function (newValue, oldValue) {
+
+ if (!newValue || angular.equals(newValue, oldValue)) {
+ return;
+ }
+
+ var errCount = 0;
+ for (var e in formCtrl.$error) {
+ if (angular.isArray(formCtrl.$error[e])) {
+ errCount++;
+ }
+ }
+
+ //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.
+
+ if ((errCount === 1 && angular.isArray(formCtrl.$error.valPropertyMsg)) || (formCtrl.$invalid && angular.isArray(formCtrl.$error.valServer))) {
+ scope.errorMsg = "";
+ formCtrl.$setValidity('valPropertyMsg', true);
+ stopWatch();
+ }
+ }, true);
+ }
+ }
+
+ //clear the watch when the property validator is valid again
+ function stopWatch() {
+ if (watcher) {
+ watcher();
+ watcher = null;
+ }
+ }
+
//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;
@@ -33,7 +97,7 @@ function valPropertyMsg(serverValidationManager) {
scope.errorMsg = "";
//listen for form error changes
- scope.$on("valStatusChanged", function(evt, args) {
+ scope.$on("valStatusChanged", function (evt, args) {
if (args.form.$invalid) {
//first we need to check if the valPropertyMsg validity is invalid
@@ -47,12 +111,7 @@ function valPropertyMsg(serverValidationManager) {
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";
+ scope.errorMsg = getErrorMsg();
}
}
else {
@@ -70,15 +129,11 @@ function valPropertyMsg(serverValidationManager) {
scope.$on("formSubmitting", 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";
+ scope.errorMsg = getErrorMsg();
}
else if (!hasError) {
scope.errorMsg = "";
+ stopWatch();
}
});
@@ -86,37 +141,10 @@ function valPropertyMsg(serverValidationManager) {
scope.$on("formSubmitted", function (ev, args) {
showValidation = false;
scope.errorMsg = "";
- formCtrl.$setValidity('valPropertyMsg', true);
+ formCtrl.$setValidity('valPropertyMsg', true);
+ stopWatch();
});
- //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.
-
- if (!newValue) {
- return;
- }
-
- var errCount = 0;
- for (var e in formCtrl.$error) {
- if (angular.isArray(formCtrl.$error[e])) {
- errCount++;
- }
- }
-
- if ((errCount === 1 && angular.isArray(formCtrl.$error.valPropertyMsg)) || (formCtrl.$invalid && angular.isArray(formCtrl.$error.valServer))) {
- 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
@@ -124,27 +152,30 @@ function valPropertyMsg(serverValidationManager) {
// 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) {
+ 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);
+ startWatch();
}
else {
scope.errorMsg = "";
//flag that the current validator is valid
formCtrl.$setValidity('valPropertyMsg', true);
+ stopWatch();
}
});
//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() {
+ element.bind('$destroy', function () {
+ stopWatch();
serverValidationManager.unsubscribe(scope.property.alias, "");
});
}
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valpropertyvalidator.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valpropertyvalidator.directive.js
new file mode 100644
index 0000000000..1d04fd9b34
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valpropertyvalidator.directive.js
@@ -0,0 +1,67 @@
+/**
+* @ngdoc directive
+* @name umbraco.directives.directive:valPropertyValidator
+* @restrict A
+* @description Performs any custom property value validation checks on the client side. This allows property editors to be highly flexible when it comes to validation
+ on the client side. Typically if a property editor stores a primitive value (i.e. string) then the client side validation can easily be taken care of
+ with standard angular directives such as ng-required. However since some property editors store complex data such as JSON, a given property editor
+ might require custom validation. This directive can be used to validate an Umbraco property in any way that a developer would like by specifying a
+ callback method to perform the validation. The result of this method must return an object in the format of
+ {isValid: true, errorKey: 'required', errorMsg: 'Something went wrong' }
+ The error message returned will also be displayed for the property level validation message.
+ This directive should only be used when dealing with complex models, if custom validation needs to be performed with primitive values, use the simpler
+ angular validation directives instead since this will watch the entire model.
+**/
+
+function valPropertyValidator(serverValidationManager) {
+ return {
+ scope: {
+ valPropertyValidator: "="
+ },
+
+ // The element must have ng-model attribute and be inside an umbProperty directive
+ require: ['ngModel', '^umbProperty'],
+
+ restrict: "A",
+
+ link: function (scope, element, attrs, ctrls) {
+
+ var modelCtrl = ctrls[0];
+ var propCtrl = ctrls[1];
+
+ // Check whether the scope has a valPropertyValidator method
+ if (!scope.valPropertyValidator || !angular.isFunction(scope.valPropertyValidator)) {
+ throw new Error('val-property-validator directive must specify a function to call');
+ }
+
+ var initResult = scope.valPropertyValidator();
+
+ // Validation method
+ var validate = function (viewValue) {
+ // Calls the validition method
+ var result = scope.valPropertyValidator();
+ if (!result.errorKey || result.isValid === undefined || !result.errorMsg) {
+ throw "The result object from valPropertyValidator does not contain required properties: isValid, errorKey, errorMsg";
+ }
+ if (result.isValid === true) {
+ // Tell the controller that the value is valid
+ modelCtrl.$setValidity(result.errorKey, true);
+ propCtrl.setPropertyError(null);
+ }
+ else {
+ // Tell the controller that the value is invalid
+ modelCtrl.$setValidity(result.errorKey, false);
+ propCtrl.setPropertyError(result.errorMsg);
+ }
+ };
+
+ // Formatters are invoked when the model is modified in the code.
+ modelCtrl.$formatters.push(validate);
+
+ // Parsers are called as soon as the value in the form input is modified
+ modelCtrl.$parsers.push(validate);
+
+ }
+ };
+}
+angular.module('umbraco.directives.validation').directive("valPropertyValidator", valPropertyValidator);
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valserver.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valserver.directive.js
index fbc91dcb11..9d944aabcc 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valserver.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valserver.directive.js
@@ -7,14 +7,49 @@
**/
function valServer(serverValidationManager) {
return {
- require: 'ngModel',
+ require: ['ngModel', '^umbProperty'],
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";
+ link: function (scope, element, attr, ctrls) {
+
+ var modelCtrl = ctrls[0];
+ var umbPropCtrl = ctrls[1];
+
+ var watcher = null;
+
+ //Need to watch the value model for it to change, previously we had subscribed to
+ //modelCtrl.$viewChangeListeners but this is not good enough if you have an editor that
+ // doesn't specifically have a 2 way ng binding. 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.
+ function startWatch() {
+ //if there's not already a watch
+ if (!watcher) {
+ watcher = scope.$watch(function () {
+ return modelCtrl.$modelValue;
+ }, function (newValue, oldValue) {
+
+ if (!newValue || angular.equals(newValue, oldValue)) {
+ return;
+ }
+
+ if (modelCtrl.$invalid) {
+ modelCtrl.$setValidity('valServer', true);
+ stopWatch();
+ }
+ }, true);
+ }
}
- var currentProperty = scope.model;
+
+ function stopWatch() {
+ if (watcher) {
+ watcher();
+ watcher = null;
+ }
+ }
+
+ var currentProperty = umbPropCtrl.property;
//default to 'value' if nothing is set
var fieldName = "value";
@@ -25,33 +60,20 @@ function valServer(serverValidationManager) {
fieldName = attr.valServer;
}
}
-
- //Need to watch the value model for it to change, previously we had subscribed to
- //ctrl.$viewChangeListeners but this is not good enough if you have an editor that
- // doesn't specifically have a 2 way ng binding. 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(function() {
- return ctrl.$modelValue;
- }, function (newValue) {
- 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);
+ modelCtrl.$setValidity('valServer', false);
//assign an error msg property to the current validator
- ctrl.errorMsg = propertyErrors[0].errorMsg;
+ modelCtrl.errorMsg = propertyErrors[0].errorMsg;
+ startWatch();
}
else {
- ctrl.$setValidity('valServer', true);
+ modelCtrl.$setValidity('valServer', true);
//reset the error message
- ctrl.errorMsg = "";
+ modelCtrl.errorMsg = "";
+ stopWatch();
}
});
@@ -59,6 +81,7 @@ function valServer(serverValidationManager) {
// 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 () {
+ stopWatch();
serverValidationManager.unsubscribe(currentProperty.alias, fieldName);
});
}
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.controller.js
index 89bc626d6a..f14492e88a 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.controller.js
@@ -2,11 +2,23 @@ function ColorPickerController($scope) {
$scope.toggleItem = function (color) {
if ($scope.model.value == color) {
$scope.model.value = "";
+ //this is required to re-validate
+ $scope.propertyForm.modelValue.$setViewValue($scope.model.value);
}
else {
$scope.model.value = color;
+ //this is required to re-validate
+ $scope.propertyForm.modelValue.$setViewValue($scope.model.value);
}
};
+ // Method required by the valPropertyValidator directive (returns true if the property editor has at least one color selected)
+ $scope.validateMandatory = function () {
+ return {
+ isValid: !$scope.model.validation.mandatory || ($scope.model.value != null && $scope.model.value != ""),
+ errorMsg: "Value cannot be empty",
+ errorKey: "required"
+ };
+ }
$scope.isConfigured = $scope.model.config && $scope.model.config.items && _.keys($scope.model.config.items).length > 0;
}
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.html
index d2bf2cf87c..a493fffdd8 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.html
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.html
@@ -12,4 +12,6 @@
+
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.controller.js
index 9106e2b334..37dea64c21 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.controller.js
@@ -21,6 +21,11 @@ function fileUploadController($scope, $element, $compile, imageHelper, fileManag
fileManager.setFiles($scope.model.alias, []);
//clear the current files
$scope.files = [];
+ if ($scope.propertyForm.fileCount) {
+ //this is required to re-validate
+ $scope.propertyForm.fileCount.$setViewValue($scope.files.length);
+ }
+
}
/** this method is used to initialize the data and to re-initialize it if the server value is changed */
@@ -71,6 +76,15 @@ function fileUploadController($scope, $element, $compile, imageHelper, fileManag
initialize();
+ // Method required by the valPropertyValidator directive (returns true if the property editor has at least one file selected)
+ $scope.validateMandatory = function () {
+ return {
+ isValid: !$scope.model.validation.mandatory || ((($scope.persistedFiles != null && $scope.persistedFiles.length > 0) || ($scope.files != null && $scope.files.length > 0)) && !$scope.clearFiles),
+ errorMsg: "Value cannot be empty",
+ errorKey: "required"
+ };
+ }
+
//listen for clear files changes to set our model to be sent up to the server
$scope.$watch("clearFiles", function (isCleared) {
if (isCleared == true) {
@@ -80,6 +94,8 @@ function fileUploadController($scope, $element, $compile, imageHelper, fileManag
else {
//reset to original value
$scope.model.value = $scope.originalValue;
+ //this is required to re-validate
+ $scope.propertyForm.fileCount.$setViewValue($scope.files.length);
}
});
@@ -96,6 +112,10 @@ function fileUploadController($scope, $element, $compile, imageHelper, fileManag
$scope.files.push({ alias: $scope.model.alias, file: args.files[i] });
newVal += args.files[i].name + ",";
}
+
+ //this is required to re-validate
+ $scope.propertyForm.fileCount.$setViewValue($scope.files.length);
+
//set clear files to false, this will reset the model too
$scope.clearFiles = false;
//set the model value to be the concatenation of files selected. Please see the notes
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.html
index afcba5a493..e200b2726c 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.html
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.html
@@ -25,4 +25,7 @@
{{file.file.name}}
-
+
+
+
+
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.controller.js
index 4577430195..9c0d016189 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.controller.js
@@ -12,31 +12,38 @@ angular.module("umbraco")
$scope.isLoading = false;
//load current value
- $scope.currentTags = [];
+
if ($scope.model.value) {
- if ($scope.model.config.storageType && $scope.model.config.storageType === "Json") {
- //it's a json array already
- $scope.currentTags = $scope.model.value;
- }
- else {
+ if (!$scope.model.config.storageType || $scope.model.config.storageType !== "Json") {
//it is csv
if (!$scope.model.value) {
- $scope.currentTags = [];
+ $scope.model.value = [];
}
else {
- $scope.currentTags = $scope.model.value.split(",");
+ $scope.model.value = $scope.model.value.split(",");
}
}
}
+ else {
+ $scope.model.value = [];
+ }
+
+ // Method required by the valPropertyValidator directive (returns true if the property editor has at least one tag selected)
+ $scope.validateMandatory = function () {
+ return {
+ isValid: !$scope.model.validation.mandatory || ($scope.model.value != null && $scope.model.value.length > 0),
+ errorMsg: "Value cannot be empty",
+ errorKey: "required"
+ };
+ }
//Helper method to add a tag on enter or on typeahead select
function addTag(tagToAdd) {
- if (tagToAdd.length > 0) {
- if ($scope.currentTags.indexOf(tagToAdd) < 0) {
- $scope.currentTags.push(tagToAdd);
- //update the model value, this is required if there's a server validation error, it can
- // only then be cleared if the model changes
- $scope.model.value = $scope.currentTags;
+ if (tagToAdd != null && tagToAdd.length > 0) {
+ if ($scope.model.value.indexOf(tagToAdd) < 0) {
+ $scope.model.value.push(tagToAdd);
+ //this is required to re-validate
+ $scope.propertyForm.tagCount.$setViewValue($scope.model.value.length);
}
}
}
@@ -47,7 +54,6 @@ angular.module("umbraco")
if ($element.find('.tags-' + $scope.model.alias).parent().find(".tt-dropdown-menu .tt-cursor").length === 0) {
//this is required, otherwise the html form will attempt to submit.
e.preventDefault();
-
$scope.addTag();
}
}
@@ -66,36 +72,26 @@ angular.module("umbraco")
$scope.removeTag = function (tag) {
- var i = $scope.currentTags.indexOf(tag);
+ var i = $scope.model.value.indexOf(tag);
if (i >= 0) {
- $scope.currentTags.splice(i, 1);
- //update the model value, this is required if there's a server validation error, it can
- // only then be cleared if the model changes
- $scope.model.value = $scope.currentTags;
+ $scope.model.value.splice(i, 1);
+ //this is required to re-validate
+ $scope.propertyForm.tagCount.$setViewValue($scope.model.value.length);
}
};
- //sync model on submit, always push up a json array
- $scope.$on("formSubmitting", function (ev, args) {
- $scope.model.value = $scope.currentTags;
- });
-
//vice versa
$scope.model.onValueChanged = function (newVal, oldVal) {
//update the display val again if it has changed from the server
$scope.model.value = newVal;
- if ($scope.model.config.storageType && $scope.model.config.storageType === "Json") {
- //it's a json array already
- $scope.currentTags = $scope.model.value;
- }
- else {
+ if (!$scope.model.config.storageType || $scope.model.config.storageType !== "Json") {
//it is csv
if (!$scope.model.value) {
- $scope.currentTags = [];
+ $scope.model.value = [];
}
else {
- $scope.currentTags = $scope.model.value.split(",");
+ $scope.model.value = $scope.model.value.split(",");
}
}
};
@@ -110,14 +106,14 @@ angular.module("umbraco")
});
// remove current tags from the list
return $.grep(tagList, function (tag) {
- return ($.inArray(tag.value, $scope.currentTags) === -1);
+ return ($.inArray(tag.value, $scope.model.value) === -1);
});
}
// helper method to remove current tags
function removeCurrentTagsFromSuggestions(suggestions) {
return $.grep(suggestions, function (suggestion) {
- return ($.inArray(suggestion.value, $scope.currentTags) === -1);
+ return ($.inArray(suggestion.value, $scope.model.value) === -1);
});
}
@@ -158,7 +154,6 @@ angular.module("umbraco")
// name = the data set name, we'll make this the tag group name
name: $scope.model.config.group,
displayKey: "value",
- //source: tagsHound.ttAdapter(),
source: function (query, cb) {
tagsHound.get(query, function (suggestions) {
cb(removeCurrentTagsFromSuggestions(suggestions));
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.html
index 1a0452e242..b1049a2309 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.html
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.html
@@ -1,21 +1,26 @@