Index: colorpicker.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/colorpicker/colorpicker.module,v
retrieving revision 1.2
diff -u -p -r1.2 colorpicker.module
--- colorpicker.module	4 Nov 2007 02:31:20 -0000	1.2
+++ colorpicker.module	9 Dec 2008 10:05:04 -0000
@@ -1,99 +1,73 @@
 <?php
+// $Id: colorpicker.module,v 0.9 2008/30/09 10:38:00 dwees, skilip Exp $
 
-// $Id$
+/**
+ * @file
+ * This module creates a new form element called a 'colorpicker_textfield'.
+ *
+ * TODO: If a colorpicker is at the bottom of a fieldset, the CSS property overflow:auto causes problems
+ *
+ * ADDED: Validation passes if the value is #
+ *        The classname is added in the theme function instead of in hook_elements.
+ */
 
 /*
- * Implementation of hook_elements
+ * Implementation of hook_elements().
  */
 function colorpicker_elements() {
-  // the Farbtastic colorpicker
-  $type['colorpicker'] = array('#attributes' => array('class' => 'colorpicker'), '#input' => TRUE);
-  
-  // a textfield to associate with the Farbtastic colorpicker
+  // A textfield to associate with the Farbtastic colorpicker
   $type['colorpicker_textfield'] = array(
-    '#attributes' => array('class' => 'colorpicker_textfield'), 
-	'#input' => TRUE,
-	'#validate' => array('colorpicker_validate_hex_color' => array())
+    '#input' => TRUE,
+    '#validate' => array('colorpicker_validate_hex_color' => array())
   );
   return $type;
 }
 
 /**
- * Format our colorpicker.
+ * Format our colorpicker textfield.
  *
  * @param $element
  *   An associative array containing the properties of the element.
- *   Properties used:  title, description, attributes, id
- *   Note that if no #id is provided, every colorpicker_textfield will be linked to the same colorpicker
+ *   Properties used:  title, value, description, required, attributes
  * @return
- *   A themed HTML string that represents the placeholder for the Farbtastic colorpicker.
+ *   A themed HTML string representing the textfield.
  */
