View Full Version : Clickable icon in an Ext.TabPanel Title

29 May 2008, 9:09 AM
It took me a bit of work to figure this out, so I figured I'd post it help anyone else trying to do this (and maybe get the root problem fixed in the next release!)

The (desired) functionality:

* I've got various documents open, each contained within a tab.
* I want to be able to add a save icon to the tab so that the user can see that the content has been changed and needs to be saved.
* I want to be able to click the save icon to save the content.

The problems:

* Ext.Panel titles are only meant to be used as textual elements.
* The actual text is held in a SPAN element on a tab, which severly limits the type of elements that we can use to complete our task. (for example, DIVs cannot be nested in SPANs when you've got a Strict DocType)
* The above problems were solved using an IMG tag. But now I can't capture a click event!

The root cause:

* At some point, the Ext creators decided that we were only going to use text in a title, and therefore, it is ok for them to pass the title element around using innerHTML (even AFTER the titlechange event has fired).
* When they do this, they are effectively destroying our click event association (and making our lives difficult!)

The solution:

* Extend the Ext.Panel object and add a new event called 'aftertitlechange'.
* Override the setTitle method, which calls the superclass setTitle method, and then fires our new 'aftertitlechange' event. This ensures that we can capture the 'live' element.
* Look for our element id, and attach the click event to it every time that the 'aftertitlechange' event fires (which will probably only be once per panel, unless you're creating an app to confuse your users).

The code:

Extension code:

Ext.ux.Panel = function(config) {
this.addEvents({'aftertitlechange' : true});
Ext.ux.Panel.superclass.constructor.call(this, config);
Ext.extend(Ext.ux.Panel, Ext.Panel, {
setTitle : function(title, iconCls) {
Ext.ux.Panel.superclass.setTitle.call(this, title, iconCls);
this.fireEvent('aftertitlechange', this, title, iconCls);

Sample code:

TabSample = function() {};
Ext.extend(TabSample, Object, {
init : function() {
var saveIconId = Ext.id();

var frag = document.createElement('x');

Ext.DomHelper.append(frag, {
tag : 'img',
src : 'ic_save.gif',
cls : 'indicateSave',
id : saveIconId
new Ext.TabPanel({
border : false,
renderTo : 'putTheTabHere',
deferredRender : false,
ctCls : 'clickableIconTabStrip',
items : [
new Ext.Panel({
layout : 'fit',
title : 'Tab 1'
new Ext.ux.Panel({
layout : 'fit',
title : frag.innerHTML + 'Tab 2',
saveIconId : saveIconId,
listeners : {
scope : this,
single : false,
aftertitlechange : this.onPanelTitleChanged
onPanelTitleChanged : function(tab, newTitle, newIconClass) {
var saveIcon = Ext.get(tab.saveIconId);
if (saveIcon) {
saveIcon.ownerCt = tab;
new Ext.util.ClickRepeater(saveIcon, {
preventDefault : true,
stopDefault : true,
listeners : {
mouseup : this.onTabIconClick, // make sure that you connect to MOUSEUP and NOT CLICK
scope : this
onTabIconClick : function(tab) {
alert('You just clicked a tab icon! Take a break, go to the pub. You DESERVE it!');

Lastly, there's a sample image file and a sample HTML file. (You just need to remove the .txt extension.)

29 May 2008, 10:39 AM
Attachment 7110 (http://extjs.com/forum/attachment.php?attachmentid=7110&d=1212079722)

"Invalid Attachment specified. If you followed a valid link, please notify the administrator" (http://extjs.com/forum/sendmessage.php)

30 May 2008, 2:27 AM
Sorry, not sure what Attachment 7110 is.... you don't need it tho so I removed it! (just the file and the image)