PDA

View Full Version : Ext.ux.plugins.TabFx



geoffrey.mcgill
27 Mar 2009, 11:26 AM
Here's a new TabFx plugin which fires a visual effect when a Tab becomes Active or is selected.

The default fx is "frame" and shows a ripple of exploding attenuating borders around the Tab.

The effect provides a subtle visual clue to the user that the Tab has become (or is) active.

Plugin


Ext.ns("Ext.ux", "Ext.ux.plugins");

Ext.ux.plugins.TabFx = Ext.extend(Ext.TabPanel, {
cfg : { name: "frame", args: [] },
constructor: function (cfg){
Ext.apply(this.cfg, cfg);
},
init : function (tp) {
tp._setActiveTab = tp.setActiveTab;
var self = this;
tp.setActiveTab = function (item) {
tp._setActiveTab(item);
item = Ext.fly(tp.getTabEl(item));
item[self.cfg.name].apply(item, Ext.isArray(self.cfg.args) ? self.cfg.args : []);
};
}
});

Usage Example


<script type="text/javascript">
Ext.onReady(function() {
var tabpanel = new Ext.TabPanel({
activeTab: 0,
width: 300,
height: 185,
plugins: new Ext.ux.plugins.TabFx(),
items: [
{ title: 'Tab 1' },
{ title: 'Tab 2' },
{ title: 'Tab 3' }
]
});

tabpanel.render(Ext.getBody());
});
</script>

Hope this helps.

zhw511006
27 Mar 2009, 5:00 PM
online demo please!

Xander75
28 Mar 2009, 12:01 AM
I tried this out last night by adding it to the Ext tab examples...

It's a nice little plugin and like you say, provides a subtle hint to which tab has become active. I will be using this come Monday morning.

Thanks for this... 5 stars from me!

tonedeaf
28 Mar 2009, 3:50 AM
A nice effect: A blue expanding rectangle around the activated tab.
Personally, I find ExtJS default highlight of the active tab quite sufficient.

EDIT: Another way to enable it for all Tab Panels (including Grid Panels) in an existing application is to use an override:
(The function is the same as Ext.TabPanel.setActiveTab() with just the line in bold added)


Ext.override(Ext.TabPanel, {
setActiveTab : function(item){
item = this.getComponent(item);
if(!item || this.fireEvent('beforetabchange', this, item, this.activeTab) === false){
return;
}
if(!this.rendered){
this.activeTab = item;
return;
}
if(this.activeTab != item){
if(this.activeTab){
var oldEl = this.getTabEl(this.activeTab);
if(oldEl){
Ext.fly(oldEl).removeClass('x-tab-strip-active');
}
this.activeTab.fireEvent('deactivate', this.activeTab);
}
var el = this.getTabEl(item);
Ext.fly(el).addClass('x-tab-strip-active');
this.activeTab = item;
this.stack.add(item);

this.layout.setActiveItem(item);
if(this.layoutOnTabChange && item.doLayout){
item.doLayout();
}
if(this.scrolling){
this.scrollToTab(item, this.animScroll);
}

Ext.fly(el)['frame'].apply(Ext.fly(el), [])

item.fireEvent('activate', item);
this.fireEvent('tabchange', this, item);
}
}
});

geoffrey.mcgill
28 Mar 2009, 9:40 AM
@tonedeaf - Maybe overriding .setActiveTab is a bit much if you want to apply the effect globally. The following code sample demonstrates using .createSequence to wedge in the call to .frame after the .setActiveTab logic has run. This then applies the effect to all Tabs/TabPanels.

Example


Ext.TabPanel.prototype.setActiveTab = Ext.TabPanel.prototype.setActiveTab.createSequence( function () {
Ext.fly(this.getActiveTab().tabEl).frame();
});

If you're just hard coding the 'frame' effect, then it's probably cleaner to just straight up call the .frame() function.

Hope this helps.

tonedeaf
28 Mar 2009, 12:25 PM
I was also trying to add the effect without duplicating the whole function in the override, but without it, its not possible to add the line in between the setActiveTab() function before it fires the tabchange event.



setActiveTab : function(item) {
...
item.fireEvent('activate', item);
this.fireEvent('tabchange', this, item);
}


I'm refreshing my grid panel, by loading server side data (and some other tasks) on tabchange event which causes a noticable delay before the animation displays on the active tab. Is there any way createSequence() can suspend events and call them once the sequence is executed?