PDA

View Full Version : [2.0] Ext.ux.plugins.HeaderButtons - Styled Buttons in Panel Header (Plugin)



mbajema
15 Jul 2008, 8:45 AM
Ext.Panel tools config option provide simple icon buttons with limited functionality. However, some cases would be better served with full functional buttons including button text, menus, etc. Although Panels provide toolbar capabilities, sometimes a panel needs one button and/or menu but the vertical space required for a toolbar is too expensive for such limited functionality.

ntony provided a simple solution by extending Ext.Panel here: http://extjs.com/forum/showthread.php?p=194506. I attempted to improve upon this, by styling the buttons appropriately for the panel header and also implementing it as a plugin so header buttons could be added to windows as well as ordinary panels. Below is my solution - feel free to make any improvements and post to this thread.

Source code: 8242

Screenshot:
http://extjs.com/forum/attachment.php?attachmentid=8108&stc=1&d=1216139964

Plugin Code:

Ext.namespace('Ext.ux.plugins');
Ext.ux.plugins.HeaderButtons = function(config)
{
Ext.apply(this, config);
};

Ext.extend(Ext.ux.plugins.HeaderButtons, Ext.util.Observable,
{
init: function(panel)
{
if (panel.hbuttons)
{
Ext.apply(panel,
{
onRender: panel.onRender.createSequence(function(ct, position)
{
if (this.headerButtons && this.headerButtons.length > 0)
{
var tb = this.header.createChild(
{
cls:'ux-panel-header-btns-ct',
cn:
{
cls:"ux-panel-header-btns",
html:'<table cellspacing="0"><tbody><tr></tr></tbody></table><div class="x-clear"></div>'
}
}, this.header.first('span', true), true); // insert before header text (but after tools)

var tr = tb.getElementsByTagName('tr')[0];
for (var i = 0, len = this.headerButtons.length; i < len; i++)
{
var b = this.headerButtons[i];
var td = document.createElement('td');
td.className = 'ux-panel-header-btn-td';
b.render(tr.appendChild(td));
}
}

}),

addHeaderButton: function(config, handler, scope)
{
var bc =
{
handler: handler,
scope: scope,
hideParent: true
};
if(typeof config == "string")
bc.text = config;
else
Ext.apply(bc, config);

var btn = new Ext.Button(bc);
btn.ownerCt = this;
if(!this.headerButtons)
this.headerButtons = [];

this.headerButtons.push(btn);
return btn;
}
});

var btns = panel.hbuttons;

panel.headerButtons = [];
for (var i = 0, len = btns.length; i < len; i++) {
if(btns[i].render)
panel.headerButtons.push(btns[i]);
else
panel.addHeaderButton(btns[i]);
}

delete panel.hbuttons;
}
}
});Plugin CSS:

.ux-panel-header-btns .icon-save
{
background: url(save_9.png) no-repeat;
}

.ux-panel-header-btns-ct
{
float: right;
}

.ux-panel-header-btns .x-btn
{
margin-left: 2px;
}

.ext-ie .ux-panel-header-btns .x-btn button
{
padding-top: 1px;
}

.ux-panel-header-btns .x-btn-icon .x-btn-center .x-btn-text
{
background-position: 0 2px;
height: 12px;
width: 9px;
}

.ux-panel-header-btns .x-btn-text-icon .x-btn-center .x-btn-text
{
background-position: 1px 3px;
padding: 0 0 0 11px;
}

.ext-ie .ux-panel-header-btns .x-btn-text-icon .x-btn-center .x-btn-text
{
padding: 1px 0 0 13px;
}

.ext-ie .ux-panel-header-btns .x-btn-text-icon .x-btn-center
{
padding-right: 4px;
}

.ux-panel-header-btns .x-btn-left
{
width: 2px;
height: 15px;
background: url(hd-btn-sprite.gif) no-repeat 0 0;
}

.ux-panel-header-btns .x-btn-right
{
width: 2px;
height: 15px;
background: url(hd-btn-sprite.gif) no-repeat 0 -15px;
}

.ux-panel-header-btns .x-btn-center
{
background: url(hd-btn-sprite.gif) repeat-x 0 -30px;
padding: 0 1px;
}

.ux-panel-header-btns .x-btn-left i, .ux-panel-header-btns .x-btn-right i
{
width: 2px;
}

.ux-panel-header-btns .x-btn-text
{
color: #3255B2;
}

.ux-panel-header-btns .x-btn-over .x-btn-text
{
color: #264390;
}

.ux-panel-header-btns .x-btn-pressed .x-btn-text
{
color: #264390;
}

