Don't miss out Virtual Happy Hour this Friday (April 26).

Try our conversational search powered by Generative AI!

How to use Spectrum color picker for property

Vote:
 

I have been trying to attach a color picker to a property in episerver edit mode for quite som time now, but my effortsare fruitless. The dojo syntax and and the color palette provided by the dijit-widget are equally horrible.Thats why I want to do something else. Like a simple dropdown list, done via the SelectionFactory. That seemed promising, only that the produced list items cannot contain HTML.

public class BackgroundColorSelectionFactory : ISelectionFactory
{
    public IEnumerable GetSelections(ExtendedMetadata metadata)
    {
        return new ISelectItem[]
        {
            new SelectItem()
            {
                Value = "red",
                Text = " Blue as hell"
            }
        };
    }

So I have decided to simply use Spectrum. Well, simply isn't the word, as hooking up this complicated javascript event ($(#input.spectrum()) on a certain input element (with css and javascript of course) has proven quite the challange. Any ideas will be greatly appreciated

#139805
Oct 06, 2015 14:18
Vote:
 

Hi,

The spectrum is a jQuery library, and jQuery is not included for episerver EditMode properties. You need probably create custom widget to use spectrum.

The SelectionFactory also can't be implemented is that simple way, because as you saw the text is encoded instead of used as HTML. If you prefer this solution, then check those blogs. They are about dropdown with icons, but you could change dropdowns into coloured rectangles.

http://geta.no/blogg/font-awesome-auto-complete-editor-for-episerver/

http://www.mogul.com/en/about-mogul/blog/font-awesome-dropdown-for-episerver-edit-mode

And finally the easiest solution is to use built-in dijit widget:

[ClientEditor(ClientEditingClass = "dijit/ColorPalette", EditorConfiguration = "{\"palette\": \"7x10\"}")]
public virtual string Color { get; set; }

It's a very simple solution and the effect is not that good as with spectrum, but it;s just one line of code...

#139816
Oct 06, 2015 15:26
Vote:
 

If you'd like to use spectrum as a dojo widget/editor - we've created exactly what you are looking for, i'll try to post the code here for you to follow:

Module.config additions:

<add name="phoenixcms-includes-scripts" path="ClientResources/Scripts/Libraries/jquery-2.1.1.min.js" resourceType="Script" sortIndex="0" />
<add name="phoenixcms-includes-scripts" path="ClientResources/Scripts/Libraries/spectrum.js" resourceType="Script" sortIndex="6" />
<add name="phoenixcms-includes-styles" path="ClientResources/Styles/spectrum.css" resourceType="Style" />

making sure your name value for these are also defined and loaded in the required resources section of module.config also.

Editor Descriptor Class:

using EPiServer.Shell.ObjectEditing.EditorDescriptors;
using System.Collections.Generic;
using System;
using PhoenixCore.Extensions.Helpers;
using System.Web.Mvc;
using System.Linq;
using PhoenixCore.UI.PropertyAttributes;

namespace PhoenixCore.UI.EditorDescriptors
{
    [EditorDescriptorRegistration(TargetType = typeof(string), UIHint = "ColorPicker")]
    public class ColorPickerEditorDescriptor : EditorDescriptor
    {
        public override void ModifyMetadata(EPiServer.Shell.ObjectEditing.ExtendedMetadata metadata, IEnumerable<Attribute> attributes)
        {
            base.ModifyMetadata(metadata, attributes);

            ClientEditingClass = "phoenixcms.Editors.ColorPickerEditor";

            var colorPickerEditorOptions =
                attributes.OfType<ColorPickerEditorOptionsAttribute>().FirstOrDefault();

            if (colorPickerEditorOptions != null)
            {
                metadata.EditorConfiguration["showInput"] =
                    colorPickerEditorOptions.ShowInput;

                metadata.EditorConfiguration["showInitial"] =
                    colorPickerEditorOptions.ShowInitial;

                metadata.EditorConfiguration["allowEmpty"] =
                    colorPickerEditorOptions.AllowEmpty;

                metadata.EditorConfiguration["showPalette"] =
                    colorPickerEditorOptions.ShowPalette;

                metadata.EditorConfiguration["showPaletteOnly"] =
                    colorPickerEditorOptions.ShowPaletteOnly;

                metadata.EditorConfiguration["togglePaletteOnly"] =
                    colorPickerEditorOptions.TogglePaletteOnly;

                metadata.EditorConfiguration["palette"] =
                    colorPickerEditorOptions.Palette ?? "";
            }
        }
    }
}

ColorPickerEditorOptions class to support customization of the color picker on each property:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PhoenixCore.UI.PropertyAttributes
{
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
    public class ColorPickerEditorOptionsAttribute : Attribute
    {
        public bool ShowInput { get; set; }
        public bool ShowInitial { get; set; }
        public bool AllowEmpty { get; set; }
        public bool ShowPalette { get; set; }
        public bool ShowPaletteOnly { get; set; }
        public bool TogglePaletteOnly { get; set; }
        public string Palette { get; set; }
    }
}

Finally, the dojo widget that the editor descriptor loads:

define([
    "dojo/_base/declare",
    "dijit/_Widget",
    "dijit/_TemplatedMixin",
    "epi-cms/widget/_HasChildDialogMixin",
    "dojo/_base/lang",
    "dijit/registry",
    "dojo/text!./templates/colorpickereditor.html",

    "epi/dependency",
    "epi/epi"
], function (
    declare,
    _Widget,
    _TemplatedMixin,
    _HasChildDialogMixin,
    lang,
    registry,
    template,

    dependency,
    epi
) {
    return declare("phoenixcms.Editors.ColorPickerEditor",
        [_Widget, _TemplatedMixin, _HasChildDialogMixin], {
            templateString: template,
            intermediatehanges: false,
            value: null,
            showInput: false,
            showInitial: false,
            allowEmpty: false,
            showPalette: false,
            showPaletteOnly: false,
            togglePaletteOnly: false,
            palette: null,

            onChange: function (value) { },

            _onChange: function (value) {
                this.onChange(value);
            },

            startup: function () {
                var base = this;

                var palleteOptions = null;
                if (base.pallete != null) {
                    palleteOptions = JSON.parse(base.palette);
                }

                $('#' + this.id + ' .colorSelector').spectrum({
                    color: base.value,
                    preferredFormat: "hex",
                    showInput: true,
                    showInitial: base.showInitial,
                    allowEmpty: base.allowEmpty,
                    showPalette: base.showPalette,
                    showPaletteOnly: base.showPaletteOnly,
                    togglePaletteOnly: base.togglePaletteOnly,
                    palette: palleteOptions,
                    change: function (color) {
                        if (color != null) {
                            base.value = color.toHexString();
                        }
                        else {
                            base.value = null;
                        }
                        base._updateValue(base.value);
                    },
                    show: function (color) {
                        base.isShowingChildDialog = true;
                    },
                    hide: function (color) {
                        base.isShowingChildDialog = false;
                    }
                });
            },

            postCreate: function () {
                this.inherited(arguments);
            },

            _updateValue: function () {
                this._onChange(this.value);
            }
        });
});

And very finally, the actual property definition on a page type or block:

 [Editable(true)]
        [Display(
            Name = "Action Link Button Color",
            Description = "The background color of the jumbotron action link button (only applies to button settings)",
            GroupName = SystemTabNames.Content,
            Order = 155)]
        [UIHint("ColorPicker")]
        [ColorPickerEditorOptions(
            AllowEmpty = true
        )]
        public virtual string ActionLinkColor { get; set; }

Hope this helps you get the editor widget you are looking for.  This is working in our production environment.


                        
#139817
Edited, Oct 06, 2015 15:39
Vote:
 

@Grzegorz Wiecheć: Thank you for your swift response! The problem with the built in palette is that it is just a palette, and not a picker. Thats why I chose to use Spectrum

@Mike Cockrell: Thanks a bunch! This is really awesome. I have been trying to get to get your code to work. Everything compiles, but I think I might have misconfigured my modules.config. 

My complete config

<?xml version="1.0" encoding="utf-8" ?>
<module>
  <clientResources>
    <add name="epi-cms.widgets.base" path="/content/dist/editorstyles/styles.css" resourceType="Style"/>
    <add name="nidcms.includes-scripts" path="ClientResources/Scripts/Libraries/jquery.min.js" resourceType="Script" sortIndex="0" />
    <add name="nidcms.includes-scripts" path="ClientResources/Scripts/Libraries/spectrum.js" resourceType="Script" sortIndex="6" />
    <add name="nidcms.includes-styles" path="ClientResources/Styles/spectrum.css" resourceType="Style" />
  </clientResources>
  <clientModule>
    <moduleDependencies>
      <add dependency="Shell"/>
    </moduleDependencies>
    <requiredResources>
      <add name="nidcms.includes-script"/>
      <add name="nidcms.includes-styles"/>
    </requiredResources>
  </clientModule>
</module>

My tree structure:

ColorPickerEditor.js is the DojoWidget definition

Error message in developer console:

GET: http://myepiserversite/EPiServer/Shell/9.1.0.0/ClientResources/nidcms/Editors/ColorPickerEditor.js 

Episerver failed to locate my file. So the question is if episerver is looking at the right place, and the file is missing, or if episerver is looking at the wrong place. 

Thanks in advance!

Daniel 

#139835
Edited, Oct 07, 2015 13:25
Vote:
 

Hey @Daniel, did you get the issues with Spectrum sorted in the end?  I'm also trying to implement and I'm not 100% sure if my modules.config is correct.  I can see the ColorPickerEditor.js being loaded in the browser but I'm getting a 404 on colorpickereditor.html - Just wondering if I'm missing a file? This is referenced in ColorPickerEditor.js - "dojo/text!./templates/colorpickereditor.html",

Cheers
Mark

#187152
Jan 15, 2018 6:18
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.