1. #1
    Ext User bendy's Avatar
    Join Date
    Mar 2007
    Posts
    18
    Vote Rating
    0
    bendy is on a distinguished road

      0  

    Default ColorField (color picker form field)

    ColorField (color picker form field)


    Whipped this thing up for one of my projects and thought I would post the code here in case anyone else finds it useful. It is an Ext.form.ColorField that allows you to choose a color from the menu or enter it manually.



    I followed the DateField as an example when making this. It is not perfect but it works for me. You may have to adjust the image paths depending on where you put things.

    Code:
    /**
     * @class Ext.form.ColorField
     * @extends Ext.form.TriggerField
     * Provides a very simple color form field with a ColorMenu dropdown.
     * Values are stored as a six-character hex value without the '#'.
     * I.e. 'ffffff'
     * @constructor
     * Create a new ColorField
     * <br />Example:
     * <pre><code>
    var cf = new Ext.form.ColorField({
    	fieldLabel: 'Color',
    	hiddenName:'pref_sales',
    	showHexValue:true
    });
    </code></pre>
     * @param {Object} config
     */
    Ext.form.ColorField = function(config){
        Ext.form.ColorField.superclass.constructor.call(this, config);
    	this.on('render', this.handleRender);
    };
    
    Ext.extend(Ext.form.ColorField, Ext.form.TriggerField,  {
        /**
         * @cfg {Boolean} showHexValue
         * True to display the HTML Hexidecimal Color Value in the field
         * so it is manually editable.
         */
        showHexValue : false,
    	
    	/**
         * @cfg {String} triggerClass
         * An additional CSS class used to style the trigger button.  The trigger will always get the
         * class 'x-form-trigger' and triggerClass will be <b>appended</b> if specified (defaults to 'x-form-color-trigger'
         * which displays a calendar icon).
         */
        triggerClass : 'x-form-color-trigger',
    	
        /**
         * @cfg {String/Object} autoCreate
         * A DomHelper element spec, or true for a default element spec (defaults to
         * {tag: "input", type: "text", size: "10", autocomplete: "off"})
         */
        // private
        defaultAutoCreate : {tag: "input", type: "text", size: "10",
    						 autocomplete: "off", maxlength:"6"},
    	
    	/**
    	 * @cfg {String} lengthText
    	 * A string to be displayed when the length of the input field is
    	 * not 3 or 6, i.e. 'fff' or 'ffccff'.
    	 */
    	lengthText: "Color hex values must be either 3 or 6 characters.",
    	
    	//text to use if blank and allowBlank is false
    	blankText: "Must have a hexidecimal value in the format ABCDEF.",
    	
    	/**
    	 * @cfg {String} color
    	 * A string hex value to be used as the default color.  Defaults
    	 * to 'FFFFFF' (white).
    	 */
    	defaultColor: 'FFFFFF',
    	
    	maskRe: /[a-f0-9]/i,
    	// These regexes limit input and validation to hex values
    	regex: /[a-f0-9]/i,
    
    	//private
    	curColor: 'ffffff',
    	
        // private
        validateValue : function(value){
    		if(!this.showHexValue) {
    			return true;
    		}
    		if(value.length<1) {
    			this.el.setStyle({
    				'background-color':'#' + this.defaultColor
    			});
    			if(!this.allowBlank) {
    				this.markInvalid(String.format(this.blankText, value));
    				return false
    			}
    			return true;
    		}
    		if(value.length!=3 && value.length!=6 ) {
    			this.markInvalid(String.format(this.lengthText, value));
    			return false;
    		}
    		this.setColor(value);
            return true;
        },
    
        // private
        validateBlur : function(){
            return !this.menu || !this.menu.isVisible();
        },
    	
    	// Manually apply the invalid line image since the background
    	// was previously cleared so the color would show through.
    	markInvalid : function( msg ) {
    		Ext.form.ColorField.superclass.markInvalid.call(this, msg);
    		this.el.setStyle({
    			'background-image': 'url(../lib/resources/images/default/grid/invalid_line.gif)'
    		});
    	},
    
        /**
         * Returns the current color value of the color field
         * @return {String} value The hexidecimal color value
         */
        getValue : function(){
    		return this.curValue || this.defaultValue || "FFFFFF";
        },
    
        /**
         * Sets the value of the color field.  Format as hex value 'FFFFFF'
         * without the '#'.
         * @param {String} hex The color value
         */
        setValue : function(hex){
    		Ext.form.ColorField.superclass.setValue.call(this, hex);
    		this.setColor(hex);
        },
    	
    	/**
    	 * Sets the current color and changes the background.
    	 * Does *not* change the value of the field.
    	 * @param {String} hex The color value.
    	 */
    	setColor : function(hex) {
    		this.curColor = hex;
    		
    		this.el.setStyle( {
    			'background-color': '#' + hex,
    			'background-image': 'none'
    		});
    		if(!this.showHexValue) {
    			this.el.setStyle({
    				'text-indent': '-100px'
    			});
    			if(Ext.isIE) {
    				this.el.setStyle({
    					'margin-left': '100px'
    				});
    			}
    		}
    	},
    	
    	handleRender: function() {
    		this.setDefaultColor();
    	},
    	
    	setDefaultColor : function() {
    		this.setValue(this.defaultColor);
    	},
    
        // private
        menuListeners : {
            select: function(m, d){
                this.setValue(d);
            },
            show : function(){ // retain focus styling
                this.onFocus();
            },
            hide : function(){
                this.focus();
                var ml = this.menuListeners;
                this.menu.un("select", ml.select,  this);
                this.menu.un("show", ml.show,  this);
                this.menu.un("hide", ml.hide,  this);
            }
        },
    	
    	//private
    	handleSelect : function(palette, selColor) {
    		this.setValue(selColor);
    	},
    
        // private
        // Implements the default empty TriggerField.onTriggerClick function to display the ColorPicker
        onTriggerClick : function(){
            if(this.disabled){
                return;
            }
            if(this.menu == null){
                this.menu = new Ext.menu.ColorMenu();
    			this.menu.palette.on('select', this.handleSelect, this );
            }
            this.menu.on(Ext.apply({}, this.menuListeners, {
                scope:this
            }));
            this.menu.show(this.el, "tl-bl?");
        }
    });
    And the CSS:
    Code:
    .x-form-field-wrap .x-form-color-trigger {
    	background:transparent url(img/color-trigger.gif) no-repeat 0 0;
        cursor:pointer; 
    }
    I have attached the icon but it could probably be replaced with something better.

    Hope someone finds this useful!
    Attached Images

  2. #2
    Sencha User
    Join Date
    Mar 2007
    Posts
    218
    Vote Rating
    0
    alien3d is on a distinguished road

      0  

    Default i tested

    i tested


    very liked it Hope jack put this code up to ext-all.js

  3. #3
    Ext User bendy's Avatar
    Join Date
    Mar 2007
    Posts
    18
    Vote Rating
    0
    bendy is on a distinguished road

      0  

    Default


    Glad you liked it.. Let me know if you find any bugs or have a feature request.
    Ben D.

  4. #4
    Sencha User
    Join Date
    Mar 2007
    Posts
    186
    Vote Rating
    0
    Nullity is on a distinguished road

      0  

    Default


    Wow, I actually just implemented this feature myself last week, but I wanted to add a little more to it before I posted it here. I hope you don't mind, I "borrowed" your small regex as I forgot to add that . Here is my code (there is still more I want to do with it, but it works as-is):

    Code:
    /**
     * @class Ext.form.ColorField
     * @extends Ext.form.TriggerField
     * Provides a color input field with a {@link Ext.ColorPalette} dropdown.
    * @constructor
    * Create a new ColorField
     * <br />Example:
     * <pre><code>
    var color_field = new Ext.form.ColorField({
    	fieldLabel: 'Color',
    	id: 'color',
    	width: 175,
    	allowBlank: false
    });
    </code></pre>
    * @param {Object} config
     */
    Ext.form.ColorField = function(config){
        Ext.form.ColorField.superclass.constructor.call(this, config);
    };
    
    Ext.extend(Ext.form.ColorField, Ext.form.TriggerField,  {
        /**
         * @cfg {String} invalidText
         * The error to display when the color in the field is invalid (defaults to
         * '{value} is not a valid color - it must be in the format {format}').
         */
        invalidText : "{0} is not a valid color - it must be in a the hex format {1}",
        /**
         * @cfg {String} triggerClass
         * An additional CSS class used to style the trigger button.  The trigger will always get the
         * class 'x-form-trigger' and triggerClass will be <b>appended</b> if specified (defaults to 'x-form-color-trigger'
         * which displays a color wheel icon).
         */
        triggerClass : 'x-form-color-trigger',
        /**
         * @cfg {String/Object} autoCreate
         * A DomHelper element spec, or true for a default element spec (defaults to
         * {tag: "input", type: "text", size: "10", autocomplete: "off"})
         */
    
        // private
        defaultAutoCreate : {tag: "input", type: "text", size: "10", maxlength: "7", autocomplete: "off"},
    
        // Limit input to hex values
        maskRe: /[a-f0-9]/i,
        regex: /[a-f0-9]/i,
    
        // private
        validateValue : function(value){
            if(!Ext.form.ColorField.superclass.validateValue.call(this, value)){
                return false;
            }
            if(value.length < 1){ // if it's blank and textfield didn't flag it then it's valid
                 return true;
            }
    
            var parseOK = this.parseColor(value);
    
            if(!value || (parseOK == false)){
                this.markInvalid(String.format(this.invalidText, value, '#AABBCC'));
                return false;
            }
    
            return true;
        },
    
        // private
        // Provides logic to override the default TriggerField.validateBlur which just returns true
        validateBlur : function(){
            return !this.menu || !this.menu.isVisible();
        },
    
        /**
         * Returns the current value of the color field
         * @return {String} value The color value
         */
        getValue : function(){
            return Ext.form.ColorField.superclass.getValue.call(this) || "";
        },
    
        /**
         * Sets the value of the color field.  You can pass a string that can be parsed into a valid HTML color
         * <br />Usage:
         * <pre><code>
    		colorField.setValue('#FFFFFF');
           </code></pre>
         * @param {String} color The color string
         */
        setValue : function(color){
            Ext.form.ColorField.superclass.setValue.call(this, this.formatColor(color));
        },
    
        // private
        parseColor : function(value){
    	return (!value || (value.substring(0,1) != '#')) ?
    		false : true;
        },
    
        // private
        formatColor : function(value){
    	if (value && (this.parseColor(value) == false)) {
    		value = '#' + value;
    	}
    
            return value;
        },
    
        // private
        menuListeners : {
            select: function(e, c){
                this.setValue(c);
            },
            show : function(){ // retain focus styling
                this.onFocus();
            },
            hide : function(){
                this.focus();
                var ml = this.menuListeners;
                this.menu.un("select", ml.select,  this);
                this.menu.un("show", ml.show,  this);
                this.menu.un("hide", ml.hide,  this);
            }
        },
    
        // private
        // Implements the default empty TriggerField.onTriggerClick function to display the ColorPalette
        onTriggerClick : function(){
            if(this.disabled){
                return;
            }
            if(this.menu == null){
                this.menu = new Ext.menu.ColorMenu();
            }
    
            this.menu.on(Ext.apply({}, this.menuListeners, {
                scope:this
            }));
    
            this.menu.show(this.el, "tl-bl?");
        }
    });
    Also, I attached the icon that I made and a sample image.
    Attached Images

  5. #5
    Ext User bendy's Avatar
    Join Date
    Mar 2007
    Posts
    18
    Vote Rating
    0
    bendy is on a distinguished road

      0  

    Default


    Looks great Nullity! Feel free to use whatever code you want. I don't need to extend this any further for my project but it is great to see someone else continuing the same thing.
    Ben D.

  6. #6
    Ext User
    Join Date
    Apr 2007
    Posts
    2
    Vote Rating
    0
    hemper is on a distinguished road

      0  

    Default extract foreground color from background..

    extract foreground color from background..


    I add formula which extract foreground color from background..

    Code:
            if (!this.validateColor(color)){
                return false;
            }
                
            var fgColor = this.defaultFgColorl,
                bgColorBr = this.hex2rgb(color);
            fgColor = ((bgColorBr.R * 299) + (bgColorBr.G * 587) + (bgColorBr.B * 114)) / 1000 - 125 < 0 ? "#FFF" : "#000"; 
            
            this.el.setStyle({
                'background-color': color,
                'background-image': 'none',
                'color' : fgColor
            });
    Code:
    // private
        hex2dec: function(hexchar) {
            return "0123456789ABCDEF".indexOf(hexchar.toUpperCase());
        },
        // private
        hex2rgb: function(color) { 
            color = color.replace("#", "");
            return {
                R : (this.hex2dec(color.substr(0, 1)) * 16) + this.hex2dec(color.substr(1, 1)),
                G : (this.hex2dec(color.substr(2, 1)) * 16) + this.hex2dec(color.substr(3, 1)),
                B : (this.hex2dec(color.substr(4, 1)) * 16) + this.hex2dec(color.substr(5, 1))
            }
        }

  7. #7
    Ext User tataye's Avatar
    Join Date
    Apr 2007
    Location
    Lille, France
    Posts
    12
    Vote Rating
    0
    tataye is on a distinguished road

      0  

    Question


    Hello Nullity,

    Your code doesn't like the empty cells : Then I click in an empty cell I have a #<div c

    Sorry, I made an error It works !
    Attached Images
    Last edited by tataye; 30 Apr 2007 at 9:30 AM. Reason: new test with another example

  8. #8
    Sencha User
    Join Date
    Mar 2007
    Posts
    186
    Vote Rating
    0
    Nullity is on a distinguished road

      0  

    Default


    I updated the regex's:
    Code:
    maskRe: /[#a-f0-9]/i,
    regex: /^#([a-f0-9]{3}|[a-f0-9]{6})$/i,
    I also made these 2 other small changes:
    Code:
    // replace line 28 with this
    invalidText : 'This is not a valid color - it must be in a the hex format "#1A2B3C"',
    
    // replace line 61 with this
    this.markInvalid(this.invalidText);

  9. #9
    Ext User
    Join Date
    Mar 2007
    Posts
    122
    Vote Rating
    0
    moraes is on a distinguished road

      0  

    Default


    Thank you guys, this is exactly what I need, and it works very well.

  10. #10
    Ext JS Premium Member stever's Avatar
    Join Date
    Mar 2007
    Posts
    1,406
    Vote Rating
    6
    stever will become famous soon enough stever will become famous soon enough

      0  

    Default


    Here is a trigger image with all the states...
    Attached Images

Turkiyenin en sevilen filmlerinin yer aldigi xnxx internet sitemiz olan ve porn sex tarzi bir site olan mobil porno izle sitemiz gercekten dillere destan bir durumda herkesin sevdigi bir site olarak tarihe gececege benziyor. Sitenin en belirgin ozelliklerinden birisi de Turkiyede gercekten kaliteli ve muntazam, duzenli porno izle siteleri olmamasidir. Bu yuzden iste. Ayrica en net goruntu kalitesine sahip adresinde yayinlanmaktadir. Mesela diğer sitelerimizden bahsedecek olursak, en iyi hd porno video arşivine sahip bir siteyiz. "The Best anal porn videos and slut anus, big asses movies set..." hd porno faketaxi