PDA

View Full Version : Ext.ux.form.ColorPickerFieldPlus



garraS
14 Apr 2009, 6:03 PM
Ext.ux.form.ColorPickerFieldPlus

This class makes Ext.ux.ColorPicker and Ext.ux.form.ColorPickerField (http://extjs.com/forum/showthread.php?t=5106) available as a form field.

Licence: IYUIYBMAC (If you use it, you buy me a Coke!)

DEMO (http://extjs.grupovrs.com/ux/ColorPickerPlus/)

SVN Link (http://code.google.com/p/ext-ux-form-colorpickerfieldplus/)

See Ext.ux.MultiColorPicker (http://extjs.com/forum/showthread.php?t=65538) too.

Tested in:
Firefox 3.0.8
Internet Explorer 7.0.x
Chrome 1.0.x
Safari 4.x
Opera 9.64CHANGELOG (dd/mm/yy):
22/04/09 - Fixed manually type color function.
17/04/09 - Added reset function.

stever
14 Apr 2009, 8:24 PM
Hey, that looks nice! I have a similar one, but I like your other color picker better than the one I'm using. I think I'll try and mix yours in and publish it. Will send you a beer (or coke) if I do!

galdaka
15 Apr 2009, 2:39 AM
Hi,

Buen trabajo Garras!!. ;)

One thing: In a form the selected color is not assign to a field.

In my opinion:

1) "Accept" button is missing.

2) I would use the standar css for slider and others. This reduce the size of the ux and will make posible include / best adapt your ux in future revisions of Ext.

Greeintgs,

Bucs
15 Apr 2009, 11:25 AM
I just had a need for this today and looked here and saw that it was just posted! Works great thanks a ton!

One question though...under a normal form.reset(), the background color of the color-picker-field-plus does not reset itself to white like it was before the field was populated. The field hex value is cleared but the color remains the same. Anyway you can make this work? Or, is there an API to the component that I could use to clear the background color?

And I have one suggestion...I would not change the color of the "Pick Color" button to the selected color. I would keep as a gray button as it gets a little hard to see it when you're choosing colors sometimes.

Great job though on the control...works exactly as I wanted it to :)

Bucs
15 Apr 2009, 12:06 PM
I guess a workaround for now is to simply use the mycolorpicker.setValue('ffffff') right before calling the form.reset(). This works but you do see a flash of the hex value appear in the field before clearing.

But works for now...:)

garraS
16 Apr 2009, 9:09 PM
Solved!

I've edited the first post.

extuser007
22 Apr 2009, 12:53 AM
Hi garraS!

Good work.

When i manually edit color value, field background stay unchanged (FF3 for example in my case).

Here is my workaround :


initComponent : function(){
Ext.ux.form.ColorPickerFieldPlus.superclass.initComponent.call(this);
this.menu1 = new Ext.menu.ColorMenu();
this.menu2 = new Ext.ux.menu.ColorMenu();
this.on('valid', function(){
var v = this.getValue();
var i = this.menu2.picker.rgbToHex(
this.menu2.picker.invert(this.menu2.picker.hexToRgb(v)));
if (v && i) { //fix: IE7 issue
this.el.applyStyles('background: #'+v+'; color: #'+i+';');
}
}, this);
},

Remove onBlur in Ext.ux.form.ColorPickerFieldPlus object


// onBlur : function(){
// Ext.ux.form.ColorPickerFieldPlus.superclass.onBlur.call(this);
// var v = this.getValue();
// var i = this.menu2.picker.rgbToHex(this.menu2.picker.invert(this.menu2.picker.hexToRgb(v)));
// this.el.applyStyles('background: #'+v+'; color: #'+i+';');
// },

three_uncle
22 Apr 2009, 2:26 AM
Need to purchase the right to use?

garraS
22 Apr 2009, 5:07 AM
Hi garraS!

Good work.

When i manually edit color value, field background stay unchanged (FF3 for example in my case).

Here is my workaround :


