You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

328 lines
11 KiB

  1. /**
  2. * Really Simple Color Picker in jQuery
  3. *
  4. * Licensed under the MIT (MIT-LICENSE.txt) licenses.
  5. *
  6. * Copyright (c) 2008-2012
  7. * Lakshan Perera (www.laktek.com) & Daniel Lacy (daniellacy.com)
  8. *
  9. * Permission is hereby granted, free of charge, to any person obtaining a copy
  10. * of this software and associated documentation files (the "Software"), to
  11. * deal in the Software without restriction, including without limitation the
  12. * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  13. * sell copies of the Software, and to permit persons to whom the Software is
  14. * furnished to do so, subject to the following conditions:
  15. *
  16. * The above copyright notice and this permission notice shall be included in
  17. * all copies or substantial portions of the Software.
  18. *
  19. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  24. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  25. * IN THE SOFTWARE.
  26. */
  27. (function ($) {
  28. /**
  29. * Create a couple private variables.
  30. **/
  31. var selectorOwner,
  32. activePalette,
  33. cItterate = 0,
  34. templates = {
  35. control : $('<div class="colorPicker-picker">&nbsp;</div>'),
  36. palette : $('<div id="colorPicker_palette" class="colorPicker-palette" />'),
  37. swatch : $('<div class="colorPicker-swatch">&nbsp;</div>'),
  38. hexLabel: $('<label for="colorPicker_hex">Hex</label>'),
  39. hexField: $('<input type="text" id="colorPicker_hex" />')
  40. },
  41. transparent = "transparent",
  42. lastColor;
  43. /**
  44. * Create our colorPicker function
  45. **/
  46. $.fn.colorPicker = function (options) {
  47. return this.each(function () {
  48. // Setup time. Clone new elements from our templates, set some IDs, make shortcuts, jazzercise.
  49. var element = $(this),
  50. opts = $.extend({}, $.fn.colorPicker.defaults, options),
  51. defaultColor = $.fn.colorPicker.toHex(
  52. (element.val().length > 0) ? element.val() : opts.pickerDefault
  53. ),
  54. newControl = templates.control.clone(),
  55. newPalette = templates.palette.clone().attr('id', 'colorPicker_palette-' + cItterate),
  56. newHexLabel = templates.hexLabel.clone(),
  57. newHexField = templates.hexField.clone(),
  58. paletteId = newPalette[0].id,
  59. swatch;
  60. /**
  61. * Build a color palette.
  62. **/
  63. $.each(opts.colors, function (i) {
  64. swatch = templates.swatch.clone();
  65. if (opts.colors[i] === transparent) {
  66. swatch.addClass(transparent).text('X');
  67. $.fn.colorPicker.bindPalette(newHexField, swatch, transparent);
  68. } else {
  69. swatch.css("background-color", "#" + this);
  70. $.fn.colorPicker.bindPalette(newHexField, swatch);
  71. }
  72. swatch.appendTo(newPalette);
  73. });
  74. newHexLabel.attr('for', 'colorPicker_hex-' + cItterate);
  75. newHexField.attr({
  76. 'id' : 'colorPicker_hex-' + cItterate,
  77. 'value' : defaultColor
  78. });
  79. newHexField.bind("keydown", function (event) {
  80. if (event.keyCode === 13) {
  81. var hexColor = $.fn.colorPicker.toHex($(this).val());
  82. $.fn.colorPicker.changeColor(hexColor ? hexColor : element.val());
  83. }
  84. if (event.keyCode === 27) {
  85. $.fn.colorPicker.hidePalette();
  86. }
  87. });
  88. newHexField.bind("keyup", function (event) {
  89. var hexColor = $.fn.colorPicker.toHex($(event.target).val());
  90. $.fn.colorPicker.previewColor(hexColor ? hexColor : element.val());
  91. });
  92. $('<div class="colorPicker_hexWrap" />').append(newHexLabel).appendTo(newPalette);
  93. newPalette.find('.colorPicker_hexWrap').append(newHexField);
  94. $("body").append(newPalette);
  95. newPalette.hide();
  96. /**
  97. * Build replacement interface for original color input.
  98. **/
  99. newControl.css("background-color", defaultColor);
  100. newControl.bind("click", function () {
  101. $.fn.colorPicker.togglePalette($('#' + paletteId), $(this));
  102. });
  103. if( options && options.onColorChange ) {
  104. newControl.data('onColorChange', options.onColorChange);
  105. } else {
  106. newControl.data('onColorChange', function() {} );
  107. }
  108. element.after(newControl);
  109. element.bind("change", function () {
  110. element.next(".colorPicker-picker").css(
  111. "background-color", $.fn.colorPicker.toHex($(this).val())
  112. );
  113. });
  114. // Hide the original input.
  115. element.val(defaultColor).hide();
  116. cItterate++;
  117. });
  118. };
  119. /**
  120. * Extend colorPicker with... all our functionality.
  121. **/
  122. $.extend(true, $.fn.colorPicker, {
  123. /**
  124. * Return a Hex color, convert an RGB value and return Hex, or return false.
  125. *
  126. * Inspired by http://code.google.com/p/jquery-color-utils
  127. **/
  128. toHex : function (color) {
  129. // If we have a standard or shorthand Hex color, return that value.
  130. if (color.match(/[0-9A-F]{6}|[0-9A-F]{3}$/i)) {
  131. return (color.charAt(0) === "#") ? color : ("#" + color);
  132. // Alternatively, check for RGB color, then convert and return it as Hex.
  133. } else if (color.match(/^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/)) {
  134. var c = ([parseInt(RegExp.$1, 10), parseInt(RegExp.$2, 10), parseInt(RegExp.$3, 10)]),
  135. pad = function (str) {
  136. if (str.length < 2) {
  137. for (var i = 0, len = 2 - str.length; i < len; i++) {
  138. str = '0' + str;
  139. }
  140. }
  141. return str;
  142. };
  143. if (c.length === 3) {
  144. var r = pad(c[0].toString(16)),
  145. g = pad(c[1].toString(16)),
  146. b = pad(c[2].toString(16));
  147. return '#' + r + g + b;
  148. }
  149. // Otherwise we wont do anything.
  150. } else {
  151. return false;
  152. }
  153. },
  154. /**
  155. * Check whether user clicked on the selector or owner.
  156. **/
  157. checkMouse : function (event, paletteId) {
  158. var selector = activePalette,
  159. selectorParent = $(event.target).parents("#" + selector.attr('id')).length;
  160. if (event.target === $(selector)[0] || event.target === selectorOwner[0] || selectorParent > 0) {
  161. return;
  162. }
  163. $.fn.colorPicker.hidePalette();
  164. },
  165. /**
  166. * Hide the color palette modal.
  167. **/
  168. hidePalette : function () {
  169. $(document).unbind("mousedown", $.fn.colorPicker.checkMouse);
  170. $('.colorPicker-palette').hide();
  171. },
  172. /**
  173. * Show the color palette modal.
  174. **/
  175. showPalette : function (palette) {
  176. var hexColor = selectorOwner.prev("input").val();
  177. palette.css({
  178. top: selectorOwner.offset().top + (selectorOwner.outerHeight()),
  179. left: selectorOwner.offset().left
  180. });
  181. $("#color_value").val(hexColor);
  182. palette.show();
  183. $(document).bind("mousedown", $.fn.colorPicker.checkMouse);
  184. },
  185. /**
  186. * Toggle visibility of the colorPicker palette.
  187. **/
  188. togglePalette : function (palette, origin) {
  189. // selectorOwner is the clicked .colorPicker-picker.
  190. if (origin) {
  191. selectorOwner = origin;
  192. }
  193. activePalette = palette;
  194. if (activePalette.is(':visible')) {
  195. $.fn.colorPicker.hidePalette();
  196. } else {
  197. $.fn.colorPicker.showPalette(palette);
  198. }
  199. },
  200. /**
  201. * Update the input with a newly selected color.
  202. **/
  203. changeColor : function (value) {
  204. selectorOwner.css("background-color", value);
  205. selectorOwner.prev("input").val(value).change();
  206. $.fn.colorPicker.hidePalette();
  207. selectorOwner.data('onColorChange').call(selectorOwner, $(selectorOwner).prev("input").attr("id"), value);
  208. },
  209. /**
  210. * Preview the input with a newly selected color.
  211. **/
  212. previewColor : function (value) {
  213. selectorOwner.css("background-color", value);
  214. },
  215. /**
  216. * Bind events to the color palette swatches.
  217. */
  218. bindPalette : function (paletteInput, element, color) {
  219. color = color ? color : $.fn.colorPicker.toHex(element.css("background-color"));
  220. element.bind({
  221. click : function (ev) {
  222. lastColor = color;
  223. $.fn.colorPicker.changeColor(color);
  224. },
  225. mouseover : function (ev) {
  226. lastColor = paletteInput.val();
  227. $(this).css("border-color", "#598FEF");
  228. paletteInput.val(color);
  229. $.fn.colorPicker.previewColor(color);
  230. },
  231. mouseout : function (ev) {
  232. $(this).css("border-color", "#000");
  233. paletteInput.val(selectorOwner.css("background-color"));
  234. paletteInput.val(lastColor);
  235. $.fn.colorPicker.previewColor(lastColor);
  236. }
  237. });
  238. }
  239. });
  240. /**
  241. * Default colorPicker options.
  242. *
  243. * These are publibly available for global modification using a setting such as:
  244. *
  245. * $.fn.colorPicker.defaults.colors = ['151337', '111111']
  246. *
  247. * They can also be applied on a per-bound element basis like so:
  248. *
  249. * $('#element1').colorPicker({pickerDefault: 'efefef', transparency: true});
  250. * $('#element2').colorPicker({pickerDefault: '333333', colors: ['333333', '111111']});
  251. *
  252. **/
  253. $.fn.colorPicker.defaults = {
  254. // colorPicker default selected color.
  255. pickerDefault : "FFFFFF",
  256. // Default color set.
  257. colors : [
  258. '000000', '993300', '333300', '000080', '333399', '333333', '800000', 'FF6600',
  259. '808000', '008000', '008080', '0000FF', '666699', '808080', 'FF0000', 'FF9900',
  260. '99CC00', '339966', '33CCCC', '3366FF', '800080', '999999', 'FF00FF', 'FFCC00',
  261. 'FFFF00', '00FF00', '00FFFF', '00CCFF', '993366', 'C0C0C0', 'FF99CC', 'FFCC99',
  262. 'FFFF99', 'CCFFFF', '99CCFF', 'FFFFFF'
  263. ],
  264. // If we want to simply add more colors to the default set, use addColors.
  265. addColors : []
  266. };
  267. })(jQuery);