Color select control (version 4.1)
posted Jul 21, 2007

This is an attempt at a standards-compliant, cross-browser, color select interface widget. It's written in javascript & css, and is fairly modular and customizable. Multiple independent color selects can exist on the same page.

It may be slightly jerky, because this site uses a different javascript library, which competes with the color select for handling browser events. The color select is a stand-alone piece of javascript, not tied to any library. See colr.org for an example of the widget on its own.

Update: Jonas Tampier contributed a javascript fix that fixes strange behavior when the color select is inside an absolutely positioned element. To update, replace your version of color_select.js with the current one.

Update: Andy Smith's code is now used for attaching events. The html elements and associated events no longer need to be specified on the page. The color select creates them its own self.

Update: Cleaned up some things, simplified some things

Update: Cleaned up more things

Example 1 (integrated with a menu)

Choose a color (actually, choose "custom"). Notice how the background color for the "custom" menu item updates in real-time as you adjust the color select.

Example 2 (integrated with a text input)

    

The color select and the form input are tied together. Change one, and the other automatically updates.

Features:
  • It works in both Mozilla and IE (Mozilla 1.2, IE 6.0)
  • It validates! (well, this page doesn't quite validate, but it's not the color select's fault.)
  • You can have multiple color selects per page!
  • It's easy to hook up to other page elements (see example 1)
  • The behavior is as close as possible to a form control. This requires some javascript kung-fu for handling things like mouse dragging.
To-do list:
  • Keyboard support (it would be nice to use the arrow keys to make fine adjustments)
  • Fix the bug where dragging the browser scroll bars causes the color select to hide.
  • Fix the bug where resizing the window doesn't cause the color select window to hide.
  • Make a more convenient half-size version (or somehow allow arbitrary scaling?).
How it works:

To achieve the smooth gradient, The color select control uses a semi-transparent .png image over a colored background.

While working on the control, I came across this site, which uses the same technique. I didn't use any of their code, but their tool is very similar to mine, and it deserves some credit (even if it doesn't work in IE).

Many people think that IE can't handle semi-transparent .png images. That's mostly correct. But MS' proprietary AlphaImageLoader style element is a workaround. It's a little clunky, but it solves the problem. I'm ok with writing a small amount of browser-specific css. After all, I use mozilla-specific css to get nice rounded corners on my website.

How to use it:

You'll need the following:

The two images used by the select tool: hue_blend.png, and sv_blend.png.

A link to the color_select.css stylesheet (this contains styles for the DOM elements that comprise the color select control):

<link rel=stylesheet href="color_select.css" type="text/css"/>

A reference to the color_select.js file (this contains the class definition for the color_select object, and all functions & methods used by the class):

<script type="text/javascript" src="color_select.js"></script>

Then, in your javascript, you have to create a new instance of the color_select class, and hook up the DOM elements you created to it. You have to hook up each instance of the color select separately.

var cs0 = new color_select('cs0');

Or if you want to supply an initial color:

var cs0 = new color_select('cs0', '#00ff00');

You probably want to hook the color select to the rest of your code somehow.

To do this, define a function called [color_select_id]_change_update(new_color). (and optionally, a function called [color_select_id]_hide_update(new_color). Example:

 function cs0_change_update(new_color) {
window.status = new_color;
}

If you hate to be constrained by function names, you don't have to be:

 function my_awesome_update_o_matic_function(the_new_color) {
window.status = the_new_color;
}
cs0.change_update_function = "my_awesome_update_o_matic_function";   // NOTE-there are no ()

There are two possible update functions - change_update and hide_update - called when the color select changes in value, or is hidden. They both should accept along a single string as the first argument: the current color in hex (i.e. "#FF03E5").

I like to put this stuff in a function, and use

<body onLoad="cs_init();">

or

setTimeout("cs_init()",200);
Example:
function cs_init() {
  var cs0 = new color_select();

  // spatially attach the color select to an element 
  // (when triggered, it will always appear below this element)
  cs0.attach_to_element(document.getElementById("color_select_icon0"));
 
}  

And done!

Comment by Sam
posted Dec 12, 2003

In IE the controls are off-center of the mouse when using them. And I'm seeing the text " " instead of proper non-breaking spaces. Pretty cool despite that.

Comment by Tim
posted Mar 15, 2004

Tested it in IE and Opera. IE working good, but in Opera it is bugged ...

Comment by Anders Holm
posted Apr 06, 2004

Hello there... Nice work. Can this "plugin" be used in a commercial matter?

Comment by LPD
posted Apr 06, 2004

Yes. It's public domain.

Comment by Anders Holm
posted Apr 07, 2004

Thank you very much then. This plugin is a brilliant work of scripting :D (and thinking)

You little Einstein ;)