initComponent : function(){
Ext.ux.form.ColorPickerFieldPlus.superclass.initComponent.call(this);
this.menu1 = new Ext.menu.ColorMenu();
this.menu2 = new Ext.ux.menu.ColorMenu();
this.on('valid', function(){
var v = this.getValue();
var i = this.menu2.picker.rgbToHex(
this.menu2.picker.invert(this.menu2.picker.hexToRgb(v)));
this.el.applyStyles('background: #'+v+'; color: #'+i+';');
}, this);
},
Remove onBlur in Ext.ux.form.ColorPickerFieldPlus object


// onBlur : function(){
// Ext.ux.form.ColorPickerFieldPlus.superclass.onBlur.call(this);
// var v = this.getValue();
// var i = this.menu2.picker.rgbToHex(this.menu2.picker.invert(this.menu2.picker.hexToRgb(v)));
// this.el.applyStyles('background: #'+v+'; color: #'+i+';');
// },


Nice! I've added to the first post. Thanks!



Need to purchase the right to use?

Like I said in my first post, "If you use it, you buy me a Coke!". ;):))
You don't need to purchese, but if you want, you can donate (look DEMO link).

three_uncle
23 Apr 2009, 4:36 PM
very thanks your Plugins. if you come to china. I ask you a cup of coffee and beer.
Sorry, English is not very good.

garraS
24 Apr 2009, 5:19 AM
very thanks your Plugins. if you come to china. I ask you a cup of coffee and beer.
Sorry, English is not very good.
Thanks! :D

extuser007
14 May 2009, 7:13 AM
Hi garraS!

When i select color from menu, there is no 'change' event fired. To fire this event, i modify menu1Listeners and menu2Listeners methods:


menu1Listeners : {
select: function(m, c){
var v0 = this.getValue();
this.setValue(c);
var v1 = this.getValue();
if (v1 !== v0) {
this.fireEvent('change', this, v1, v0);
}
this.focus.defer(10, this);
},
show : function(m){ // retain focus styling
this.onFocus();
},
hide : function(){
this.focus.defer(10, this);
var ml = this.menu1Listeners;
this.menu1.un("select", ml.select, this);
this.menu1.un("show", ml.show, this);
this.menu1.un("hide", ml.hide, this);
}
},
menu2Listeners : {
select: function(m, c){
var v0 = this.getValue();
this.setValue(c);
var v1 = this.getValue();
if (v1 !== v0) {
this.fireEvent('change', this, v1, v0);
}
this.focus.defer(10, this);
},
show : function(m){ // retain focus styling
this.onFocus();
},
hide : function(){
this.focus.defer(10, this);
var ml = this.menu2Listeners;
this.menu2.un("select", ml.select, this);
this.menu2.un("show", ml.show, this);
this.menu2.un("hide", ml.hide, this);
}
},

garraS
14 May 2009, 7:53 AM
Good point. ;)

jarril
15 May 2009, 8:35 AM
I have modifyed Ext.ux.form.ColorPicker.js and Ext.ux.form.ColorPickerPlus.js for Ext 3

I also added localization (only 3 labels !).


Hope it will help you when migrating to 3.0

garraS
15 May 2009, 8:37 AM
Thanks! :)

Bucs
21 May 2009, 6:26 AM
Hello...so you have tested this in IE 7? The control works great in FF when calling a form.load() method on a from that has a field of type xtype: 'colorpickerfieldplus'. I am passing the hex text value from the server to the control, or rather the form.load method is doing this behind the scenes. However, it does not work in IE 7...I get the following error using ext-alll-debug.js

"Function Expected"

Error is on the following line (number 27645 in the ext code)



if(this.vtype){
var vt = Ext.form.VTypes;
if(!vt[this.vtype](value, this)){
this.markInvalid(this.vtypeText || vt[this.vtype +'Text']);
return false;
}
}
Am I doing something wrong in my field definition when placing the control in my code? Here is all that I am doing:


