Karl Karl - 7 months ago 116
Javascript Question

jquery color picker Spectrum not working on Internet explorer

I am using Spectrum as a jquery plugin for the color picker to use it in the contenteditable divs. In chrome and firefox its working perfectly. But in Internet explorer its just showing the color palettes but when I select nothing is changed.

However, if I exectute

execCommand
directly in this way it is working:

$('#btn-color_font').click(function() {
document.execCommand('foreColor', false, "#ff0000");
});


What am I doing wrong? Please help me how to use it in IE too. Thank you.

jsfiddle

snippet html:

<li class="main-btn">
<a href="#" id="btn-color_font" class="wysiwyg-color-spectrum-cF">cF</a>
</li>
<li class="main-btn" >
<a href="#" id="btn-color_background" class="wysiwyg-color-spectrum-bF">cB</a>
</li>


snippet js:

$(".wysiwyg-color-spectrum-cF").spectrum({
showPaletteOnly: true,
togglePaletteOnly: true,
togglePaletteMoreText: 'more',
togglePaletteLessText: 'less',
color: 'blanchedalmond',
change: function (color) {
document.execCommand('foreColor', false, color.toHexString());
},
hideAfterPaletteSelect: true,
palette: [
["#000", "#444", "#666", "#999", "#ccc", "#eee", "#f3f3f3", "#fff"],
["#f00", "#f90", "#ff0", "#0f0", "#0ff", "#00f", "#90f", "#f0f"],
["#f4cccc", "#fce5cd", "#fff2cc", "#d9ead3", "#d0e0e3", "#cfe2f3", "#d9d2e9", "#ead1dc"],
["#ea9999", "#f9cb9c", "#ffe599", "#b6d7a8", "#a2c4c9", "#9fc5e8", "#b4a7d6", "#d5a6bd"],
["#e06666", "#f6b26b", "#ffd966", "#93c47d", "#76a5af", "#6fa8dc", "#8e7cc3", "#c27ba0"],
["#c00", "#e69138", "#f1c232", "#6aa84f", "#45818e", "#3d85c6", "#674ea7", "#a64d79"],
["#900", "#b45f06", "#bf9000", "#38761d", "#134f5c", "#0b5394", "#351c75", "#741b47"],
["#600", "#783f04", "#7f6000", "#274e13", "#0c343d", "#073763", "#20124d", "#4c1130"]
]
});

Answer

The problem here is that IE is losing the focus/selection before you click in the color, and that's why it's not working. It triggers the change event, but since there is nothing selected, nothing happens.

As a workaround, you must save the selection when the Spectrum buttons are clicked, and then restore that selection when the change event of Spectrum is triggered.

Something like that:

var WinSelection = (function(w, d) {
  var currentSelection = null; // create a variable to save the current selection

  function saveSelection() { // saveSelection copied from another SO answer
    if (w.getSelection) {
      sel = w.getSelection();
      if (sel.getRangeAt && sel.rangeCount) {
        return sel.getRangeAt(0);
      }
    } else if (d.selection && d.selection.createRange) {
      return d.selection.createRange();
    }
    return null;
  }

  function restoreSelection(range) { // restoreSelection copied from another SO answer
    if (range) {
      if (w.getSelection) {
        sel = w.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
      } else if (d.selection && range.select) {
        range.select();
      }
    }
  }

  return { // return an object with two public methods: saveSelection and restoreSelection
    saveSelection: function() {
      currentSelection = saveSelection();
    },
    restoreSelection: function() {
      restoreSelection(currentSelection);
    }
  };
})(window, document);

Then, in your code, you can save the selection when the buttons are clicked:

$('#wysiwyg-editor li a').click(function() {
  WinSelection.saveSelection();
});

And inside your change event, you restore the selection:

/* ... */
change: function (color) {
  WinSelection.restoreSelection();
  document.execCommand('foreColor', false, color.toHexString());
},
/* ... */
change: function (color) {
  WinSelection.restoreSelection();
  document.execCommand("BackColor", false, color.toHexString());
},
/* ... */

And here is your fiddle - updated, and working in IE.