Click here to Skip to main content
6,822,123 members and growing! (17,867 online)
Email Password   helpLost your password?
Web Development » Custom Controls » General     Intermediate License: The Code Project Open License (CPOL)

ASP.NET Color Picker Web Server Control

By Viktar Karpach

An ASP.NET color picker web server control
Javascript, C#2.0.NET2.0, ASP.NET, Dev
Revision:2 (See All)
Posted:20 Jul 2008
Updated:12 Mar 2009
Views:40,337
Bookmarked:57 times
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
24 votes for this article.
Popularity: 6.19 Rating: 4.49 out of 5
1 vote, 4.2%
1

2
2 votes, 8.3%
3
3 votes, 12.5%
4
18 votes, 75.0%
5
ColorPickerDemo.png

Introduction

It is difficult to find a decent color picker control for ASP.NET. However, there are plenty of pure JavaScript color picker controls. I decided to take one of them and convert it into an ASP.NET web server control. As a base, I took the dhtmlgoodies advanced color picker.

Project Setup

First, let's do New Project ->ASP.NET Server Control. By default, the name of the project would be the same as the name of the default namespace. I called my project WebControls, and renamed ServerControl1.cs to ColorPicker.cs. I changed default namespace to Karpach.WebControls, as well as assembly name. Then, I added to the project the images, JavaScript, and styles supplied by dhtmlgoodies.

CustomControlSolutionFiles.gif

Then, I clicked on each file's properties and changed the Build Action from Content to Embedded Resource. I also renamed some of the files.

AssemblyInfo.cs

I registered all the resources like this:

[assembly: System.Web.UI.WebResource("Karpach.WebControls.Images.SliderHandle.gif",
    "img/gif")]
[assembly: System.Web.UI.WebResource("Karpach.WebControls.Images.TabCenterActive.gif",
    "img/gif")]
[assembly: System.Web.UI.WebResource("Karpach.WebControls.Images.TabLeftActive.gif",
    "img/gif")]
[assembly: System.Web.UI.WebResource("Karpach.WebControls.Images.TabLeftInactive.gif",
    "img/gif")]
[assembly: System.Web.UI.WebResource("Karpach.WebControls.Images.TabRightActive.gif",
    "img/gif")]
[assembly: System.Web.UI.WebResource("Karpach.WebControls.Images.TabRightInactive.gif",
    "img/gif")]
[assembly: System.Web.UI.WebResource("Karpach.WebControls.Images.ColorPickerIcon.jpg",
    "img/jpeg")]

[assembly: System.Web.UI.WebResource("Karpach.WebControls.Styles.ColorPicker.css",
    "text/css")]

[assembly: System.Web.UI.WebResource("Karpach.WebControls.Javascript.ColorPicker.js",
    "text/js")]

As you might have noticed, System.Web.UI.WebResource, the first parameter has the following signature:

[Assembly Name].[Folder].[File Name]

This is very important, since it is not documented even in MSDN.

ColorPicker.cs

I modified ToolboxData to look like this:

[ToolboxData("<{0}:ColorPicker runat="server">")]

Next, I wanted a custom icon in the Visual Studio Toolbox. After ToolboxData, I added the following line...

[System.Drawing.ToolboxBitmap(typeof(ColorPicker),"Images.color_picker_icon.jpg")]

... where the first parameter is the type of the control and the second parameter is the icon file name used in AssemblyInfo.cs.

Originally color picker had two JavaScript files: color_functions.js and js_color_picker_v2.js. I combined them in one file, ColorPicker.js. Those files had a bunch of functions. I combined everything in one JavaScript class, exposed some public properties and one public function ShowColorPicker.

function ColorPicker(options)
{
    // Public properties
    this.FormWidgetAmountSliderHandleImage = options.FormWidgetAmountSliderHandleImage;
    this.TabRightActiveImage = options.TabRightActiveImage;
    this.TabRightInactiveImage = options.TabRightInactiveImage;
    this.TabLeftActiveImage = options.TabLeftActiveImage;
    this.TabLeftInactiveImage = options.TabLeftInactiveImage;
    this.AutoPostBack = options.AutoPostBack;
    this.AutoPostBackReference = options.AutoPostBackReference;
    this.PopupPosition = options.PopupPosition;

    // Public methods

    this.ShowColorPicker = function(inputObj, formField)
    {
	  //.....
	}
	// Private variables
	// ....

	// Private functions
    // ....
}

After some feedback, I had to fix JavaScript in order to support ASP.NET AJAX UpdatePanel and ModalPopup extender.

Then, I needed to load the stored resources from the DLL into JavaScript class. The best event for this is OnInit:

// Javascript
string colorFunctions = Page.ClientScript.GetWebResourceUrl(typeof(ColorPicker), 
				"Karpach.WebControls.Javascript.ColorPicker.js");
Page.ClientScript.RegisterClientScriptInclude("ColorPicker.js", colorFunctions);