Comment by LPD
posted Apr 07, 2004

Actually, it's just a copy of the GIMP color select (which may be derived from somewhere else):

http://www.mpi-hd.mpg.de/galileo/software/gimp/images/color_select.gif

  • Lloyd
Comment by Tim Hardy
posted May 27, 2004

It needs a button to say "Select" or "Done" or some UI element for the user to let the selector know that they're done choosing a color. Press Done, or Select or whatever, and the selector should go away. It's not real intuitive to have to click somewhere else on the page in order to make it go away. I mean it works, but it doesn't feel right.

Other than that, it's really nice.

Comment by LPD
posted Jun 28, 2004

That's a good point. I originally wanted it to function like a drop-down or pop-up menu. But it may be a little more complex than the typical drop-down menu. I will think about adding a close button or something.

Comment by byu webguy
posted Jul 23, 2004

Wow. I've been doing dhtml and Javascript programming for many years now. When I first saw the color selector, all I could say is wow--about 5 times. I still continue to say wow every time I see it. It is possibly the best web programming I've ever seen. Thanks!

Comment by nocelery
posted Aug 18, 2004

pretty slick . . . I was writing my own selector when I came across this and after getting my head around the 16m(253^3) colors and writing all sorts of equations . . .I was simply blown away. Excellent stuff.

Comment by turrican
posted Sep 04, 2004

Darn great stuff, very well done. Really awesome work - just too bad it doesn't work in opera (I'll check that maybe if i find time)

Keep up the good work :)

Comment by Oliver Said
posted Sep 11, 2004

Hey there. Great script, was gonna use it on my site until I encountered a problem. The boxes that need the color were too far down and right, causing the color picker to be cut off. Perhaps you should fix this, or put it on your todo list. Make it to go up and left or let us choose up and right, down and left, etc..

<a href=http://www.dynamix.bannerbreak.com/edit.php?id=1http://www.dynamix.bannerbreak.com/edit.php?id=1</a>>

That's the page with the problem.

-Oliver

Comment by Oliver Said
posted Sep 12, 2004

As a matter a fact, it was the scroll bug that was messing up my attempts to change it. I also have another quaetion though. How do you get the beginning color? I would like to know where #333404 comes from :-P Anyway, I'm gonna look into this, and if I create a patch to the color_select.js file letting you choose a start color, I'll post it here.

-Oliver

Comment by Bharat
posted Dec 14, 2004

I have done lot javascripting over last 3 years. I had not even imagined that anything like this can be done with javascript. Great outstanding work. Hats off to you man.

Comment by YvesB
posted Jan 07, 2005

Somebody have a exemple this script with more one color selected ? Because i have some dificults for employed this in my page. My page with script : http://www.afterdreams.com/homeblog/couleurs/changecoul.php Sorry for my english, I'm french.

Comment by anonymous
posted Jan 07, 2005

The numbering of your two color selects is wrong:

In the javascript, you have: cs0.colorselectbox = document.getElementById("colorselectbox0"); ... cs1.colorselectbox = document.getElementById("colorselectbox1");

In the html, you have: div id="colorselectbox1" ... div id="colorselectbox2"

Comment by Robert Ryan
posted Jan 17, 2005

Hm, for some reason this script did not work correctly locally on my machine until i changed this line: this.svselectboxbg.style.background = newcolor; To this.svselectboxbg.style.backgroundColor = newcolor;

Very weird, considering it works here on your site with the exact same code.

Anyways, extremely cool script!

Comment by Fred
posted Mar 03, 2005

Works ok in IE 6.0, but fails with IE 5.5. Background image is'nt displayed, and mouse control works only on the right bar...

Comment by Damir Secki
posted May 14, 2005

Hello!

It's a great color picker... in my opinion you should resize it (half the size would be ok) and second... instead of that icon, it should be a selected color! (also with a started color in it!)

