1. #1
    Ext JS Premium Member
    Join Date
    Feb 2008
    Posts
    28
    Vote Rating
    0
    jcarbou is on a distinguished road

      0  

    Default Extention of Ext.ux.form.IconCombo

    Extention of Ext.ux.form.IconCombo


    I add 2 extentions to the Ext.ux.form.IconCombo pluggin (created by Jozef Sakalos) :

    - You can used icon with any width (It was limited to 16px). To do this just set the property iconWidth with the biggest icon width.
    - add the possibility to build the css name using a template instead of using a property of the record. To do this just set the property iconClsTpl.

    Code:
    /**
     * Ext.ux.form.IconComboBox Extension Class for Ext 2.x Library
     *
     * @author  Ing. Jozef Sakalos
     * @version $Id: IconCombo.js,v 1.1 2010/01/29 10:14:25 jcarbou Exp $
     *
     * @license Ext.ux.form.IconComboBox is licensed under the terms of
     * the Open Source LGPL 3.0 license.  Commercial use is permitted to the extent
     * that the code/component(s) do NOT become part of another Open Source or Commercially
     * licensed development library or toolkit without explicit permission.
     * 
     * License details: http://www.gnu.org/licenses/lgpl.html
     */
    
    /**
     * @class Ext.ux.form.IconComboBox
     * @extends Ext.form.ComboBox
     */
    Ext.namespace('Ext.ux.form');
    Ext.ux.form.IconCombo = Ext.extend(Ext.form.ComboBox, {
        initComponent:function() {
    		this.iconWidth = this.iconWidth || 16;
    		var iw = this.iconWidth;
    		
    		// Add, if not already exist, css for icon width
    		if (!Ext.util.CSS.getRule('ux-icon-combo-icon-'+iw)) {
    			var css = '.ux-icon-combo-icon-'+iw+' {background-repeat: no-repeat;background-position: 0 50%;width: '+(iw+2)+'px;height: 14px;}'
    	        + '.ux-icon-combo-input-'+iw+' {padding-left: '+(iw+9)+'px;}'
    	        + '.x-form-field-wrap .ux-icon-combo-icon-'+iw+' {top: 4px;left: 5px;}'
    	        + '.ux-icon-combo-item-'+iw+' {background-repeat: no-repeat ! important;background-position: 3px 50% ! important;padding-left: '+(iw+8)+'px ! important;}';
    			Ext.util.CSS.createStyleSheet(css, 'ux-IconCombo-css-'+iw);
    		}
            
            this.iconClsTpl = this.iconClsTpl || ('{' + this.iconClsField + '}');	
    		
            Ext.apply(this, {
                tpl:  '<tpl for=".">'
                    + '<div class="x-combo-list-item ux-icon-combo-item-'+iw+' '+ this.iconClsTpl+'">'
                    + '{' + this.displayField + '}'
                    + '</div></tpl>'
            });
    		
    		this.iconClsTpl = new Ext.Template(this.iconClsTpl);
    
            // call parent initComponent
            Ext.ux.form.IconCombo.superclass.initComponent.apply(this, arguments);
    
        } // eo function initComponent
    
        ,onRender:function(ct, position) {
            // call parent onRender
            Ext.ux.form.IconCombo.superclass.onRender.apply(this, arguments);
    
            // adjust styles
            this.wrap.applyStyles({position:'relative'});
            this.el.addClass('ux-icon-combo-input-'+this.iconWidth);
    
            // add div for icon
            this.icon = Ext.DomHelper.append(this.el.up('div.x-form-field-wrap'), {
                tag: 'div', style:'position:absolute'
            });
        } // eo function onRender
    
        ,afterRender:function() {
            Ext.ux.form.IconCombo.superclass.afterRender.apply(this, arguments);
            if(undefined !== this.value) {
                this.setValue(this.value);
            }
        } // eo function afterRender
        ,setIconCls:function() {
            var rec = this.store.query(this.valueField || this.displayField, this.getValue()).itemAt(0);
            if(rec && this.icon) {
    			this.icon.className = 'ux-icon-combo-icon-'+this.iconWidth +' '+ this.iconClsTpl.apply(rec.data);
            }
        } // eo function setIconCls
    
        ,reset:function(value) {
           Ext.ux.form.IconCombo.superclass.reset.apply(this, arguments);
           this.icon.className = ''; 
        } // eo function reset
    
        ,setValue: function(value) {
            Ext.ux.form.IconCombo.superclass.setValue.call(this, value);
            this.setIconCls();
        } // eo function setValue
    
    
    });
    
    // register xtype
    Ext.reg('iconcombo', Ext.ux.form.IconCombo);
    Example (see the screeShot for the result) :

    Code:
    {
    xtype: 'iconcombo',
    fieldLabel: 'Web portal',
    name: 'roleIWP',
    hiddenName: 'roleIWP',
    allowBlank: false,
    displayField: 'name',
    valueField:'id',
    iconClsTpl: 'user-role-{application}-{role}',
    iconWidth:69,
    mode: 'local',
    triggerAction: 'all',
    editable:false,
    store: new Ext.data.JsonStore({
    	url: 'Decl/User.do',
    	baseParams: {jsAction: 'findIWPRole'},
    	root:'root',
    	autoLoad: true,
    	id:'id',
    	totalProperty:'totalProperty',
    	fields: [
    		{name: 'id', mapping: 'id'},
    		{name: 'application', mapping: 'application'},
    		{name: 'role', mapping: 'role'},
    		{name: 'name', mapping: 'name'}
    	]
    })
    }
    Attached Images
    Attached Files

  2. #2
    Sencha - Services Team Stju's Avatar
    Join Date
    Dec 2008
    Location
    Redwood city, California
    Posts
    288
    Vote Rating
    3
    Stju is on a distinguished road

      0  

    Default Small addition

    Small addition


    This Extension is missing very important part from the beginning: chance to clear the value including the Icon !
    If You clear the value of combo, by default text disappears, but icon for first row stays..
    So, here is the code(add before setValue):
    Code:
    reset:combo.reset.createSequence(function(value) {
                   this.icon.className = ''; 
                    
                }),
    Stju

  3. #3
    Ext JS Premium Member
    Join Date
    Feb 2008
    Posts
    28
    Vote Rating
    0
    jcarbou is on a distinguished road

      0  

    Thumbs up Thanks !

    Thanks !


    I modified the code in the first post.

  4. #4
    Sencha Premium Member goldledoigt's Avatar
    Join Date
    Jul 2007
    Location
    Paris, France
    Posts
    56
    Vote Rating
    0
    goldledoigt is on a distinguished road

      0  

    Default


    It works great, thank you for sharing.

    Because, as far as I know, "valueField" is not mandatory I had to change this :

    Code:
    var rec = this.store.query(this.valueField, this.getValue()).itemAt(0);
    for this:

    Code:
    var rec = this.store.query(this.valueField || this.displayField, this.getValue()).itemAt(0);
    Goldledoigt

  5. #5
    Ext JS Premium Member
    Join Date
    Feb 2008
    Posts
    28
    Vote Rating
    0
    jcarbou is on a distinguished road

      0  

    Default


    Ok !

    Code updated on the first post.

  6. #6
    Sencha User
    Join Date
    Nov 2008
    Location
    Currently Mexico
    Posts
    133
    Vote Rating
    0
    jmariani is on a distinguished road

      0  

    Default CSS

    CSS


    Please, can you attach a sample of the CSS of your example?

  7. #7
    Ext JS Premium Member
    Join Date
    Feb 2008
    Posts
    28
    Vote Rating
    0
    jcarbou is on a distinguished road

      0  

    Default


    I have updated the first post with css !

  8. #8
    Sencha User
    Join Date
    Nov 2008
    Location
    Currently Mexico
    Posts
    133
    Vote Rating
    0
    jmariani is on a distinguished road

      0  

    Default


    Thank you!

  9. #9
    Sencha User
    Join Date
    Jul 2010
    Posts
    4
    Vote Rating
    0
    ToxSox is on a distinguished road

      0  

    Default


    nice extention but i found a bug.
    If i had a iconcombobox select one item and now remove the content of the combobox, than i get a empty combobox but with the first icon in store.

    Its possible to make a emptyIcon, like the emtpyText property?
    Attached Images

  10. #10
    Sencha User
    Join Date
    Dec 2008
    Location
    France
    Posts
    244
    Vote Rating
    0
    senacle is on a distinguished road

      0  

    Default


    If you have a lot of items in your combo and some css names have the same beginning, only one icon is displayed.

    Exemple :
    Code:
    .ux-flag-ressource-9 {
    background-image: url("9.png") !important;
    }
    .....
    .ux-flag-ressource-90 {
    background-image: url("90.png") !important;
    }
    ....
    .ux-flag-ressource-900 {
    background-image: url("900.png") !important;
    }
    If you choose the item 9, 90 or 900 in the combo's dropdownlist, it's allways the 9 icon which is displayed.

    So, need to change :
    Code:
        ,setIconCls:function() { 
            var rec = this.store.query(this.valueField || this.displayField, this.getValue()).itemAt(0); 
            if(rec && this.icon) { 
                this.icon.className = 'ux-icon-combo-icon-'+this.iconWidth +' '+ this.iconClsTpl.apply(rec.data); 
            } 
        } // eo function setIconCls
    to :

    Code:
        ,setIconCls:function() { 
            var rec = this.store.query(this.valueField || this.displayField, RegExp("^"+this.getValue()+"$")).itemAt(0); 
            if(rec && this.icon) { 
                this.icon.className = 'ux-icon-combo-icon-'+this.iconWidth +' '+ this.iconClsTpl.apply(rec.data); 
            } 
        } // eo function setIconCls