1 /** 2 * SlickGrid color editor and formatter. 3 * 4 * @module SlickGridColors 5 */ 6 define([ 7 'jquery', 8 'underscore', 9 'view', 10 'viewcontroller', 11 'spectrum' 12 ], 13 function($, _, DecompositionView, ViewControllers, spectrum) { 14 15 /** 16 * 17 * @class ColorEditor 18 * 19 * This class represents a color editor defined by the SlickGrid 20 * project. 21 * 22 * Note, this object is heavily based on classes in slick.editors.js and in 23 * the documentation that can be found [here](https://github.com/mleibman/ 24 * SlickGrid/wiki/Writing-custom-cell-editors). 25 * 26 * Also see ColorFormatter, a function in charge of formatting colors for the 27 * SlickGrid object. 28 * 29 * @param {object} args Arguments passed by SlickGrid. 30 * 31 * @constructs ColorEditor 32 * @alias module:SlickGridColors.ColorEditor 33 * 34 */ 35 function ColorEditor(args) { 36 var $input = $("<div class='colorbox'></div>"); 37 var defaultValue; 38 var scope = this; 39 40 this.init = function() { 41 // make the background look exactly the same when the color is being 42 // edited 43 $(args.container).css('background-color', '#eeeeee'); 44 $input.appendTo($(args.container)); 45 $input.css('background-color', args.item.value); 46 47 // initialize spectrum 48 $input.spectrum({ 49 color: args.item.color, 50 showInput: true, 51 allowEmpty: false, 52 showInitial: true, 53 clickoutFiresChange: true, 54 className: 'full-spectrum', 55 preferredFormat: 'hex6', 56 // Show the whole set of color palette on the menu (only discrete) 57 showPalette: args.grid.selectionPalette !== undefined, 58 showSelectionPalette: args.grid.selectionPalette !== undefined, 59 palette: args.grid.selectionPalette, 60 61 62 /* On change callback */ 63 change: function(color) { 64 $input.css('background-color', color.toHexString()); 65 66 // commit the changes as soon as a new shape is selected 67 // https://stackoverflow.com/a/35768360/379593 68 args.grid.getEditorLock().commitCurrentEdit(); 69 args.grid.resetActiveCell(); 70 } 71 }); 72 73 // Don't propagate the keydown and keypress events so that inputing a 74 // color doesn't interfere with the shortcuts of the Jupyter Notebook 75 $input 76 .spectrum('container') 77 .find('.sp-input') 78 .on('keydown keypress', function(e) { 79 e.stopPropagation(); 80 }); 81 }; 82 83 this.destroy = function() { 84 $input.spectrum('hide'); 85 $input.spectrum('destroy'); 86 $input.remove(); 87 }; 88 89 this.focus = function() { 90 $input.focus(); 91 $input.spectrum('show'); 92 }; 93 94 this.isValueChanged = function() { 95 return $input.spectrum('get').toHexString() !== defaultValue; 96 }; 97 98 this.serializeValue = function() { 99 return $input.spectrum('get').toHexString(); 100 }; 101 102 this.loadValue = function(item) { 103 defaultValue = item[args.column.field]; 104 $input.spectrum('set', defaultValue); 105 }; 106 107 this.applyValue = function(item, state) { 108 item[args.column.field] = state; 109 }; 110 111 this.validate = function() { 112 return {valid: true, msg: null}; 113 }; 114 115 this.hide = function() { 116 $input.spectrum('hide'); 117 }; 118 119 this.show = function() { 120 /* 121 * 122 * We setup a brief timeout that gives the browser enough time to finish 123 * preparing the specturm widget. If we don't wait for 100 milliseconds, 124 * opening the color picker will take two clicks. This is also a 125 * consequence of spectrum initializing asynchronously, by the time 126 * SlickGrid executes the show method the widget is not ready yet so the 127 * 'spectrum('show')' call results in a noop, and in order to show the 128 * color picker users would need to click again on the colorbox. 129 * 130 */ 131 setTimeout(function() { 132 $input.spectrum('show'); 133 }, 100); 134 }; 135 136 this.position = function(cellBox) { 137 $input.spectrum('reflow'); 138 }; 139 140 this.init(); 141 } 142 143 /** 144 * 145 * Function to format colors for the SlickGrid object. 146 * 147 * This formatter is heavily based in the examples found in 148 * slick.formattters.js and is only intended to be used with ColorFormatter. 149 * 150 * @param {integer} row SlickGrid row. 151 * @param {integer} cell SlickGrid cell. 152 * @param {integer|string|bool} value The value in the row. 153 * @param {object} columnDef SlickGrid column definition. 154 * @param {object} dataContext Data model of the SlickGrid object. 155 * 156 * @return {string} String with a div where the background color is set as 157 * the value that's passed in. 158 * 159 * @alias module:SlickGridColors.ColorFormatter 160 * 161 */ 162 function ColorFormatter(row, cell, value, columnDef, dataContext) { 163 return "<div class='colorbox' style='cursor:pointer;background-color:" + 164 value + ";'></div>"; 165 } 166 167 return {'ColorEditor': ColorEditor, 'ColorFormatter': ColorFormatter}; 168 }); 169