Comment by Ian
posted May 30, 2005

Are you aware that the given example screws up the other form elements of the page? I need to right click on the fields to get the cursor show up and be able to type..

Comment by LPD
posted Jun 14, 2005

Thanks for catching that, Ian. That bug is fixed now. The color select was trapping mousedown events and disabling the default behavior (the idea was to prevent text on the page from being "selected" in IE when the color select cursor was dragged around.

Comment by Sylvio
posted Jun 30, 2005

IE BUG : Files must be in the same directory than the HTML page else : - SV selector (256x256px area) will not be display correctely (no gradient - it show only the plain color selected at the right) - Mouse action doesn't work in the SV selector

All works fine in firefox when files are in a different directory and css file and javascript file are linked correctely

Comment by lpd
posted Jun 30, 2005

This is because IE is crap! :) Actually, it's because when IE sees relative "url" references in the stylesheet, it looks up the urls relative to the page location (not the stylesheet location).

You can work around this by adding your subdirectory to all the images in the css file.

  • Lloyd
Comment by pf
posted Jul 14, 2005

This is excellent work! I want to say thank you! However I am too dumb to pass it an initial color value. My INPUT is always overwritten with #FFFFFF on load. I know you mentioned that in the HowTo-Section above, but I am quite a beginner in javascript.... A little written out example would be very appreciated.

Comment by Spigot
posted Jul 20, 2005

This is awesome! Took me a while to figure out the nuances of using it, but i'm finally putting it in action. One problem, however: I'm using it in a large color-picker form, with about 10 instances of it on a page, each attached to a different INPUT on the same form. They all work, but on the lower few INPUTs, the color picker appears way higher then it should, thus forcing the user to scroll upwards. Glancing at the code, I presume it's related to docjslib_getRealTop() messing up somewhere. I'm not good enough at javascript to kludge up even a lame fix for it.

Comment by Bill
posted Aug 07, 2005

Hi Lloyd,

First off, in case you haven't heard, this is a beautiful script and its exactly what I've been looking for.

I'm using it on a page that has multiple color selects (10 of them). The selected colors are entered into a database. The problem I have is.. When the page reloads the default values change to #ffffff, and I need them to be the value that was entered into the database. I set the value of the form field to the color it should be (see below), and it works, but when the page loads it changes back to #ffffff. I'm a dummy when it comes to javascript, and was hoping there is an easy cure for this.

input name="fontColor" class="formfields" id="fontColor" onchange="cs2.setrgb(this.value);" onkeypress="if (event.keyCode == 13){return false;}" value="<%=(settings.Fields.Item("fontColor").Value)%>" type="text" size="7" maxlength="7" span id="colorselecticon2" class="bodycopy" onclick="cs2.togglecolorselect();"> select

Any help would be appreciated.. Bill

Comment by Johnathan
posted Aug 09, 2005

Set this variable somewhere.

cs1.setrgb("#HEXCOLOURCODE");

And change the cs1 to the appropriate thing.

Comment by LPD
posted Aug 12, 2005

You can do this:

var cs0 = new color_select('cs0', '#00ff00');

Comment by almulder
posted Aug 20, 2005

could you show a example of a new html file with a table that has 5 rows and a "Example 2 (integrated with a text input)" version in each line that works, I have tryed to make a basic html to see how it works but have had no such luck.

Thank you for your help.

Comment by Simon
posted Sep 05, 2005

Hi all, <br><br> Had some time spare today and fixed the scrolling cause it to hide problem (not sure if anyone else has done this yet, still on the to do list though) <br><br> <u>Solution</u><br> In the js file add:

a variable called abortClose

this.AbortClosing = function() { abortClose=true; }

abortClose=false; above the line "setTimeout("colorselecthide("+l1+")",200);" in function "colorselectmousedown"

Change the function "" to read as below:

function color_select_hide(num)
{
  var ob=color_selects[num];
  if(!abortClose) {
    ob.hide();
  }
  else {
    abortClose=false;
  }
}

Then in the body tag add:    onscroll="cs0.AbortClosing();" Obviously replacing cs0 with your object ID.

Sorry if this is a bit jibberish. The general concept is that the hide is done on a timeout. If you add a function to set a variable to override the closing and use the variable in the hide function then you will be fine and dandy.

Comment by Gui
posted Sep 23, 2005

