182 lines
6.0 KiB
JavaScript
182 lines
6.0 KiB
JavaScript
|
|
/*
|
||
|
|
* Ext JS Library 2.3.0
|
||
|
|
* Copyright(c) 2006-2009, Ext JS, LLC.
|
||
|
|
* licensing@extjs.com
|
||
|
|
*
|
||
|
|
* http://extjs.com/license
|
||
|
|
*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @class Ext.SplitButton
|
||
|
|
* @extends Ext.Button
|
||
|
|
* A split button that provides a built-in dropdown arrow that can fire an event separately from the default
|
||
|
|
* click event of the button. Typically this would be used to display a dropdown menu that provides additional
|
||
|
|
* options to the primary button action, but any custom handler can provide the arrowclick implementation. Example usage:
|
||
|
|
* <pre><code>
|
||
|
|
// display a dropdown menu:
|
||
|
|
new Ext.SplitButton({
|
||
|
|
renderTo: 'button-ct', // the container id
|
||
|
|
text: 'Options',
|
||
|
|
handler: optionsHandler, // handle a click on the button itself
|
||
|
|
menu: new Ext.menu.Menu({
|
||
|
|
items: [
|
||
|
|
// these items will render as dropdown menu items when the arrow is clicked:
|
||
|
|
{text: 'Item 1', handler: item1Handler},
|
||
|
|
{text: 'Item 2', handler: item2Handler}
|
||
|
|
]
|
||
|
|
})
|
||
|
|
});
|
||
|
|
|
||
|
|
// Instead of showing a menu, you provide any type of custom
|
||
|
|
// functionality you want when the dropdown arrow is clicked:
|
||
|
|
new Ext.SplitButton({
|
||
|
|
renderTo: 'button-ct',
|
||
|
|
text: 'Options',
|
||
|
|
handler: optionsHandler,
|
||
|
|
arrowHandler: myCustomHandler
|
||
|
|
});
|
||
|
|
</code></pre>
|
||
|
|
* @cfg {Function} arrowHandler A function called when the arrow button is clicked (can be used instead of click event)
|
||
|
|
* @cfg {String} arrowTooltip The title attribute of the arrow
|
||
|
|
* @constructor
|
||
|
|
* Create a new menu button
|
||
|
|
* @param {Object} config The config object
|
||
|
|
*/
|
||
|
|
Ext.SplitButton = Ext.extend(Ext.Button, {
|
||
|
|
// private
|
||
|
|
arrowSelector : 'button:last',
|
||
|
|
|
||
|
|
// private
|
||
|
|
initComponent : function(){
|
||
|
|
Ext.SplitButton.superclass.initComponent.call(this);
|
||
|
|
/**
|
||
|
|
* @event arrowclick
|
||
|
|
* Fires when this button's arrow is clicked
|
||
|
|
* @param {MenuButton} this
|
||
|
|
* @param {EventObject} e The click event
|
||
|
|
*/
|
||
|
|
this.addEvents("arrowclick");
|
||
|
|
},
|
||
|
|
|
||
|
|
// private
|
||
|
|
onRender : function(ct, position){
|
||
|
|
// this is one sweet looking template!
|
||
|
|
var tpl = new Ext.Template(
|
||
|
|
'<table cellspacing="0" class="x-btn-menu-wrap x-btn"><tr><td>',
|
||
|
|
'<table cellspacing="0" class="x-btn-wrap x-btn-menu-text-wrap"><tbody>',
|
||
|
|
'<tr><td class="x-btn-left"><i> </i></td><td class="x-btn-center"><button class="x-btn-text" type="{1}">{0}</button></td></tr>',
|
||
|
|
"</tbody></table></td><td>",
|
||
|
|
'<table cellspacing="0" class="x-btn-wrap x-btn-menu-arrow-wrap"><tbody>',
|
||
|
|
'<tr><td class="x-btn-center"><button class="x-btn-menu-arrow-el" type="button"> </button></td><td class="x-btn-right"><i> </i></td></tr>',
|
||
|
|
"</tbody></table></td></tr></table>"
|
||
|
|
);
|
||
|
|
var btn, targs = [this.text || ' ', this.type];
|
||
|
|
if(position){
|
||
|
|
btn = tpl.insertBefore(position, targs, true);
|
||
|
|
}else{
|
||
|
|
btn = tpl.append(ct, targs, true);
|
||
|
|
}
|
||
|
|
var btnEl = this.btnEl = btn.child(this.buttonSelector);
|
||
|
|
|
||
|
|
this.initButtonEl(btn, btnEl);
|
||
|
|
this.arrowBtnTable = btn.child("table:last");
|
||
|
|
this.arrowEl = btn.child(this.arrowSelector);
|
||
|
|
if(this.arrowTooltip){
|
||
|
|
this.arrowEl.dom[this.tooltipType] = this.arrowTooltip;
|
||
|
|
}
|
||
|
|
},
|
||
|
|
|
||
|
|
// private
|
||
|
|
autoWidth : function(){
|
||
|
|
if(this.el){
|
||
|
|
var tbl = this.el.child("table:first");
|
||
|
|
var tbl2 = this.el.child("table:last");
|
||
|
|
this.el.setWidth("auto");
|
||
|
|
tbl.setWidth("auto");
|
||
|
|
if(Ext.isIE7 && Ext.isStrict){
|
||
|
|
var ib = this.btnEl;
|
||
|
|
if(ib && ib.getWidth() > 20){
|
||
|
|
ib.clip();
|
||
|
|
ib.setWidth(Ext.util.TextMetrics.measure(ib, this.text).width+ib.getFrameWidth('lr'));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if(this.minWidth){
|
||
|
|
if((tbl.getWidth()+tbl2.getWidth()) < this.minWidth){
|
||
|
|
tbl.setWidth(this.minWidth-tbl2.getWidth());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
this.el.setWidth(tbl.getWidth()+tbl2.getWidth());
|
||
|
|
}
|
||
|
|
},
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Sets this button's arrow click handler.
|
||
|
|
* @param {Function} handler The function to call when the arrow is clicked
|
||
|
|
* @param {Object} scope (optional) Scope for the function passed above
|
||
|
|
*/
|
||
|
|
setArrowHandler : function(handler, scope){
|
||
|
|
this.arrowHandler = handler;
|
||
|
|
this.scope = scope;
|
||
|
|
},
|
||
|
|
|
||
|
|
// private
|
||
|
|
onClick : function(e){
|
||
|
|
e.preventDefault();
|
||
|
|
if(!this.disabled){
|
||
|
|
if(e.getTarget(".x-btn-menu-arrow-wrap")){
|
||
|
|
if(this.menu && !this.menu.isVisible() && !this.ignoreNextClick){
|
||
|
|
this.showMenu();
|
||
|
|
}
|
||
|
|
this.fireEvent("arrowclick", this, e);
|
||
|
|
if(this.arrowHandler){
|
||
|
|
this.arrowHandler.call(this.scope || this, this, e);
|
||
|
|
}
|
||
|
|
}else{
|
||
|
|
if(this.enableToggle){
|
||
|
|
this.toggle();
|
||
|
|
}
|
||
|
|
this.fireEvent("click", this, e);
|
||
|
|
if(this.handler){
|
||
|
|
this.handler.call(this.scope || this, this, e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
|
||
|
|
// private
|
||
|
|
getClickEl : function(e, isUp){
|
||
|
|
if(!isUp){
|
||
|
|
return (this.lastClickEl = e.getTarget("table", 10, true));
|
||
|
|
}
|
||
|
|
return this.lastClickEl;
|
||
|
|
},
|
||
|
|
|
||
|
|
onDisableChange: function(disabled){
|
||
|
|
Ext.SplitButton.superclass.onDisableChange.call(this, disabled);
|
||
|
|
if(this.arrowEl){
|
||
|
|
this.arrowEl.dom.disabled = disabled;
|
||
|
|
}
|
||
|
|
},
|
||
|
|
|
||
|
|
// private
|
||
|
|
isMenuTriggerOver : function(e){
|
||
|
|
return this.menu && e.within(this.arrowBtnTable) && !e.within(this.arrowBtnTable, true);
|
||
|
|
},
|
||
|
|
|
||
|
|
// private
|
||
|
|
isMenuTriggerOut : function(e, internal){
|
||
|
|
return this.menu && !e.within(this.arrowBtnTable);
|
||
|
|
},
|
||
|
|
|
||
|
|
// private
|
||
|
|
onDestroy : function(){
|
||
|
|
Ext.destroy(this.arrowBtnTable);
|
||
|
|
Ext.SplitButton.superclass.onDestroy.call(this);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
// backwards compat
|
||
|
|
Ext.MenuButton = Ext.SplitButton;
|
||
|
|
|
||
|
|
|
||
|
|
Ext.reg('splitbutton', Ext.SplitButton);
|