-function theme_colorpicker($element) {
+function theme_colorpicker_textfield($element) {
   $path = drupal_get_path('module', 'colorpicker');
 
   // Add Farbtastic color picker
   drupal_add_css('misc/farbtastic/farbtastic.css');
   drupal_add_js('misc/farbtastic/farbtastic.js');
-	
-  // Add our custom js and css for our colorpicker
-  drupal_add_js($path . '/js/colorpicker.js');
-  drupal_add_css($path . '/css/colorpicker.css');
-	
-  $size = $element['#size'] ? ' size="' . $element['#size'] . '"' : '';
 
-  $output = '';
+  // Add our custom js and css for our colorpicker
+  drupal_add_js("$path/js/colorpicker.js");
+  drupal_add_css("$path/css/colorpicker.css");
 
   if (isset($element['#field_prefix'])) {
-    $output .= '<span class="field-prefix">'. $element['#field_prefix'] .'</span> ';
+    $output[] = '<span class="field-prefix">'. $element['#field_prefix'] .'</span> ';
   }
 
-  $output .= '<div class="colorpicker" id="'. $element['#id'] .'" '. drupal_attributes($element['#attributes']) .' ></div>';
+  // Add the required classname to the input element
+  $element['#attributes']['class'] .= ' colorpicker_textfield';
 
-  if (isset($element['#field_suffix'])) {
-    $output .= ' <span class="field-suffix">'. $element['#field_suffix'] .'</span>';
-  }
-
-  return theme('form_element', $element, $output);
-}
-
-/**
- * Format our colorpicker textfield.
- *
- * @param $element
- *   An associative array containing the properties of the element.
- *   Properties used:  title, value, description, size, maxlength, required, attributes
- * @return
- *   A themed HTML string representing the textfield.
- */
-function theme_colorpicker_textfield($element) {
-  $path = drupal_get_path('module', 'colorpicker');
-	
-  $size = $element['#size'] ? ' size="' . $element['#size'] . '"' : '';
-
-  $output = '';
-
-  if (isset($element['#colorpicker'])) {
-    $element['#attributes']['class'] .= ' edit-'. str_replace("_", "-", $element['#colorpicker']);
-  }
-
-  if (isset($element['#field_prefix'])) {
-    $output .= '<span class="field-prefix">'. $element['#field_prefix'] .'</span> ';
-  }
-
-  $output .= '<input type="text" maxlength="'. $element['#maxlength'] .'" name="'. $element['#name'] .'" id="'. $element['#id'] .'" '. $size .' value="'. check_plain($element['#value']) .'"'. drupal_attributes($element['#attributes']) .' />';
+  $output[] = '<input type="text" name="'. $element['#name'] .'" id="'. $element['#id'] .'" maxlength="7" size="7" value="'. check_plain($element['#value']) .'"'. drupal_attributes($element['#attributes']) .' />';
 
   if (isset($element['#field_suffix'])) {
-    $output .= ' <span class="field-suffix">'. $element['#field_suffix'] .'</span>';
+    $output[] = ' <span class="field-suffix colorpicker">'. $element['#field_suffix'] .'</span>';
   }
 
-  return theme('form_element', $element, $output);
+  // Add a wrapper div. Only when if Javascript is enabled, a button is added inside this wrapper.
+  // If the button is clicked, the colorpicker will be added to this wrapper too.
+  $output[] = '<div class="picker_wrapper"></div>';
+
+  return theme('form_element', $element, join("\n", $output));
 }
 
 /**
  *  Check to make sure the user has entered a valid 6 digit hex color.
  */
 function colorpicker_validate_hex_color($element) {
-  if (!preg_match('/^#(?:(?:[a-f\d]{3}){1,2})$/i', $element['#value'])) {
+  if ($element['#value'] !== '#' && !preg_match('/^#(?:(?:[a-f\d]{3}){1,2})$/i', $element['#value'])) {
     form_error($element, "'". check_plain($element['#value']) ."'". t(' is not a valid hex color'));
   }
-}
\ No newline at end of file
+}
Index: js/colorpicker.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/colorpicker/js/colorpicker.js,v
retrieving revision 1.3
diff -u -p -r1.3 colorpicker.js
--- js/colorpicker.js	4 Nov 2007 04:50:20 -0000	1.3
+++ js/colorpicker.js	9 Dec 2008 10:05:04 -0000
@@ -1,50 +1,89 @@
-// $Id$
+// $Id: swfupload.info, v 0.1, 2008/10/13 10:02:46, dwees, skilip Exp $
 
-/*
- *  Bind the colorpicker event to the form element
- */
-$(document).ready(function () {
-
-  // do we have multiple colorpickers?
-  if ($("div.colorpicker").size() > 1) {
-  
-    // loop over each colorpicker type
-    $("div.colorpicker").each(function() {
-
-      // create the farbtastic colorpicker
-    var farb = $.farbtastic(this);
-    
-    // get the id of the current matched colorpicker wrapper div
-    var id = $(this).attr("id");
+$(function () {
 
-    // get the colorpicker_textfields associated with this colorpicker
-    $("input.colorpicker_textfield").filter("." + id).each(function () {
-      // set the background colors of all of the textfields appropriately
-       farb.linkTo(this);
-    
-      // when clicked, they get linked to the farbtastic colorpicker that they are associated with
-      $(this).click(function () {
-        farb.linkTo(this);
-      });
+  // loop over each colorpicker_textfield type
+  $("input.colorpicker_textfield").each(function() {
+    // get the id of the current matched colorpicker wrapper div
+    var input = $(this);
 
+    // Add an opener button directly after the input field
+    var border = $('<div />').addClass('picker_border').appendTo(input.parent().find('.picker_wrapper'));
+    var button = $('<div />').addClass('picker_button').appendTo(border);
+
+    // Add a wrapper for the Farbtastic colorpicker
+    var wrapper = $('<div />').addClass('colorwrapper').appendTo(border);
+
+    // create the farbtastic colorpicker
+    var farb = $.farbtastic(wrapper);
+    farb.linkTo(input);
+
+    // Add a close button for the wrapper of the colorpicker
+    var close_button = $('<div />').addClass('close_button').appendTo(wrapper);
+
+    // Attach the event handlers
+    button.click(function() {
+      // Hide all colorwrappers and show the clicked one
+      $('.colorwrapper').hide();
+      wrapper.show();
     });
-
+    input.focus(function() {
+      // Hide all colorwrappers and show the focussed one
+      $('.colorwrapper').hide();
+      wrapper.show();
+    }).blur(function() {
+      // Hide all colorwrappers
+      $('.colorwrapper').hide();
+    }).keyup(function() {
+      if($(this).val().indexOf('#') !== 0) {
+        $(this).val('#' + $(this).val());
+      };
+    }).keydown(function(e) {
+      var key = e.charCode || e.keyCode || -1;
+      if (key == 27) { // ESC
+        $(this).blur();
+      }
+      else {
+        return validHexKey(key);
+      };
+    });
+    close_button.click(function() {
+      // Hide all colorwrappers
+      $('.colorwrapper').hide();
     });
-  }
-  else {
-    // we do this differently because we don't care about the id
-  var farb = $.farbtastic("div.colorpicker");
-    $("input.colorpicker_textfield").each(function () {
-      // set the background colors of all of the textfields appropriately
-      farb.linkTo(this);
-
-      // update the farbtastic colorpicker when this textfield is clicked
-      $(this).click(function () {
-        farb.linkTo(this);
-      });
-
-    
   });
-  }
 });
 
+/*
+ * Checks wheiter a given key is a valid hex character 
+ *
+ * @param e Object The keypress event's object
+ * @return Boolean true if the key is a valid hex character, false if it isn't
+ **/
+validHexKey = function(e) {
+  var key = (typeof(e) == 'object') ? e.charCode || e.keyCode || -1 : e;
+  var valid_keys = [
+    48, // 0
+    49, // 1
+    50, // 2
+    51, // 3
+    52, // 4
+    53, // 5
+    54, // 6
+    55, // 7
+    56, // 8
+    57, // 9
+    65, // A
+    66, // B
+    67, // C
+    68, // D
+    69, // E
+    70, // F
+    8, // BACKSPACE
+    9, // TAB
+    27, // ESC
+    37, // ARROW LEFT
+    39 // ARROW RIGHT
+  ];
+  return ($.inArray(key, valid_keys) > -1);
+};