If you want this script to work with IE you HAVE to place the .js file in the same directory. Something like that src="../colorselect/color_select.js" will not work. Note that IE is not giving errors just that you can't move the cursors. Seems that the problem is that mousemove events are not hooked correctly but I don't have time to look into it any further.

Gui

Comment by Top One
posted Nov 12, 2005

Hi,

Is there any license agreement around?

GPL, LGPL or other?

10x

Comment by mcmjon
posted Dec 05, 2005

its not currently working for me???? I put in a word in the box and press "Go!" and nothing happens. I do however get a javascript error about an element not being null or object.

I'm running windows 2000 pro totally up to date. I tested with: I.E. FireFox and Opera (all lastest versions)

... and had the same problem in all browsers.

I couldn't get any results to show.

Comment by Redeye
posted Apr 12, 2006

Fantastic piece of code! Have been playing and seems to be some problem with positioning, probably due to my pages having some complicated embedded DIV positioning. Happens with both IE6 and firefox, could I suggest positioning override by passing x,y coords to the show function?

Comment by David Hern%e1ndez
posted Jun 27, 2006

Hello,<br><br> I have some extensions to color select: <ul><li>add optional button for transparent color</li> <li>supports multilenguage</li> <li>supports themes (I have 2)</li> </ul> explanation and source code are in <a href="http://www.terra.es/personal3/davidhdezsanz/paginas/misaplic/jscolors.htm</a><br>> (my page is in spanish)

Comment by Shachi Bista
posted Jul 07, 2006

Great piece of scripting!! Keep up the good work. I think you should write a tutorial on stuffs like these so that development like these keep on going, just a suggesstion!! Again, great work!!

Comment by Joomla!
posted Sep 20, 2006

It's exactly what I was looking for. But I can't get it work. What do I have to put where in my html file? What do I have to change? Could you paste a whole example of Example 2 (sounds silly) :), please?

Comment by Brown
posted Dec 14, 2006

Thanks!! This is exactly I was looking for... Great solution, really...

Comment by sandh
posted Jan 13, 2007

(sorry for the broken english)

I used the script under IE7 and I found one little bug. The vertical line of the crosshair is not in its normal position (it's under the box). So it will be just fine if you define the "top" value for it in the stylesheet

e.g.

.svcrosshairvert_cursor {

position:absolute;

border: 0px;

background-color:#000;

color: #0c0c0c;

height:257px;

width:1px;

padding:0px;

top: 0px;

}

P.S. - great work! :)

Comment by Baris
posted Feb 04, 2007

Hi all it's perfect component. I am using for content management consol. But, sometimes ie was appeared the error message. when I was <body bgcolor="#4D5052" onLoad="cs_init();"> code it was fixed.

Sample of the code

function csinit() { cs1 = new colorselect('cs1','<?=$arkaplansayfarengi?>'); cs2 = new colorselect('cs2','<?=$sayfarengi?>'); cs3 = new colorselect('cs3','<?=$navigasyonarkaplanrengi?>'); cs4 = new colorselect('cs4','<?=$navigasyontextrengi?>'); cs5 = new colorselect('cs5','<?=$navigasyontextarkaplanrengi?>'); cs6 = new colorselect('cs6','<?=$menusecimrengi?>'); cs7 = new colorselect('cs7','<?=$menusecimmetinrengi?>');

cs1.attachtoelement(document.getElementById("colorselecticon1")); cs2.attachtoelement(document.getElementById("colorselecticon2")); cs3.attachtoelement(document.getElementById("colorselecticon3")); cs4.attachtoelement(document.getElementById("colorselecticon4")); cs5.attachtoelement(document.getElementById("colorselecticon5")); cs6.attachtoelement(document.getElementById("colorselecticon6")); cs7.attachtoelement(document.getElementById("colorselecticon7")); }

Comment by Brian Birtle
posted May 01, 2007

FANTASTIC! I was getting worried I'd have to reinvent the wheel until I found this, after sifting through 50 other controls that are either not free or do not allow picking any color on the spectrum.

It works perfect so far (in Firefox) and I'm back and moving along on my form.

Thanks very much!

  • Brian
Comment by KentR
posted May 28, 2007

hmm... Not working in IE6 for me. Pops up, but the color gradient isn't there (just a solid color).