, {
id: 'surg_cp_Color'
, name: 'Color'
, width: 100
, xtype: 'colorpickerfieldplus'
, fieldLabel: 'Surgeon Color'
, allowBlank: true

}
Do I have to specify a vtype? If so why only in IE and not FF

This is the last bug in my app before I can launch it, so any help is GREATLY appreciated! :)

Bucs
21 May 2009, 9:49 AM
That was it, I have to add a vtype to allow form.load to work under IE. Also, you apparently cannot pass a null value to the control in IE, whereas FF handles that just fine.

Strange that no one else is encountering these issues with the control?

Oh well...

Bucs
21 May 2009, 10:48 AM
Well, what the above did was fix the issue temporarily with getting the thing to work in IE 7. Then I realized there was still an issue when the form.reset was being called on a form with the ColorPickeFieldrPlus on it. So I looked at the updates and saw that a reset() function was added, so I downloaded and installed the new version of the code.

Now back to square one where the CPFP does not work at all in IE 7. Are we sure this latest version was tested in IE 7? Cannot get it to work at all, which sux :(

Bucs
21 May 2009, 12:08 PM
Ok, I have verified that the code added by extuser007 in post #7 does in fact break compatibility of the control with IE 7. Please check this out when you get a chance as I really like the control but cannot use it given that is does not work across browsers. Works fine in FF.

I went back to the ealier version of the control to get it to work for now but still have to use the vtype in the field config to get it to work.

I and do not think the reset function is working in IE either.

Also, did not see a post that the CSS name changed from ColorPicker.css to ColorPickerFieldPlus CSS in the lates download.

And finally, there are references to add.gif and remove.gif in the CSS, however these icons do not exist in the images directory. Not sure what that will do to the control.

Hope you have time soon to look into these issues as I need to launch this site soon :)

Thanks.

extuser007
22 May 2009, 4:57 AM
Hi Bucs,
i test my latest version of control and find, that it works fine in IE7(IE8 compatibility mode), IE8 and FF. Problem as i understand related to vtypes, to fix it, replace code in file Ext.ux.form.ColorPickerFieldPlus

Ext.form.VTypes["hex"] = /^#?([a-f]|[A-F]|[0-9]){3}(([a-f]|[A-F]|[0-9]){3})?$/; on


Ext.form.VTypes["hex"] = function(v){ return /^#?([a-f]|[A-F]|[0-9]){3}(([a-f]|[A-F]|[0-9]){3})?$/.test(v); };

Bucs
22 May 2009, 5:12 AM
Thanks for the reply.

So I take it that this code change is to be applied to the latest version that is in the ColorPickerFieldPlus thread? I will try to re-implement the latest version later, but have you tried to use a form.load() or form.reset() with your version of the code? Neither of those were functioning properly after your changes in IE. And I am not sure what IE8 compatibility mode is, but hopefully the user is not required to set that up as that is not a workable solution in my opinion.

Again, thanks for the reply and I will try this vType change later.

Bucs
23 May 2009, 6:22 AM
The control still did not work in IE 7, but I did not try IE8 compatibility mode, nor did I want to...I just want the code to work in IE 7 standard install.

There appears to be a difference in how IE and FF handle an empty color parameter, where FF automatically translates to "" to "ffffff", but IE does not, therefore you will get an ext-all.js error in the setStyles function. The IE8 compatibility mode that you are using may mimic the FireFox translation of the empty color param, which might account for why you are not picking up the error. I took the liberty of fixing the code to account for this difference in IE7 and all is well in the IE world again. Have not tested this in IE8 yet, but should be fine as it leaves nothing for interpretation :)

Thanks for the vtype help. Here is the changed code:



initComponent: function() {
Ext.ux.form.ColorPickerFieldPlus.superclass.initComponent.call(this);
this.menu1 = new Ext.menu.ColorMenu();
this.menu2 = new Ext.ux.menu.ColorMenu();
this.on('valid', function() {
var v = (this.getValue() != "" ? this.getValue() : "ffffff");
var i = this.menu2.picker.rgbToHex(
this.menu2.picker.invert(this.menu2.picker.hexToRgb(v)));
this.el.applyStyles('background: #' + v + '; color: #' + i + ';');
}, this);
},
setValue: function(v) {
Ext.ux.form.ColorPickerFieldPlus.superclass.setValue.apply(this, arguments);
var i = this.menu2.picker.rgbToHex(this.menu2.picker.invert(this.menu2.picker.hexToRgb(v)));
this.el.applyStyles('background: #' + (v != "" ? v : "ffffff") + '; color: #' + i + ';');
},

mystix
24 May 2009, 6:05 PM
@Bucs,

your code could be shortened to just:


initComponent: function() {
Ext.ux.form.ColorPickerFieldPlus.superclass.initComponent.call(this);
this.menu1 = new Ext.menu.ColorMenu();
this.menu2 = new Ext.ux.menu.ColorMenu();
this.on('valid', function() {
var v = this.getValue() || "ffffff";
var i = this.menu2.picker.rgbToHex(
this.menu2.picker.invert(this.menu2.picker.hexToRgb(v)));
this.el.applyStyles('background: #' + v + '; color: #' + i + ';');
}, this);
},
setValue: function(v) {
Ext.ux.form.ColorPickerFieldPlus.superclass.setValue.apply(this, arguments);
var i = this.menu2.picker.rgbToHex(this.menu2.picker.invert(this.menu2.picker.hexToRgb(v)));
this.el.applyStyles('background: #' + (v || "ffffff") + '; color: #' + i + ';');
},

no need for unnecessary ternary operators.

HTH :)

extuser007
25 May 2009, 12:48 AM
Hi Bucs, mistyx, thanks for you fix.
BTW garraS, it's time to put code under SVN ;)

garraS
25 May 2009, 12:13 PM
Hi Bucs, mistyx, thanks for you fix.
BTW garraS, it's time to put code under SVN ;)

I've edited the first post and add SVN link.

garraS
25 May 2009, 12:15 PM
When I have time, I will update the final code of CPFP (ColorPickerFieldPlus).

somebee
16 Jun 2009, 3:47 AM
Is it possible to make this work in an EditorGrid? It seems to work right now, but the color-value is not persisted back into the grid..

incaic
24 Jun 2009, 11:45 PM
Thanks garraS for an excellent ux!

