Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added labels to colors in the color picker. #639

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 36 additions & 2 deletions src/Umbraco.Core/PropertyEditors/PreValueEditor.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Newtonsoft.Json;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;

Expand Down Expand Up @@ -177,7 +177,7 @@ public virtual IDictionary<string, object> ConvertDbToEditor(IDictionary<string,
return result;
}

private void ConvertItemsToJsonIfDetected(IDictionary<string, object> result)
protected void ConvertItemsToJsonIfDetected(IDictionary<string, object> result)
{
//now we're going to try to see if any of the values are JSON, if they are we'll convert them to real JSON objects
// so they can be consumed as real json in angular!
Expand All @@ -201,6 +201,40 @@ private void ConvertItemsToJsonIfDetected(IDictionary<string, object> result)
}
}
}
else if (result[keys[i]] is Dictionary<int, string>)
{
var nestedDic = result[keys[i]] as Dictionary<int, string>;
var nestedKeys = nestedDic.Keys.ToArray();
var newValues = new Dictionary<int, object>();
var allJson = true;
for (var j = 0; j < nestedKeys.Length; j++)
{
var asString = nestedDic[nestedKeys[j]];
if (asString.DetectIsJson())
{
try
{
var json = JsonConvert.DeserializeObject(asString);
newValues[nestedKeys[j]] = json;
}
catch
{
//swallow this exception, we thought it was json but it really isn't so continue returning a string
allJson = false;
break;
}
}
else
{
allJson = false;
break;
}
}
if (allJson && nestedKeys.Length > 0)
{
result[keys[i]] = newValues;
}
}
}
}

Expand Down
64 changes: 42 additions & 22 deletions src/Umbraco.Web.UI.Client/src/less/property-editors.less
Original file line number Diff line number Diff line change
Expand Up @@ -82,32 +82,52 @@ ul.color-picker li {
margin: 3px;
border: 2px solid transparent;
width: 60px;
}
ul.color-picker li.active {
border: 2px dashed #d9d9d9;
}
ul.color-picker li a {
height: 50px;
display:block;
cursor:pointer;
}

.control-group.color-picker-preval .thumbnail {
width:30px;
border:none;
overflow: hidden;
position: relative;
&.active {
border: 2px dashed #d9d9d9;
}
&:hover {
overflow: visible;
z-index: 1;
.color-label {
background-color: @white;
}
}
a {
height: 50px;
display:block;
cursor:pointer;
}
}

/* pre-value editor */

.control-group.color-picker-preval pre {
display: inline;
margin-right: 20px;
margin-left: 10px;
}

.control-group.color-picker-preval label {
border:solid white 1px;
padding:6px;
.control-group.color-picker-preval {
.thumbnail {
width:30px;
border:none;
}
pre {
display: inline;
margin-left: 10px;
&.color-label {
margin-right: 20px;
}
}
label {
border:solid white 1px;
padding:6px;
}
input[type=checkbox] + label {
padding: 0;
border: none;
}
input.color-label {
min-width: 10px;
max-width: 100px;
margin-right: 20px;
}
}


Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,165 @@
function ColorPickerController($scope) {

$scope.isConfigured = $scope.model.config && $scope.model.config.items && _.keys($scope.model.config.items).length > 0;
if ($scope.isConfigured) {
$scope.model.useLabel = isTrue($scope.model.config.useLabel);
initActiveColor();
}

$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);

// Get model color (stored either as a string or as a JSON object).
var modelColor;
if($scope.model.value.hasOwnProperty("value")) {
modelColor = $scope.model.value.value;
} else {
modelColor = $scope.model.value;
}
else {
$scope.model.value = color;
//this is required to re-validate
$scope.propertyForm.modelValue.$setViewValue($scope.model.value);

// Either select or deselect color.
var newModelColor;
if (modelColor === color.value) {

// Deselect color.
if($scope.model.useLabel) {
$scope.model.value = {
value: "",
label: ""
};
} else {
$scope.model.value = "";
}
newModelColor = "";

} else {

// Select color.
if($scope.model.useLabel) {
$scope.model.value = {
value: color.value,
label: color.label
};
} else {
$scope.model.value = color.value;
}
newModelColor = color.value;

}

//this is required to re-validate
$scope.propertyForm.modelValue.$setViewValue(newModelColor);

};

// 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 != ""),
isValid: !$scope.model.validation.mandatory ||
($scope.model.value !== null && $scope.model.value !== "" &&
(!$scope.model.value.hasOwnProperty("value") || $scope.model.value.value !== "")),
errorMsg: "Value cannot be empty",
errorKey: "required"
};
};