[edit] Just noticed: The mouse has no effect inside the color selector, either. No crosshairs appear, and clicking does nothing.

Comment by Jai
posted Jun 22, 2007

I am confused as to how to even get this started. I needthe integrated with a text input one, but I don't understand what I need to do to add it in.

Comment by Sean Utt
posted Jul 21, 2007

a slight bug in the example with a select: <option id="op0" style="background-color: rgb(153, 204, 255);" value="#99ccff; selected">

should be: <option id="op0" style="background-color: rgb(153, 204, 255);" value="#99ccff;" selected>

other than that, THANKS!

Sean

Comment by LPD
posted Jul 21, 2007

Sean, thanks for noticing that bug! It's fixed now.

Comment by Sean Utt
posted Jul 23, 2007

A little quirk in Firefox, the background color for the option is overriden by the background color of the select if the select has a background color set, so to stop that, I use onChange="if(this.selectedIndex==this.length-1){cs1.togglecolorselect();}else{this.style.backgroundColor='';}" to clear the color. (assumes that custom is the last option) before I have the cs1changeupdate(new_color) function set the background of the custom option and the background of the select to the custom color. This way the selected color shows when custom is the selected option, and the non-custom ones look right when it is not (and so does custom when the select drops down). Hope this helps.

Sean

Comment by Jeremy
posted Sep 26, 2007

Great work on the color select control.

A few issues: Your current version posted on this page doesn't work in IE 6, so I had to go to the other sites that implement this to see what was wrong. It turned out it had to deal with IE's png filter, which wasn't getting loaded correctly.

Also, I found a small bug: If you drag the hue selector around and release the mouse while not hovering over the hue selector image, the hue changes as you move around your unclicked mouse, which isn't a big deal - EXCEPT that when you click out of the color select box the hue still changes as you move your mouse even though the color select box is hidden. I was able to fix the error by placing: this.hselectbox_focus=false;

in the this.hide function. I'm sure it would be better placed in the unfocus() function but this was a fix that I worked quickly.

Comment by Don Russell
posted Oct 06, 2007

I think this is the nicest color picker control I've found, and the easiest to use.

However, I did have to tweak the css file for my use and modify the sv_image property of the color selector.

cs0 = new colorselector('cs0'); cs0.svimage='images/sv_blend.png';

It would be cool if there were a method (setImagePath?) so it would dynamically change the three css settings as well...

i.e. Something like:

cs0 = new color_selector('cs0'); cs0.setImagePath('images');

That way no "tweaks" would be needed at all. :-)

Very cool... great job with the DOM stuff....

PS.. I can't get the underscore character to behave in a consistent manner in my comments here... svimage is read as sv(underscore)image and colorselector is color(underscore)selector

Cheers

Comment by Andrea Chiodi
posted May 20, 2008

This little modification in color_select.js allows to change the position of the gadget (from outside):

this.attachtoelement = function(e, offsx, offsy) {

//patch: offsx, offsy added to change position

this.x = docjslib_getRealLeft(e) + offsx;

this.y = docjslib_getRealTop(e) + 22 + offsy;

}

Seems to work ...

Comment by Tapio
posted Jun 17, 2008

Great color picker, BUT! one strategic flaw.

When I try to select #FF0000 (for example) only using my mouse, the real trick is to select the topmost hue in the spectrum. I'd have to be 1px accurate with dragging the cursor. If I go over the spectrum while dragging and release mouse button, the dragging is still active. The numbers fly in my textbox even after I've closed the picker and wave my mouse around the textbox =P

This happens at least on FF3 and IE7

Comment by nils
posted Jul 16, 2008

Excellent tool, thanks guys!

I had an issue with Firefox3 refusing to change back from custom colour to static ones. After reading Jean Utts comment I applied it somewhat differently:

onChange="if(this.selectedIndex==this.length-1){cs11changeupdate();}else{this.style.backgroundColor=this.options[this.selectedIndex].value;}"

works like a charm now! :)

cheers!

nils

Comment by Honza Odvarko
posted Oct 19, 2009

Hi, great color picker! Try also this one, mine (-: Just another way to do the same thing...

http://jscolor.com - HSV color picker

Comment by fufu
posted Jun 19, 2010

what about a jquery version ...

Comment by prefabrik
posted Jul 03, 2010

Thanks you very much sir!..

Wonderful!..