.ux-panel-header-btns .x-btn-over .x-btn-left
{
background-position: 0 -45px;
}

.ux-panel-header-btns .x-btn-over .x-btn-right
{
background-position: 0 -60px;
}

.ux-panel-header-btns .x-btn-over .x-btn-center
{
background-position: 0 -75px;
}Sample:

var w = new Ext.Window(
{
title: 'Header Buttons',
width: 400,
height: 200,
bodyStyle:'padding:15px',
collapsible: true,
renderTo: Ext.getBody(),
html: 'This panel has header buttons.',
tools:
[
{
id: 'gear'
}
],
plugins: new Ext.ux.plugins.HeaderButtons(),
hbuttons:
[
{
text: 'Button 1',
menu: new Ext.menu.Menu(
{
items:
[
{
text: 'Option 1'
},
{
text: 'Option 2'
},
{
text: 'Option 3'
}
]
})
},
{
text: 'Button 2',
disabled: true
},
{
text: 'Button 3',
iconCls: 'icon-save'
}
]
});

w.show();Demo:
http://www.innovativetechsolutions.net/kb/extjs/examples/panel/headerbuttons.htm

NeonMonk
21 Jul 2008, 3:09 AM
I like!

userofit
21 Jul 2008, 10:25 AM
In IE, the title and the buttons are shown in 2 lines. Can you fix it?

mbajema
21 Jul 2008, 11:00 AM
Updates:
Buttons have style when pressed (toggle buttons now display correctly).
Full source with a working example attached to the original post._____
userofit: are you sure you're including all of the CSS styles. Here is a screenshot of it displaying correctly in IE:
http://extjs.com/forum/attachment.php?attachmentid=8241&stc=1&d=1216666470

userofit
22 Jul 2008, 12:24 PM
yes, I used your updated files.

----------------------------

ie6 problem fixed. change the file Ext.ux.plugins.HeaderButtons.js as follows (ie6 just needs the width to float right. The red text are added or changed):


if

(Ext.isIE6) {

Ext.util.CSS.createStyleSheet(".ux-panel-header-btns-ct-ie6 {float: right; width: 1px; }");

}





Ext.namespace('Ext.ux.plugins');

Ext.ux.plugins.HeaderButtons = function(config)
{
Ext.apply(this, config);
};





Ext.extend(Ext.ux.plugins.HeaderButtons, Ext.util.Observable,

{
init: function(panel)
{
if (panel.hbuttons)
{
Ext.apply(panel,
{
onRender: panel.onRender.createSequence(function(ct, position)
{
if (this.headerButtons && this.headerButtons.length > 0)
{
var tb = this.header.createChild(
{
cls: (Ext.isIE6) ? 'ux-panel-header-btns-ct-ie6' : 'ux-panel-header-btns-ct',
cn:
{
cls:"ux-panel-header-btns",
html:'<table cellspacing="0"><tbody><tr></tr></tbody></table><div class="x-clear"></div>'
}
}, this.header.first('span', true), true); // insert before header text (but after tools)





var tr = tb.getElementsByTagName('tr')[0];

for (var i = 0, len = this.headerButtons.length; i < len; i++)
{
var b = this.headerButtons[i];
var td = document.createElement('td');
td.className = 'ux-panel-header-btn-td';
b.render(tr.appendChild(td));
}
}





}),




addHeaderButton: function(config, handler, scope)

{
var bc =
{
handler: handler,
scope: scope,
hideParent: true
};
if(typeof config == "string")
bc.text = config;
else
Ext.apply(bc, config);





var btn = new Ext.Button(bc);

btn.ownerCt = this;
if(!this.headerButtons)
this.headerButtons = [];





this.headerButtons.push(btn);

return btn;
}
});





var btns = panel.hbuttons;




panel.headerButtons = [];

for (var i = 0, len = btns.length; i < len; i++) {
if(btns[i].render)
panel.headerButtons.push(btns[i]);
else
panel.addHeaderButton(btns[i]);
}





delete panel.hbuttons;

}
}


});

huoyan_21
22 Jul 2008, 4:18 PM
yes it is cool thanks
but IE can't display one row

feiichi
30 Jul 2008, 10:39 AM
That's really sweet!

Thank you, I'll definetely use it.

mbajema
6 Aug 2008, 11:13 AM
userofit: rather than changing the code, you could simply update the stylesheet to support ie6 as such:


.ext-ie6 .ux-panel-header-btns-ct
{
width: 1px;
}

userofit
6 Aug 2008, 12:23 PM
yes, yours is simpler

deka49
20 Apr 2009, 7:07 AM
thanks for this plugin

is it possible to center buttons ?