Fix issue with pressing enter on color picker labels
Prevent form submission when pressing enter in color picker labels, instead execute "add" code. Improve validation highlights.
This commit is contained in:
committed by
Michael Latouche
parent
0c82b9b700
commit
f8b66aaf50
@@ -1,38 +1,46 @@
|
||||
<div class="umb-property-editor umb-prevalues-multivalues umb-colors" ng-controller="Umbraco.PrevalueEditors.MultiColorPickerController as vm">
|
||||
<div class="control-group umb-prevalues-multivalues__add color-picker-preval">
|
||||
<div class="umb-prevalues-multivalues__left">
|
||||
<div class="control-group umb-prevalues-multivalues__add color-picker-preval">
|
||||
<div class="umb-prevalues-multivalues__left">
|
||||
|
||||
<umb-color-picker
|
||||
ng-model="newColor"
|
||||
options="options"
|
||||
on-hide="vm.hide(color)"
|
||||
on-show="vm.show(color)"
|
||||
on-change="vm.change(color)">
|
||||
</umb-color-picker>
|
||||
<umb-color-picker ng-model="newColor"
|
||||
options="options"
|
||||
on-hide="vm.hide(color)"
|
||||
on-show="vm.show(color)"
|
||||
on-change="vm.change(color)">
|
||||
</umb-color-picker>
|
||||
|
||||
<label val-highlight="{{hasError}}">#{{newColor}}</label>
|
||||
<input type="text" name="newLabel" ng-model="newLabel" focus-when="{{focusOnNew}}" class="umb-property-editor color-label" localize="placeholder" placeholder="@general_label" ng-show="vm.labelEnabled" />
|
||||
</div>
|
||||
<div class="umb-prevalues-multivalues__right">
|
||||
<button type="button" class="btn btn-info add" ng-if="vm.editItem == null" ng-click="vm.add($event)"><localize key="general_add">Add</localize></button>
|
||||
<button type="button" class="btn btn-info add" ng-if="vm.editItem != null" ng-click="vm.add($event)"><localize key="general_update">Update</localize></button>
|
||||
<button type="button" class="btn btn-link" ng-if="vm.editItem != null" ng-click="vm.cancel($event)"><localize key="general_cancel">Cancel</localize></button>
|
||||
</div>
|
||||
<label val-highlight="{{colorHasError}}">#{{newColor}}</label>
|
||||
<input type="text" name="newLabel"
|
||||
ng-model="newLabel"
|
||||
focus-when="{{focusOnNew}}"
|
||||
class="umb-property-editor color-label"
|
||||
localize="placeholder"
|
||||
placeholder="@general_label"
|
||||
ng-show="vm.labelEnabled"
|
||||
ng-keydown="vm.addOnEnter($event)"
|
||||
ng-keyup="vm.validateLabel()"
|
||||
val-highlight="{{labelHasError}}" />
|
||||
</div>
|
||||
<div ui-sortable="sortableOptions" ng-model="model.value">
|
||||
<div class="control-group umb-prevalues-multivalues__listitem color-picker-preval" ng-repeat="item in model.value track by $id(item)">
|
||||
<umb-icon icon="icon-navigation" class="icon handle"></umb-icon>
|
||||
<div class="umb-prevalues-multivalues__left">
|
||||
<div class="thumbnail span1" hex-bg-color="{{item.value}}" hex-bg-orig="transparent"></div>
|
||||
<div class="color-picker-prediv">
|
||||
<pre>#{{item.value}}</pre>
|
||||
<span ng-bind="item.label" ng-if="vm.labelEnabled"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="umb-prevalues-multivalues__right">
|
||||
<button type="button" class="umb-node-preview__action umb-node-preview__action--red" ng-click="vm.edit(item, $event)"><localize key="general_edit">Edit</localize></button>
|
||||
<button type="button" class="umb-node-preview__action umb-node-preview__action--red" ng-click="vm.remove(item, $event)"><localize key="general_remove">Remove</localize></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="umb-prevalues-multivalues__right">
|
||||
<button type="button" class="btn btn-info add" ng-if="vm.editItem == null" ng-click="vm.add($event)"><localize key="general_add">Add</localize></button>
|
||||
<button type="button" class="btn btn-info add" ng-if="vm.editItem != null" ng-click="vm.add($event)"><localize key="general_update">Update</localize></button>
|
||||
<button type="button" class="btn btn-link" ng-if="vm.editItem != null" ng-click="vm.cancel($event)"><localize key="general_cancel">Cancel</localize></button>
|
||||
</div>
|
||||
</div>
|
||||
<div ui-sortable="sortableOptions" ng-model="model.value">
|
||||
<div class="control-group umb-prevalues-multivalues__listitem color-picker-preval" ng-repeat="item in model.value track by $id(item)">
|
||||
<umb-icon icon="icon-navigation" class="icon handle"></umb-icon>
|
||||
<div class="umb-prevalues-multivalues__left">
|
||||
<div class="thumbnail span1" hex-bg-color="{{item.value}}" hex-bg-orig="transparent"></div>
|
||||
<div class="color-picker-prediv">
|
||||
<pre>#{{item.value}}</pre>
|
||||
<span ng-bind="item.label" ng-if="vm.labelEnabled"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="umb-prevalues-multivalues__right">
|
||||
<button type="button" class="umb-node-preview__action umb-node-preview__action--red" ng-click="vm.edit(item, $event)"><localize key="general_edit">Edit</localize></button>
|
||||
<button type="button" class="umb-node-preview__action umb-node-preview__action--red" ng-click="vm.remove(item, $event)"><localize key="general_remove">Remove</localize></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,191 +1,228 @@
|
||||
angular.module("umbraco").controller("Umbraco.PrevalueEditors.MultiColorPickerController",
|
||||
function ($scope, angularHelper, $element, eventsService) {
|
||||
function ($scope, angularHelper, $element, eventsService) {
|
||||
|
||||
const vm = this;
|
||||
const vm = this;
|
||||
|
||||
vm.add = add;
|
||||
vm.remove = remove;
|
||||
vm.edit = edit;
|
||||
vm.cancel = cancel;
|
||||
vm.add = add;
|
||||
vm.addOnEnter = addOnEnter;
|
||||
vm.validateLabel = validateLabel;
|
||||
vm.remove = remove;
|
||||
vm.edit = edit;
|
||||
vm.cancel = cancel;
|
||||
|
||||
vm.show = show;
|
||||
vm.hide = hide;
|
||||
vm.change = change;
|
||||
vm.show = show;
|
||||
vm.hide = hide;
|
||||
vm.change = change;
|
||||
|
||||
vm.labelEnabled = false;
|
||||
vm.editItem = null;
|
||||
vm.labelEnabled = false;
|
||||
vm.editItem = null;
|
||||
|
||||
// NOTE: We need to make each color an object, not just a string because you cannot 2-way bind to a primitive.
|
||||
const defaultColor = "000000";
|
||||
const defaultLabel = null;
|
||||
// NOTE: We need to make each color an object, not just a string because you cannot 2-way bind to a primitive.
|
||||
const defaultColor = "000000";
|
||||
const defaultLabel = null;
|
||||
|
||||
$scope.newColor = defaultColor;
|
||||
$scope.newLabel = defaultLabel;
|
||||
$scope.hasError = false;
|
||||
$scope.focusOnNew = false;
|
||||
$scope.newColor = defaultColor;
|
||||
$scope.newLabel = defaultLabel;
|
||||
$scope.colorHasError = false;
|
||||
$scope.labelHasError = false;
|
||||
$scope.focusOnNew = false;
|
||||
|
||||
$scope.options = {
|
||||
type: "color",
|
||||
color: defaultColor,
|
||||
allowEmpty: false,
|
||||
showAlpha: false
|
||||
};
|
||||
$scope.options = {
|
||||
type: "color",
|
||||
color: defaultColor,
|
||||
allowEmpty: false,
|
||||
showAlpha: false
|
||||
};
|
||||
|
||||
function hide() {
|
||||
// show the add button
|
||||
$element.find(".btn.add").show();
|
||||
function hide() {
|
||||
// show the add button
|
||||
$element.find(".btn.add").show();
|
||||
}
|
||||
|
||||
function show() {
|
||||
// hide the add button
|
||||
$element.find(".btn.add").hide();
|
||||
}
|
||||
|
||||
function change(color) {
|
||||
angularHelper.safeApply($scope, function () {
|
||||
if (color) {
|
||||
$scope.newColor = color.toHexString().trimStart("#");
|
||||
$scope.colorHasError = !colorIsValid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function show() {
|
||||
// hide the add button
|
||||
$element.find(".btn.add").hide();
|
||||
}
|
||||
|
||||
function change(color) {
|
||||
angularHelper.safeApply($scope, function () {
|
||||
if (color) {
|
||||
$scope.newColor = color.toHexString().trimStart("#");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var evts = [];
|
||||
evts.push(eventsService.on("toggleValue", function (e, args) {
|
||||
if (args.inputId === "useLabel") {
|
||||
vm.labelEnabled = args.value;
|
||||
}
|
||||
}));
|
||||
|
||||
$scope.$on('$destroy', function () {
|
||||
for (var e in evts) {
|
||||
eventsService.unsubscribe(evts[e]);
|
||||
}
|
||||
});
|
||||
|
||||
if (!Utilities.isArray($scope.model.value)) {
|
||||
//make an array from the dictionary
|
||||
var items = [];
|
||||
for (var i in $scope.model.value) {
|
||||
var oldValue = $scope.model.value[i];
|
||||
if (Object.prototype.hasOwnProperty.call(oldValue, "value")) {
|
||||
items.push({
|
||||
value: oldValue.value,
|
||||
label: oldValue.label,
|
||||
sortOrder: oldValue.sortOrder,
|
||||
id: i
|
||||
});
|
||||
} else {
|
||||
items.push({
|
||||
value: oldValue,
|
||||
label: oldValue,
|
||||
sortOrder: oldValue.sortOrder,
|
||||
id: i
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//ensure the items are sorted by the provided sort order
|
||||
items.sort(function (a, b) { return (a.sortOrder > b.sortOrder) ? 1 : ((b.sortOrder > a.sortOrder) ? -1 : 0); });
|
||||
|
||||
//now make the editor model the array
|
||||
$scope.model.value = items;
|
||||
}
|
||||
|
||||
// ensure labels
|
||||
for (var ii = 0; ii < $scope.model.value.length; ii++) {
|
||||
var item = $scope.model.value[ii];
|
||||
item.label = Object.prototype.hasOwnProperty.call(item, "label") ? item.label : item.value;
|
||||
}
|
||||
|
||||
function validLabel(label) {
|
||||
return label !== null && typeof label !== "undefined" && label !== "" && label.length && label.length > 0;
|
||||
}
|
||||
|
||||
function remove(item, evt) {
|
||||
|
||||
evt.preventDefault();
|
||||
|
||||
$scope.model.value = _.reject($scope.model.value, function (x) {
|
||||
return x.value === item.value && x.label === item.label;
|
||||
});
|
||||
|
||||
setDirty();
|
||||
}
|
||||
|
||||
function add(evt) {
|
||||
evt.preventDefault();
|
||||
|
||||
if ($scope.newColor) {
|
||||
var newLabel = validLabel($scope.newLabel) ? $scope.newLabel : $scope.newColor;
|
||||
var exists = _.find($scope.model.value, function (item) {
|
||||
return item != vm.editItem && (item.value.toUpperCase() === $scope.newColor.toUpperCase() || item.label.toUpperCase() === newLabel.toUpperCase());
|
||||
});
|
||||
if (!exists) {
|
||||
if (vm.editItem == null) {
|
||||
$scope.model.value.push({
|
||||
value: $scope.newColor,
|
||||
label: newLabel
|
||||
});
|
||||
} else {
|
||||
|
||||
if(vm.editItem.value === vm.editItem.label && vm.editItem.value === newLabel) {
|
||||
vm.editItem.label = $scope.newColor;
|
||||
|
||||
}
|
||||
else {
|
||||
vm.editItem.label = newLabel;
|
||||
}
|
||||
|
||||
vm.editItem.value = $scope.newColor;
|
||||
|
||||
vm.editItem = null;
|
||||
}
|
||||
|
||||
$scope.newLabel = "";
|
||||
$scope.hasError = false;
|
||||
$scope.focusOnNew = true;
|
||||
setDirty();
|
||||
return;
|
||||
}
|
||||
|
||||
// there was an error, do the highlight (will be set back by the directive)
|
||||
$scope.hasError = true;
|
||||
}
|
||||
}
|
||||
|
||||
function edit(item, evt) {
|
||||
evt.preventDefault();
|
||||
|
||||
vm.editItem = item;
|
||||
|
||||
$scope.newColor = item.value;
|
||||
$scope.newLabel = item.label;
|
||||
}
|
||||
|
||||
function cancel(evt) {
|
||||
evt.preventDefault();
|
||||
|
||||
vm.editItem = null;
|
||||
$scope.newColor = defaultColor;
|
||||
$scope.newLabel = defaultLabel;
|
||||
}
|
||||
|
||||
function setDirty() {
|
||||
if (vm.modelValueForm) {
|
||||
vm.modelValueForm.selectedColor.$setDirty();
|
||||
}
|
||||
}
|
||||
|
||||
$scope.sortableOptions = {
|
||||
axis: 'y',
|
||||
containment: 'parent',
|
||||
cursor: 'move',
|
||||
//handle: ".handle, .thumbnail",
|
||||
items: '> div.control-group',
|
||||
tolerance: 'pointer',
|
||||
update: function () {
|
||||
setDirty();
|
||||
}
|
||||
};
|
||||
var evts = [];
|
||||
evts.push(eventsService.on("toggleValue", function (e, args) {
|
||||
if (args.inputId === "useLabel") {
|
||||
vm.labelEnabled = args.value;
|
||||
}
|
||||
}));
|
||||
|
||||
$scope.$on('$destroy', function () {
|
||||
for (var e in evts) {
|
||||
eventsService.unsubscribe(evts[e]);
|
||||
}
|
||||
});
|
||||
|
||||
if (!Utilities.isArray($scope.model.value)) {
|
||||
//make an array from the dictionary
|
||||
var items = [];
|
||||
for (var i in $scope.model.value) {
|
||||
var oldValue = $scope.model.value[i];
|
||||
if (Object.prototype.hasOwnProperty.call(oldValue, "value")) {
|
||||
items.push({
|
||||
value: oldValue.value,
|
||||
label: oldValue.label,
|
||||
sortOrder: oldValue.sortOrder,
|
||||
id: i
|
||||
});
|
||||
} else {
|
||||
items.push({
|
||||
value: oldValue,
|
||||
label: oldValue,
|
||||
sortOrder: oldValue.sortOrder,
|
||||
id: i
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//ensure the items are sorted by the provided sort order
|
||||
items.sort(function (a, b) { return (a.sortOrder > b.sortOrder) ? 1 : ((b.sortOrder > a.sortOrder) ? -1 : 0); });
|
||||
|
||||
//now make the editor model the array
|
||||
$scope.model.value = items;
|
||||
}
|
||||
|
||||
// ensure labels
|
||||
for (var ii = 0; ii < $scope.model.value.length; ii++) {
|
||||
var item = $scope.model.value[ii];
|
||||
item.label = Object.prototype.hasOwnProperty.call(item, "label") ? item.label : item.value;
|
||||
}
|
||||
|
||||
function remove(item, evt) {
|
||||
|
||||
evt.preventDefault();
|
||||
|
||||
$scope.model.value = _.reject($scope.model.value, function (x) {
|
||||
return x.value === item.value && x.label === item.label;
|
||||
});
|
||||
|
||||
setDirty();
|
||||
}
|
||||
|
||||
function colorIsValid() {
|
||||
var colorExists = _.find($scope.model.value, function (item) {
|
||||
return item != vm.editItem && item.value.toUpperCase() === $scope.newColor.toUpperCase();
|
||||
});
|
||||
|
||||
return colorExists ? false : true;
|
||||
}
|
||||
|
||||
function getLabel() {
|
||||
var validLabel = $scope.newLabel !== null && typeof $scope.newLabel !== "undefined" && $scope.newLabel !== "" && $scope.newLabel.length && $scope.newLabel.length > 0;
|
||||
return validLabel ? $scope.newLabel : $scope.newColor;
|
||||
}
|
||||
|
||||
function labelIsValid() {
|
||||
var label = getLabel();
|
||||
label = label.toUpperCase();
|
||||
|
||||
var labelExists = _.find($scope.model.value, function (item) {
|
||||
return item != vm.editItem && item.label.toUpperCase() === label;
|
||||
});
|
||||
|
||||
return labelExists ? false : true;
|
||||
}
|
||||
|
||||
function validateLabel() {
|
||||
$scope.labelHasError = !labelIsValid();
|
||||
}
|
||||
|
||||
function addOnEnter(evt) {
|
||||
if (evt.keyCode === 13) {
|
||||
add(evt);
|
||||
}
|
||||
}
|
||||
|
||||
function add(evt) {
|
||||
evt.preventDefault();
|
||||
|
||||
if ($scope.newColor) {
|
||||
|
||||
$scope.colorHasError = !colorIsValid();
|
||||
$scope.labelHasError = !labelIsValid();
|
||||
|
||||
if ($scope.labelHasError || $scope.colorHasError) {
|
||||
return;
|
||||
}
|
||||
|
||||
var newLabel = getLabel();
|
||||
|
||||
if (vm.editItem == null) {
|
||||
$scope.model.value.push({
|
||||
value: $scope.newColor,
|
||||
label: newLabel
|
||||
});
|
||||
} else {
|
||||
|
||||
if (vm.editItem.value === vm.editItem.label && vm.editItem.value === newLabel) {
|
||||
vm.editItem.label = $scope.newColor;
|
||||
|
||||
}
|
||||
else {
|
||||
vm.editItem.label = newLabel;
|
||||
}
|
||||
|
||||
vm.editItem.value = $scope.newColor;
|
||||
|
||||
vm.editItem = null;
|
||||
}
|
||||
|
||||
$scope.newLabel = "";
|
||||
$scope.colorHasError = false;
|
||||
$scope.labelHasError = false;
|
||||
$scope.focusOnNew = true;
|
||||
setDirty();
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function edit(item, evt) {
|
||||
evt.preventDefault();
|
||||
|
||||
vm.editItem = item;
|
||||
|
||||
$scope.newColor = item.value;
|
||||
$scope.newLabel = item.label;
|
||||
}
|
||||
|
||||
function cancel(evt) {
|
||||
evt.preventDefault();
|
||||
|
||||
vm.editItem = null;
|
||||
$scope.newColor = defaultColor;
|
||||
$scope.newLabel = defaultLabel;
|
||||
}
|
||||
|
||||
function setDirty() {
|
||||
if (vm.modelValueForm) {
|
||||
vm.modelValueForm.selectedColor.$setDirty();
|
||||
}
|
||||
}
|
||||
|
||||
$scope.sortableOptions = {
|
||||
axis: 'y',
|
||||
containment: 'parent',
|
||||
cursor: 'move',
|
||||
//handle: ".handle, .thumbnail",
|
||||
items: '> div.control-group',
|
||||
tolerance: 'pointer',
|
||||
update: function () {
|
||||
setDirty();
|
||||
}
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user