// Create ColorPicker object
string script = string.Format(@"
var colorPicker = new ColorPicker({{
FormWidgetAmountSliderHandleImage : '{0}',
TabRightActiveImage : '{1}',
TabRightInactiveImage : '{2}',
TabLeftActiveImage : '{3}',
TabLeftInactiveImage : '{4}',
AutoPostBack : {5},
AutoPostBackReference : ""{6}"",
PopupPosition : {7}
}});
", Page.ClientScript.GetWebResourceUrl(typeof(ColorPicker), 
		"Karpach.WebControls.Images.SliderHandle.gif")
 , Page.ClientScript.GetWebResourceUrl(typeof(ColorPicker), 
		"Karpach.WebControls.Images.TabRightActive.gif")
 , Page.ClientScript.GetWebResourceUrl(typeof(ColorPicker), 
		"Karpach.WebControls.Images.TabRightInactive.gif")
 , Page.ClientScript.GetWebResourceUrl(typeof(ColorPicker), 
		"Karpach.WebControls.Images.TabLeftActive.gif")
 , Page.ClientScript.GetWebResourceUrl(typeof(ColorPicker), 
		"Karpach.WebControls.Images.TabLeftInactive.gif")
 , AutoPostBack?"true":"false"
 , Page.ClientScript.GetPostBackEventReference(this,"")
 , (int)PopupPosition
 );

Page.ClientScript.RegisterStartupScript(Page.GetType(), "InitColorPicker", script, true);
if (!DesignMode && Page.Header != null)
{
	RegisterCSSInclude(Page.Header);
}

Where RegisterCSSInclude is a following helper method:

private void RegisterCSSInclude(Control target)
{
    // CSS
    bool linkIncluded = false;
    foreach (Control c in target.Controls)
    {
        if (c.ID == "ControlPickerStyle")
        {
            linkIncluded = true;
        }
    }
    if (!linkIncluded)
    {
        HtmlGenericControl csslink = new HtmlGenericControl("link");
        csslink.ID = "ControlPickerStyle";
        csslink.Attributes.Add("href", Page.ClientScript.GetWebResourceUrl
	    (typeof(ColorPicker), "Karpach.WebControls.Styles.ColorPicker.css"));
        csslink.Attributes.Add("type", "text/css");
        csslink.Attributes.Add("rel", "stylesheet");
        csslink.EnableViewState = false;
        target.Controls.Add(csslink);
    }
}

Then I overrode the Render event of WebControl class in order to render the control HTML.

PlaceHolder plh = new PlaceHolder();
if (DesignMode || Page.Header == null)
{
    RegisterCSSInclude(plh);
}
Table table = new Table();
table.Rows.Add(new TableRow());
table.Rows[0].Cells.Add(new TableCell());
table.Rows[0].Cells.Add(new TableCell());
HtmlGenericControl txt = new HtmlGenericControl("input");
txt.EnableViewState = false;
txt.Attributes.CssStyle.Add(HtmlTextWriterStyle.Color, Color);
txt.Attributes.Add("maxlength","15");
txt.Attributes.Add("size", "15");
txt.Attributes.Add("value", Color);
txt.Attributes.Add("id",ColorInputControlClientId);
txt.Attributes.Add("name",this.UniqueID);
table.Rows[0].Cells[0].Controls.Add(txt);
HtmlInputImage btn = new HtmlInputImage();
btn.Src = Page.ClientScript.GetWebResourceUrl(typeof(ColorPicker), 
		"Karpach.WebControls.Images.ColorPickerIcon.jpg");
