Ce blog a déménagé et parle maintenant uniquement anglais.

This blog has moved and now only speaks English.

blog.floriancargoet.com

See you there!

/home/florian

le blog de florian cargoet : du linux, du web et du logiciel libre



ExtJS : Boutons à plusieurs icônes

29 August, 2009 (10:16) | Ext JS, Webdev | Florian Cargoet

Catégorie Webdev : A propos du web, de son contenu, de ses outils...

Voilà une nouvelle extension ExtJS. Elle permet à un bouton d’avoir plusieurs icônes qui sont permutées à chaque clic. Très utile pour un bouton toggle à deux états, on peut aussi l’utiliser pour un bouton cyclique avec autant d’états que l’on veut. Avant de regarder le code, vous pouvez jetter un oeil à la démo.

L’extension

L’extension ajoute le support de l’option de configuration icons qui prend comme valeur un array d’url d’icônes.
On reprend quasiment tout le code original du Toolbar.Button et on ajoute simplement la gestion de icons.
Les ajouts au code de base sont commentés //AJOUT :

?View Code JAVASCRIPT
//file:Ext.ux.MultipleIconsButton.js
Ext.ns('Ext.ux');
 
Ext.ux.MultipleIconsButton = Ext.extend(Ext.Toolbar.Button, {
    getTemplateArgs : function(){
        var cls = (this.cls || '');
        //AJOUT : ici on ajoute la vérification de this.icons pour décider de la classe CSS
        cls += (this.iconCls || this.icon || this.icons) ? (this.text ? ' x-btn-text-icon' : ' x-btn-icon') : ' x-btn-noicon';
        if(this.pressed){
            cls += ' x-btn-pressed';
        }
        return [this.text || ' ', this.type, this.iconCls || '', cls, 'x-btn-' + this.scale + ' x-btn-icon-' + this.scale + '-' + this.iconAlign, this.getMenuClass()];
    },
    initButtonEl : function(btn, btnEl){
        this.el = btn;
 
        if(this.id){
            this.el.dom.id = this.el.id = this.id;
        }
        //AJOUT : si this.icons existe, on prend le premier élément comme icône par défaut
        if(this.icons){
        	this.iconIndex = 0;
    		this.icon = this.icons[0];
        }
        if(this.icon){
                //AJOUT : si this.icon est un tableau, c'est qu'il manque un s à icons
        	if(Ext.isArray(this.icon)){ //handles icon/icons typo
        		this.icons = this.icon;
        		this.iconIndex = 0;
        		this.icon = this.icons[0];
        	}
            btnEl.setStyle('background-image', 'url(' +this.icon +')');
        }
        if(this.tabIndex !== undefined){
            btnEl.dom.tabIndex = this.tabIndex;
        }
        if(this.tooltip){
            this.setTooltip(this.tooltip, true);
        }
 
        if(this.handleMouseEvents){
            this.mon(btn, {
                scope: this,
                mouseover: this.onMouseOver,
                mousedown: this.onMouseDown
            });
 
            // new functionality for monitoring on the document level
            //this.mon(btn, 'mouseout', this.onMouseOut, this);
        }
 
        if(this.menu){
            this.mon(this.menu, {
                scope: this,
                show: this.onMenuShow,
                hide: this.onMenuHide
            });
        }
 
        if(this.repeat){
            var repeater = new Ext.util.ClickRepeater(btn, Ext.isObject(this.repeat) ? this.repeat : {});
            this.mon(repeater, 'click', this.onClick, this);
        }
 
        this.mon(btn, this.clickEvent, this.onClick, this);
    },
    onClick : function(e){
        if(e){
            e.preventDefault();
        }
        if(e.button !== 0){
            return;
        }
        if(!this.disabled){
            //AJOUT : on passe à l'icône suivante
            if(this.icons){
        	this.setNextIcon();
            }
            if(this.enableToggle && (this.allowDepress !== false || !this.pressed)){
                this.toggle();
            }
            if(this.menu && !this.menu.isVisible() && !this.ignoreNextClick){
                this.showMenu();
            }
            this.fireEvent('click', this, e);
            if(this.handler){
                //this.el.removeClass('x-btn-over');
                this.handler.call(this.scope || this, this, e);
            }
        }
    },
    //AJOUT : methode pour passer à l'icône suivante
    setNextIcon : function(){
    	this.iconIndex++;//next icon
    	this.iconIndex%=this.icons.length;//restart at 0 if needed
    	this.icon = this.icons[this.iconIndex];
    	this.el.child('button').setStyle('background-image','url('+this.icon+')');
    }
});
 
Ext.reg('mibutton',Ext.ux.MultipleIconsButton);

Utilisation

Voyons comment utiliser cette nouvelle option de configuration icons.

?View Code JAVASCRIPT
new Ext.Window({
    title : 'Multiple Icons Button test',
    width : 400,
    height: 300,
    tbar:[
        {
            xtype:'mibutton',
            icons : ['img/disconnect.png','img/connect.png'],
            text : 'Connect',
            enableToggle:true,
            toggleHandler : function(btn,state){
                if(state){
                    btn.setText('Disconnect');
                }
                else{
                    btn.setText('Connect');
                }
           }
        },{    
            xtype:'mibutton',
            icons : ['img/tag_blue.png','img/tag_red.png','img/tag_green.png','img/tag_yellow.png'],
            text : 'blue tag',
            handler : function(){
                var color = this.icon.replace(/(\.png)|(img\/tag_)/g,'');
                 this.setText(color+' tag');
            }
    }]
});

Et voilà, l’icône change à chaque clic !

Vous pouvez retrouver cette extension sur sa page page dédiée où vous trouverez le code et des éventuelles mises à jour.