// A color is active if it matches the value and label of the model.
// If the model doesn't store the label, ignore the label during the comparison.
$scope.isActiveColor = function (color) {

// Variables.
var modelColor;
var modelLabel;
var compareBoth;

// Complex color (value and label)?
if($scope.model.value.hasOwnProperty("value")) {
modelColor = $scope.model.value.value;
modelLabel = $scope.model.value.label;
compareBoth = true;
} else {
modelColor = $scope.model.value;
modelLabel = null;
compareBoth = false;
}

// Compare either as a simple or as a complex color.
if (compareBoth) {
return modelColor === color.value && modelLabel === color.label;
} else {
return modelColor === color.value;
}

};

// Finds the color best matching the model's color,
// and sets the model color to that one. This is useful when
// either the value or label was changed on the data type.
function initActiveColor() {

// Variables.
var modelColor;
var modelLabel;
var hasBoth;

// Complex color (value and label)?
if($scope.model.value.hasOwnProperty("value")) {
modelColor = $scope.model.value.value;
modelLabel = $scope.model.value.label;
hasBoth = true;
} else {
hasBoth = false;
}

// Check for a full match or partial match.
if (hasBoth) {
var foundItem = null;

// Look for a fully matching color.
for (var key in $scope.model.config.items) {
var item = $scope.model.config.items[key];
if (item.value == modelColor && item.label == modelLabel) {
foundItem = item;
break;
}
}

// Look for a color with a matching value.
if (!foundItem) {
for (var key in $scope.model.config.items) {
var item = $scope.model.config.items[key];
if (item.value == modelColor) {
foundItem = item;
break;
}
}
}

// Look for a color with a matching label.
if (!foundItem) {
for (var key in $scope.model.config.items) {
var item = $scope.model.config.items[key];
if (item.label == modelLabel) {
foundItem = item;
break;
}
}
}

// If a match was found, set it as the active color.
if (foundItem) {
$scope.model.value.value = foundItem.value;
$scope.model.value.label = foundItem.label;
}

}

}
$scope.isConfigured = $scope.model.config && $scope.model.config.items && _.keys($scope.model.config.items).length > 0;

// Is the value truthy (accounts for some extra falsy cases)?
function isTrue(bool) {
return !!bool && bool !== "0" && angular.lowercase(bool) !== "false";
}

}

angular.module("umbraco").controller("Umbraco.PropertyEditors.ColorPickerController", ColorPickerController);
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
</div>

<ul class="thumbnails color-picker">
<li ng-repeat="(key, val) in model.config.items" ng-class="{active: model.value === val}">
<a ng-click="toggleItem(val)" class="thumbnail" hex-bg-color="{{val}}">

<li ng-repeat="(key, val) in model.config.items" ng-class="{active: isActiveColor(val)}">
<a ng-click="toggleItem(val)" class="thumbnail" hex-bg-color="{{val.value}}">
</a>
<span class="color-label" ng-bind="val.label"></span>
</li>
</ul>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
<div ng-controller="Umbraco.PrevalueEditors.MultiColorPickerController">
<div class="control-group color-picker-preval">
<input name="newColor" type="hidden" />
<label for="newColor" val-highlight="hasError">{{newColor}}</label>
<input name="newColor" type="hidden" id="{{newColorId}}" />
<label for="{{newColorId}}" val-highlight="hasError">{{newColor}}</label>
<input name="newLabel" type="text" ng-model="newLabel" class="umb-editor color-label" placeholder="Label" />
<button class="btn btn-small add" ng-click="add($event)">Add</button>
</div>
<div class="control-group color-picker-preval" ng-repeat="item in model.value">
<div class="thumbnail span1" hex-bg-color="{{item.value}}" bg-orig="transparent"></div>
<pre>{{item.value}}</pre>
<pre class="color-label">{{item.label}}</pre>
<button class="btn btn-small btn-danger" ng-click="remove(item, $event)">Remove</button>
</div>
</div>
Loading