btn.Attributes.Add("onclick", string.Format("colorPicker.ShowColorPicker
    (this,document.getElementById('{0}'));return false;", ColorInputControlClientId));
HtmlGenericControl container = new HtmlGenericControl("div");
container.EnableViewState = false;
container.Controls.Add(btn);
container.Attributes.CssStyle.Add(HtmlTextWriterStyle.Position, "relative");
container.Attributes.CssStyle.Add(HtmlTextWriterStyle.Display, "block");
table.Rows[0].Cells[1].Controls.Add(container);
plh.Controls.Add(table);
plh.RenderControl(output); 

There are a few ways how you can save postback value of color picker. However I think the best way is to implement IPostBackDataHandler interface.

public bool LoadPostData(string postDataKey,NameValueCollection postCollection)
{
    String presentValue = Color;
    String postedValue = postCollection[postDataKey];

    if (presentValue == null || !presentValue.Equals(postedValue))
    {
        Color = postedValue;
        return true;
    }
    return false;
}

public virtual void RaisePostDataChangedEvent()
{
    OnColorChanged(EventArgs.Empty);
}

public void OnColorChanged(EventArgs e)
{
    if (ColorChanged != null)
        ColorChanged(this, e);
}

LoadPostData method will be called during each postback, when postback form has token with key this.UniqueID. As you can see above rendered input tag has name attribute this.UniqueID.

Build.proj

Now, the final touch: Minification of JavaScript and CSS. I used Yahoo YUI compressor and Microsoft MSBuild. Here is the final MSbuild file:

<?xml version="1.0" encoding="utf-8" ?>
<Project ToolsVersion="3.5" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <PropertyGroup>
    <MSBuildCommunityTasksPath>..\References</MSBuildCommunityTasksPath>
    <ProjectName>WebControls</ProjectName>
  </PropertyGroup>
  <Target Name="Compress">

    <Message Text="Create temp files ..." />
    <Copy SourceFiles=".\$(ProjectName)\Javascript\ColorPicker.js"
        DestinationFiles=".\$(ProjectName)\Javascript\ColorPicker.js.full"/>
    <Copy SourceFiles=".\$(ProjectName)\Styles\ColorPicker.css"
        DestinationFiles=".\$(ProjectName)\Styles\ColorPicker.css.full"/>
    <Exec Command=
       "java -jar yuicompressor-2.4.2.jar --type js .\$(ProjectName)\
       Javascript\ColorPicker.js.full >.\$(ProjectName)\Javascript\ColorPicker.js"/>

    <Exec Command=
       "java -jar yuicompressor-2.4.2.jar --type css .\$(ProjectName)\Styles\
       ColorPicker.css.full >.\$(ProjectName)\Styles\ColorPicker.css"/>
  </Target>
  <Import Project=".\References\MSBuild.Community.Tasks.targets" />
  <Target Name="Build" DependsOnTargets="Compress">

    <Message Text="Building Project" />
    <MSBuild Projects="./$(ProjectName)/$(ProjectName).sln"
        Properties="Configuration=Release;Platform=Any CPU" />
  </Target>

</Project>

Now you even don't need Visual Studio to compile DLL. All that you need is .NET 2.0 installed and then the following console script will do the compilation:

%SystemRoot%\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe  Build.proj /t:Build

Per requests below, I added PopupPosition property, so you can specify position of ColorPicker popup (top left, top right, bottom left, bottom right - default).

I also added AutoPostBack property and ColorChanged event.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Viktar Karpach


Member

Occupation: Web Developer
Company: ALG Worldwide Logistics
Location: United States United States

Other popular Custom Controls articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 25 of 82 (Total in Forum: 82) (Refresh)FirstPrevNext
GeneralAwesome Control! A few bugs? Or just me? Pinmemberbjahelka9:34 29 Jan '10  
GeneralColorPicker in gridview EditItemTemplate PinmemberjudyIsk23:45 21 Jul '09  
GeneralRe: ColorPicker in gridview EditItemTemplate PinmemberViktar Karpach4:36 23 Jul '09  
GeneralRe: ColorPicker in gridview EditItemTemplate PinmemberjudyIsk22:14 25 Jul '09  
GeneralRe: ColorPicker in gridview EditItemTemplate PinmemberViktar Karpach13:07 26 Jul '09  
GeneralBug in Slider PinmemberMember 54067796:20 30 Jun '09  
GeneralRe: Bug in Slider PinmemberViktar Karpach7:44 1 Jul '09  
GeneralMultiple ColorPickers on same page PinmemberMember 30146911:52 27 Mar '09  
GeneralRe: Multiple ColorPickers on same page Pinmemberankit_vyas19:48 21 Apr '09  
GeneralRe: Multiple ColorPickers on same page PinmemberMember 301469122:28 21 Apr '09  
GeneralRe: Multiple ColorPickers on same page PinmemberViktar Karpach3:34 22 Apr '09  
GeneralRe: Multiple ColorPickers on same page Pinmemberankit_vyas13:36 22 Apr '09  
GeneralRe: Multiple ColorPickers on same page PinmemberViktar Karpach20:42 23 Apr '09  
GeneralRe: Multiple ColorPickers on same page Pinmemberankit_vyas14:12 25 Apr '09  
GeneralRe: Multiple ColorPickers on same page PinmemberMember 30146911:33 1 May '09  
GeneralValidating the control PinmemberMember 12471490:10 19 Mar '09  
GeneralVisibility Pinmemberdherrmann1:18 17 Mar '09  
GeneralRe: Visibility PinmemberViktar Karpach4:35 17 Mar '09  
QuestionSearch in your website PinmemberBlumen1:54 15 Mar '09  
AnswerRe: Search in your website PinmemberViktar Karpach9:49 16 Mar '09  
GeneralAutoPostBack? PinmemberNick Tam7:53 27 Feb '09  
GeneralRe: AutoPostBack? PinmemberViktar Karpach14:17 1 Mar '09  
GeneralRe: AutoPostBack? Pinmembernktm859:38 3 Mar '09  
GeneralMultiple Objects in page !! PinmemberMember 47189925:45 9 Feb '09  
GeneralRe: Multiple Objects in page !! PinmemberMember 43371026:20 9 Feb '09  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads.

PermaLink | Privacy | Terms of Use
Last Updated: 12 Mar 2009
Editor: Deeksha Shenoy
Copyright 2008 by Viktar Karpach
Everything else Copyright © CodeProject, 1999-2010
Web17 | Advertise on the Code Project