3
votes

I'd like to have the colour selected from a Primefaces ColourPicker sent to my backend on change.

This seems not to be supported though.

  <p:colorPicker value="#{colorView.colorPopup}" />

I can see it will submit the value when the page is submitted.

  <p:colorPicker value="#{colorView.colorPopup}" />
  <p:commandButton value="Submit" oncomplete="PF('dlg').show();" update="grid" />

Even some Javascript being called on change would be great.


Update:

I would like the backing bean to updated on colour change, not just when I submit the form.

The main reason for this is that I have several colourpickers on the page and the form is submitted I don't know which value is from which colour picker.

3
Do you want to perform some actions besides setting the colorPopup value? Or is it that you have tested this and believe that the value is not updated before a non-ajax submit ?yannicuLar

3 Answers

6
votes

Having an ajax call onChange of the colorPicker is a bad idea, you might end up with 100 queued ajax calls as the user is picking the color by dragging the selector in the color palette.

Therefor onHide would serve better in that case, I'll demonstrate the two events implementations and I do recommend the onHide

onChange

var oldOnChange = PF('colorPickerWV').cfg.onChange;
$(document.body).children('.ui-colorpicker-container').data('colorpicker').onChange =
function(b,d,c) {
   oldOnChange.apply(this, [b,d,c]);
   console.log('valueChanged:should be remoteCommand with process of the colorPicker');
 };

onHide

var oldOnHide = PF('colorPickerWV').cfg.onHide;
$(document.body).children('.ui-colorpicker-container').data('colorpicker').onHide = 
   function(b) {
      oldOnHide.apply(this, [b]);
      console.log('Panel is hidden: should be remoteCommand with process of the colorPicker');
};

colorPickerWV is the widgetVar name

And here's the this object

enter image description here

1
votes

You can use the onChange eventhandler and by adding a timeout that is reset on each 'change' and that only fires after x miliseconds of no change (250 in this case), it works perfectly. Keep in mind that I used the widgetVar value of the component here to, to have it work on specific ColorPickers in your page, not automagically all of them.

var oldonChange = PF(widgetVar).cfg.onChange;
$(document.body).children('.ui-colorpicker-container').each(
    function(i, element) {
        var overlay = $(element), options = overlay.data('colorpicker');
        if (options.id == PF(widgetVar).id) {
            _self = PF(widgetVar);
            options.onChange = function(a, b, c) {
                oldonChange.apply(_self, [a, b, c ]);
                clearTimeout(_self.submitTimer);
                _self.submitTimer = setTimeout(function() {
                    console
                       .log('Data is changed: should be remoteCommand with process of the colorPicker')
                    //The call below is what the name of the remote command is
                    //window[widgetVar+"_change"]();

                }, 250);
            }
        }
    }
)
1
votes

If you have several colorpickers you can do it like this:

document.body.onload = function() {
    $(".ui-colorpicker-container").each(function() {
        $(this).data('colorpicker').onHide = 
            function() {
                updateMiniPreview();
            }
        })      
};

The "updateMiniPreview" function is a p:remoteCommand which updates the target area:

<p:remoteCommand update="miniPreview" name="updateMiniPreview" />