I'm using the colorpicker module, which uses Farbtastic, and I need to attach actions on the user land when the color value changes. Actually, the colorpicker widget needs to update not only the textfield, but also a DOM object (it is a panel where users customize the look of a page, where they actually see the changes in real time, at least that's what I'm trying to do). But... when Farbtastic changes the value of the textfield no other event is invoked. I hope this explanation makes sense ti somone...

I believe the best solution would to trigger onchange event from inside Farbtastic's updateDisplay method. That is, if the callback is an object, then use jQuery trigger method to invoke onchange event of that DOM object.

The code of the updateDisplay method would look somthing like:

  fb.updateDisplay = function () {
    // Markers
    var angle = fb.hsl[0] * 6.28;
    $('.h-marker', e).css({
      left: Math.round(Math.sin(angle) * fb.radius + fb.width / 2) + 'px',
      top: Math.round(-Math.cos(angle) * fb.radius + fb.width / 2) + 'px'
    });

    $('.sl-marker', e).css({
      left: Math.round(fb.square * (.5 - fb.hsl[1]) + fb.width / 2) + 'px',
      top: Math.round(fb.square * (.5 - fb.hsl[2]) + fb.width / 2) + 'px'
    });

    // Saturation/Luminance gradient
    $('.color', e).css('backgroundColor', fb.pack(fb.HSLToRGB([fb.hsl[0], 1, 0.5])));

    // Linked elements or callback
    if (typeof fb.callback == 'object') {
      // Set background/foreground color
      $(fb.callback).css({
        backgroundColor: fb.color,
        color: fb.hsl[2] > 0.5 ? '#000' : '#fff'
      });

      // Change linked value
      $(fb.callback).each(function() {
        if (this.value && this.value != fb.color) {
          this.value = fb.color;
        }
      });
      $(fb.callback).trigger('change'); // <---  This line is what could solve the issue.
    }
    else if (typeof fb.callback == 'function') {
      fb.callback.call(fb, fb.color);
    }
  }
CommentFileSizeAuthor
#4 farbtastic.js_.patch314 bytesmarkus_petrux
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

markus_petrux’s picture

Sorry, I made a mistake. That line ought to be added with the each() loop:

      // Change linked value
      $(fb.callback).each(function() {
        if (this.value && this.value != fb.color) {
          this.value = fb.color;
          $(this).trigger('change'); // <---  Please, correct me if I'm wrong.
        }
      });
Pancho’s picture

Version: 6.x-dev » 7.x-dev
Component: javascript » color.module

Guess, that won't happen before D7. :(

skilip’s picture

Nice one!! Worked out very well for me!

markus_petrux’s picture

Status: Active » Needs review
FileSize
314 bytes

Here's the patch.

Please, apply also to DRUPAL-6. It's just a line that probably causes no harm, and it would make things easier for those using D6, if/when a new package is released.

mfer’s picture

Status: Needs review » Closed (works as designed)

farbtastic allows you to set a callback function that is called when the color is changed. Taking advantage of the callback function would the be farbtastic way to do this. When the color is changed your callback function would be called. Have your callback function grab the color and make the needed updates to the DOM.

You can see twitter (non-drupal site) doing that right now.

If you still want this change in core it's a functionality change and won't go in until drupal 7.

markus_petrux’s picture

farbtastic allows you to set a callback function that is called when the color is changed.

Adds complexity to the implementation.

If you still want this change in core it's a functionality change and won't go in until drupal 7.

Fine for me. But perhaps, it could eventually goto to D6 as well, so it's present for new releases? maybe? :)

"functionality change" would apply if the element attached to the colorpicker had an onchange event implemented, which may not be the case because someone who had tried it would have noticed his event was not invoked when colorpicker was changing the value of its attached element. That's why I think it can cause no harm.

Scheepers de Bruin’s picture

This works for me:

var picker = $('#mypicker')
var colorInput = $('#mytextbox');
$.farbtastic(picker).
  linkTo(
    function(color){
      colorInput.
        css({ backgroundColor: color, color: (this.hsl[2] > 0.5 ? '#000' : '#fff') }).
        val(color).
        change();
    }
  ).setColor(colorInput.val());

  colorInput.keyup(
    function(){
      picker.setColor(colorInput.val());
    }
  );