Display Templates – Colour Picker

Following on from my recent post which explores the potential of using Display Templates with Site Columns I wanted to expand on that concept with another idea that has proved a challenge in SharePoint – a colour picker.

There are several times in the past I have wanted to allow a user to choose a colour – perhaps for a particular category in a list driven menu. Display Templates let me do just this.

Site Column
Name: ColourPicker
Type: Single line of text

As usual, you can give this a friendly display name by editing after it has been created, but that is all you need to do for the site column. It is ready to be added to any list or library and will hold the hex value of the selected colour.

Display Template
You can get the full Display Template here on GitHub. Note that I have extended the basic concept to also display the RGB values just in case you need them. As is my usual approach I have saved my file into a custom folder inside my Style Library.

The invertColour function simply lets me show the hex value in display mode using a contrasting colour to the background which is my selected colour.

paylord.colourPicker.invertColour = function(hexTripletColor) {
    var color = hexTripletColor;
    //color = color.substring(1);         // remove #
    color = parseInt(color, 16);          // convert to integer
    color = 0xFFFFFF ^ color;             // invert three bytes
    color = color.toString(16);           // convert to hex
    color = ("000000" + color).slice(-6); // pad with leading zeros
    //color = "#" + color;                // prepend #
    return color;
}

To be able to show the RGB values of my selected colour, I also need to convert from hex:

paylord.colourPicker.hexToRgb = function(hex) {
    // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
    var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
    hex = hex.replace(shorthandRegex, function(m, r, g, b) {
        return r + r + g + g + b + b;
    });

    var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
    return result ? {
        r: parseInt(result[1], 16),
        g: parseInt(result[2], 16),
        b: parseInt(result[3], 16)
    } : null;
}

So now I bring those together with a template to display the selected value in view mode:

paylord.colourPicker.colourViewTemplate = function(ctx) {
	var colour = ctx.CurrentItem[ctx.CurrentFieldSchema.Name];
	if (colour == "") {
		colour = "353535";
	}
	
	if (colour[0] == "#") {
		colour = colour.substring(1);
	}
	
	var rgb = paylord.colourPicker.hexToRgb(colour);
	var title = "";
	title = "R:" + rgb.r + " G: " + rgb.g + " B:" + rgb.b;
	
	var fontColour = paylord.colourPicker.invertColour(colour);

	var ret = "<div title='" + title + "' style='background-color: #" + colour + ";color:#" + fontColour + ";padding: 0px 5px;'>" + colour + "</div>";
	return ret;
}

So now to focus on setting the colour. What I want to do is grab the current value or set a default if it is blank then ensure I set the class so my field is recognised by the colour picker:

paylord.colourPicker.colourEditTemplate = function(ctx) {
	var formCtx = SPClientTemplates.Utility.GetFormContextForCurrentField(ctx); 
	formCtx.registerGetValueCallback(formCtx.fieldName, paylord.colourPicker.getFieldValue.bind(null, formCtx.fieldName));
	var elId = "paylord-" + formCtx.fieldName;
	
	var colour = ctx.CurrentItem[ctx.CurrentFieldSchema.Name];
	if (colour == "") {
		colour = "#353535";
	}
	var ret = "<input id='" + elId + "' class='color' value='" + colour + "'>";
	return ret;
};

And finally, I register my templates:

(function () {
	var colourCtx = {};
	colourCtx.Templates = {};
	colourCtx.Templates.Fields = {
		"Colour": {
			"View": paylord.colourPicker.colourViewTemplate,
			"DisplayForm": paylord.colourPicker.colourViewTemplate,
			"EditForm": paylord.colourPicker.colourEditTemplate,
			"NewForm": paylord.colourPicker.colourEditTemplate
		}
	};
	
	SPClientTemplates.TemplateManager.RegisterTemplateOverrides(colourCtx);

})();

Colour Picker Script
For the purposes of this example, I decided to go with a pure JavaScript colour picker rather than one dependent on jQuery. There are many to choose from out there so feel free to experiment and find one you like. I went with JSColor which is really easy to interface with as all I had to do was give the input field a class of “color”.

PowerShell
In this case, our template needs both the Display Template and the JSColor script so this introduces the ability to add multiple scripts to our Site Column. It is just the same as before but we separate each script we want to reference with a pipe ¦ character:

$web = Get-SPWeb "http://sitename"
$field = $web.Fields["ColourPicker"]
$field.JSLink = "~sitecollection/Style Library/custom/jscolor.js¦~sitecollection/Style Library/custom/ColourPicker.js"
$field.Update($true)
$web.Dispose()

The Resulting Column in Action

Colour Picker showing RGB hover text

Colour Picker showing RGB hover text

Colour Picker Showing Picker

Colour Picker Showing Picker

So here is the resulting column in display mode and edit mode. When you click on the input in edit mode then the colour picker appears and lets you choose the colour you like which then stores the hex value in the text field.

JSLink Property
Being able to add the JSLink through the standard browser interface settings for the site column would make this whole approach so much more flexible so I have raised it as a suggestion on User Voice – please add your vote.

This entry was posted in SharePoint and tagged , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s