As extuser007 pointed out the 'change' event does not propogate. His solution works when selecting from the 2 menus, but not when typing in a valid hex value. The following is a standalone solution for all 3 cases: (not incorporating extuser007's solution)



// add this as the last operation in the this.on('valid', ... function on line ~83
if(String(v) !== String(this.startValue)){
this.fireEvent('change', this, v, this.startValue);
this.startValue = v;
}

Bucs
21 Jan 2010, 12:45 PM
garraS (http://www.extjs.com/forum/member.php?u=13739), is there a version of this that is working in Ext 3.1? Trying to upgrade project right now from 2.2 to 3.1 and getting error that's pointing to the Ext.ux.form.ColorPickerFieldPlus.js file. Haven't looked at specifics of error yet but thought I'd throw a quick shout out just in case there is already an update out there somewhere :)

Thanks!

Bucs
21 Jan 2010, 1:14 PM
FYI, the error is happening on the onSelect method extension:


Ext.extend(Ext.ux.menu.ColorItem, Ext.menu.Adapter, {
// private
onSelect : function(picker, color){
this.fireEvent("select", this, color, picker);
Ext.ux.menu.ColorItem.superclass.handleClick.call(this);
}
});

Not sure if the fireEvent signature changed or what, thought I read that somewhere.

extuser007
22 Jan 2010, 1:03 AM
Hi Bucs!

Ext.menu.Adapter removed from Ext 3. For a while your can take my version of Ext.ux.form.ColorPickerFieldPlus, that work for Ext 3.x.x.



/**
* @class Ext.ux.form.ColorPickerFieldPlus
* @extends Ext.form.TwinTriggerField
* This class makes Ext.ux.ColorPicker and Ext.ux.form.ColorPickerField available as a form field.
* @license: IYUIYBMAC (If you use it, you buy me a Coke)
* @author of Ext.ux.form.ColorPickerField: Robert B. Williams (extjs id: vtswingkid)
* @author of Ext.ux.form.ColorPickerFieldPlus: Ramiro P. Saenz
* @constructor
* Creates a new ColorPickerFieldPlus
* @param {Object} config Configuration options
* @version 1.0
* @date 14/04/09 (dd/mm/yy)
*/

Ext.namespace("Ext.ux", "Ext.ux.menu", "Ext.ux.form");

Ext.ux.menu.ColorMenu = Ext.extend(Ext.menu.Menu, {
enableScrolling : false,
hideOnClick : true,
initComponent : function(){
Ext.apply(this, {
plain : true,
showSeparator : false,
items: this.picker = new Ext.ux.ColorPicker(Ext.apply({
style: 'width:350px;'
}, this.initialConfig))
});
Ext.ux.menu.ColorMenu.superclass.initComponent.call(this);
this.relayEvents(this.picker, ['select']);
this.on('select', this.menuHide, this);
if (this.handler) {
this.on('select', this.handler, this.scope || this)
}
},
menuHide: function(){
if (this.hideOnClick) {
this.hide(true);
}
}
});


Ext.form.VTypes["hexText"] = "Invalid Hex code, eg: (#F0F0F0)";
Ext.form.VTypes["hex"] = function(v){ return /^#?([a-f]|[A-F]|[0-9]){3}(([a-f]|[A-F]|[0-9]){3})?$/.test(v); };

Ext.ux.form.ColorPickerFieldPlus = Ext.extend(Ext.form.TwinTriggerField, {
/**
* @cfg {String} fieldClass The default CSS class for the field (defaults to "x-form-trigger")
*/
trigger1Class: 'x-form-color-trigger-1',
/**
* @cfg {String} fieldClass The default CSS class for the field (defaults to "x-form-trigger")
*/
trigger2Class: 'x-form-color-trigger-2',
/**
* @cfg {String} fieldClass The default CSS class for the field (defaults to "x-form-image")
*/
hideTrigger1: false,
/**
* @cfg {String} fieldClass The default CSS class for the field (defaults to "x-form-image")
*/
hideTrigger2: false,
// private
vtype: 'hex',
// private
initComponent : function(){
Ext.ux.form.ColorPickerFieldPlus.superclass.initComponent.call(this);
this.menu1 = new Ext.menu.ColorMenu();
this.menu2 = new Ext.ux.menu.ColorMenu();
this.on('valid', function(){
var v = this.getValue();
var i = this.menu2.picker.rgbToHex(this.menu2.picker.invert(this.menu2.picker.hexToRgb(v)));
if (v && i) {
this.el.applyStyles('background: #' + v + '; color: #' + i + ';');
}
}, this);
},
setValue : function(v){
if (typeof(v) != 'string') {
v = parseInt(v);
v = this.menu2.picker.rgbToHex( (v&0x00ff0000) >> 16 ,(v&0x00ff00) >> 8,(v&0x00ff) );
}
Ext.ux.form.ColorPickerFieldPlus.superclass.setValue.apply(this, [v]);
// var i = this.menu2.picker.rgbToHex(this.menu2.picker.invert(this.menu2.picker.hexToRgb(v)));
// if (v && i) {
// this.el.applyStyles('background: #' + v + '; color: #' + i + ';');
// }
},
onDestroy : function(){
if(this.menu2) {
this.menu2.destroy();
}
if(this.wrap){
this.wrap.remove();
}
Ext.ux.form.ColorPickerFieldPlus.superclass.onDestroy.call(this);
},
// onBlur : function(){
// Ext.ux.form.ColorPickerFieldPlus.superclass.onBlur.call(this);
// var v = this.getValue();
// var i = this.menu2.picker.rgbToHex(this.menu2.picker.invert(this.menu2.picker.hexToRgb(v)));
// this.el.applyStyles('background: #'+v+'; color: #'+i+';');
// },
menu1Listeners : {
select: function(m, c){
var v0 = this.getValue();
this.setValue(c);
var v1 = this.getValue();
if (v1 !== v0) {
this.fireEvent('change', this, v1, v0);
}
this.focus.defer(10, this);
},
show : function(m){ // retain focus styling
this.onFocus();
},
hide : function(){
this.focus.defer(10, this);
var ml = this.menu1Listeners;
this.menu1.un("select", ml.select, this);
this.menu1.un("show", ml.show, this);
this.menu1.un("hide", ml.hide, this);
}
},
menu2Listeners : {
select: function(m, c){
var v0 = this.getValue();
this.setValue(c);
var v1 = this.getValue();
if (v1 !== v0) {
this.fireEvent('change', this, v1, v0);
}
this.focus.defer(10, this);
},
show : function(m){ // retain focus styling
this.onFocus();
},
hide : function(){
this.focus.defer(10, this);
var ml = this.menu2Listeners;
this.menu2.un("select", ml.select, this);
this.menu2.un("show", ml.show, this);
this.menu2.un("hide", ml.hide, this);
}
},
onTrigger1Click : function(){
if(this.disabled){
return;
}
this.menu1.on(Ext.apply({}, this.menu1Listeners, {
scope:this
}));

this.menu1.show(this.el, "tl-bl?");
},
onTrigger2Click : function(){
if(this.disabled){
return;
}
this.menu2.on(Ext.apply({}, this.menu2Listeners, {
scope:this
}));
this.menu2.show(this.el, "tl-bl?");
this.menu2.picker.setColor(this.getValue());
}
});
Ext.reg('colorpickerfieldplus', Ext.ux.form.ColorPickerFieldPlus);

garraS
22 Jan 2010, 4:02 AM
Awesome work! Thanks extuser007.

Bucs
22 Jan 2010, 4:08 AM
extuser007, thanks a ton! Works like a champ. Also like the move to initComponent, code looks much cleaner :)

One question. When the field is first initialized on a disabled form, the value of "v" is set to "000000". I personally would rather have this set to "ffffff" as it looks funny defaulting to black when all other form fields are white. Where would be the best place to initialize the picker's field to a white background?

EDIT: Also, it would be nice to initialize the field to not show the hex value of the default (ffffff in my case).

Again, thanks for sharing!
Bucs

extuser007
22 Jan 2010, 4:40 AM
Bucs,
as i understand, this sample code will initialize color field with white color.


items: [{
xtype : 'colorpickerfieldplus',
vtype : 'hex',
value : 'FFFFFF',
name : 'color',
fieldLabel: 'Color'
},{
....
}]

Bucs
22 Jan 2010, 4:54 AM
Hmmm, that didn't work for me. Still getting '000000' as default color.

extuser007
22 Jan 2010, 6:18 AM
Bucs,

Can't imagine why. Here sample code that works with Ext 3.x.x in FF 3.5.7,IE8, could you run it?



new Ext.Window({
width : 300,
height: 200,
layout : 'fit',
items : {
xtype : 'form',
items : [{
xtype : 'colorpickerfieldplus',
vtype : 'hex',
value : '800080',//'000000',
name : 'color',
//hideValue : true,
fieldLabel: 'Color2'
}]
}
}).show();

nak1
7 Apr 2011, 10:19 AM
I'm not sure if anyone else has experienced this issue, but in IE 8, if you attempt to have more then 2 ColorPickerFieldPlus fields rendered at once only 1 will ever appear.

Anyone figure out why?

nak1
7 Apr 2011, 10:41 AM
I figured it out, it was an invalid value for the for the "value" param. I was using
value:'#ffffff' instead of
value:'ffffff'