mscifo
11 Dec 2006, 6:46 PM
This class will create a toolbar menu. If the 'useArrow' config property is set, then an arrow (or whatever image you specify in the css) will be appended next to the button. The 'arrowClick' config property can be used to indicate which function to call when the arrow is clicked. You can also click just the button to fire the normal 'click' config property. If the 'useArrow' config property is false (default), then no arrow will be appended next to the button and the normal 'click' action will fire (which you should change to whatever you would have put in the 'arrowClick' property).
Example usage:
var tb = new YAHOO.ext.Toolbar('tb');
tb.addMenu({
id:'buttonid',
className: 'b1',
click: this.clickButton1.createDelegate(this),
useArrow: true,
arrowClick: myMenu.showAt.createDelegate(myMenu, ['buttonid'])
});
tb.addMenu({
id:'buttonid2',
className: 'b2',
useArrow: false,
click: myMenu2.showAt.createDelegate(myMenu2, ['buttonid2'])
});
The javascript code...
/**
* Adds element(s) to the toolbar - this function takes a variable number of
* arguments of mixed type and adds them to the toolbar...
*
* @param {Mixed} arg If arg is a ToolbarButton, it is added. If arg is a string, it is wrapped
* in a ytb-text element and added unless the text is "separator" in which case a separator
* is added. Otherwise, it is assumed the element is an HTMLElement and it is added directly.
*/
YAHOO.ext.Toolbar.prototype.add = function() {
for(var i = 0; i < arguments.length; i++){
var el = arguments[i];
var td = document.createElement('td');
this.tr.appendChild(td);
if(el instanceof YAHOO.ext.ToolbarMenu){
el.initMenu(td);
}else if(el instanceof YAHOO.ext.ToolbarButton){
el.init(td);
}else if(el instanceof Array){
this.addButton(el);
}else if(typeof el == 'string'){
var span = document.createElement('span');
if(el == 'separator'){
span.className = 'ytb-sep';
}else{
span.innerHTML = el;
span.className = 'ytb-text';
}
td.appendChild(span);
}else if(typeof el == 'object' && el.nodeType){ // must be element?
td.appendChild(el);
}else if(typeof el == 'object'){ // must be button config?
this.addButton(el);
}
}
};
/**
* Add a menu (or menus), see {@link YAHOO.ext.ToolbarMenu} for more info on the config
* @param {Object/Array} config A menu config or array of configs
* @return {YAHOO.ext.ToolbarMenu/Array}
*/
YAHOO.ext.Toolbar.prototype.addMenu = function(config){
if(config instanceof Array){
var menus = [];
for(var i = 0, len = config.length; i < len; i++) {
menus.push(this.addMenu(config[i]));
}
return menus;
}
var b = config;
if(!(config instanceof YAHOO.ext.ToolbarMenu)){
b = new YAHOO.ext.ToolbarMenu(config);
}
this.add(b);
return b;
};
/**
* Inserts a menu (or menus) at the specified index
* @param {Number} index The index where the menus are to be inserted
* @param {Object/Array} config A menu config or array of configs
* @return {YAHOO.ext.ToolbarMenu/Array}
*/
YAHOO.ext.Toolbar.prototype.insertMenu = function(index, config){
if(config instanceof Array){
var menus = [];
for(var i = 0, len = config.length; i < len; i++) {
menus.push(this.insertMenu(index + i, config[i]));
}
return menus;
}
var b = new YAHOO.ext.ToolbarMenu(config);
var td = document.createElement('td');
var nextSibling = this.tr.childNodes[index];
if (nextSibling)
this.tr.insertBefore(td, nextSibling);
else
this.tr.appendChild(td);
b.init(td);
return b;
};
/**
* @class YAHOO.ext.ToolbarMenu
* Extends {@link YAHOO.ext.ToolbarButton} .
@extends YAHOO.ext.ToolbarButton
* A toolbar menu. The config has the following options:
* <ul>
* className - The CSS class for the button. Use this to attach a background image for an icon.
* text - The button's text
* tooltip - The buttons tooltip text
* click - function to call when the button is clicked, only used when usearrow is true
* useArrow - whether or not to include an arrow to activate the menu instead of the button
* arrowClick - function to call when the arrow is clicked, only used when usearrow is true
* mouseover - function to call when the mouse moves over the button
* mouseout - function to call when the mouse moves off the button
* scope - The scope of the above event handlers
*
*
* @constructor
* @param {Object} config
*/
YAHOO.ext.ToolbarMenu = function(config){
YAHOO.ext.util.Config.apply(this, config);
};
YAHOO.extendX(YAHOO.ext.ToolbarMenu, YAHOO.ext.ToolbarButton);
/** @private */
YAHOO.ext.ToolbarMenu.prototype.initMenu = function(appendTo) {
// build the normal ToolbarButton
this.init(appendTo);
var td = document.createElement('td');
appendTo.parentNode.appendChild(td);
appendTo = td;
if (this.useArrow) {
var arrow = document.createElement('span');
arrow.className = 'ytb-menu';
if (this.id) {
arrow.id = this.id += '_arrow';
}
var inner = document.createElement('span');
inner.className = 'ytb-menu-inner ' + this.className;
inner.unselectable = 'on';
if (this.tooltip) {
arrow.title = this.tooltip;
}
arrow.appendChild(inner);
appendTo.appendChild(arrow);
this.arrow = getEl(arrow, true);
this.arrow.unselectable();
inner.innerHTML = ' ';
this.arrowInner = inner;
this.arrow.mon('click', this.arrowClick, this, true);
this.arrow.mon('mouseover', this.onMouseOver, this, true);
this.arrow.mon('mouseout', this.onMouseOut, this, true);
this.el.removeClass('ytb-button');
this.el.addClass('ytb-button-menu');
getEl(this.inner).removeClass('ytb-button-inner');
getEl(this.inner).addClass('ytb-button-menu-inner');
} else {
this.el.mon('click', this.click, this, true);
}
};
/** @private */
YAHOO.ext.ToolbarMenu.prototype.onMouseOver = function(){
if(!this.disabled && this.useArrow) {
this.arrow.addClass('ytb-menu-over');
this.el.addClass('ytb-button-menu-over');
} else {
YAHOO.ext.ToolbarButton.prototype.onMouseOver.call(this);
}
};
/** @private */
YAHOO.ext.ToolbarMenu.prototype.onMouseOut = function(){
if (this.useArrow) {
this.arrow.removeClass('ytb-menu-over');
this.el.removeClass('ytb-button-menu-over');
} else {
YAHOO.ext.ToolbarButton.prototype.onMouseOut.call(this);
}
};
And here is the css....
Note: The image paths are relative the yui-ext/resources directory
Note: I had some trouble with the positioning of the arrow image so I manually modified the width/height/padding/margin properties to get it to fit properly. You will most likely need to do the same, unless someone wants to take a crack at making it universal.
.ytoolbar .ytb-menu {
display: block;
white-space: nowrap;
width: 11px;
}
.ytoolbar .ytb-menu-inner{
margin-top: 5px;
background-position: center;
background-repeat: no-repeat;
// specify the arrow image here
background-image: url(../images/down_arrow.gif);
cursor:pointer;
white-space: nowrap;
width: 12px;
height: 16px;
}
.ytoolbar .ytb-menu-disabled{
color:gray;
cursor:default;
}
.ytoolbar .ytb-menu-over{
background:#c3d3ed url(../images/toolbar/btn-over-bg.gif) repeat-x;
border-top:1px solid #6593cf;
border-bottom:1px solid #6593cf;
border-right:1px solid #6593cf;
width: 10px;
height: 19px;
}
.ytoolbar .ytb-button-menu-inner{
background-position: center;
background-repeat: no-repeat;
display: block;
height: 16px;
width: 16px;
cursor:pointer;
white-space: nowrap;
margin-right:-5px;
}
.ytoolbar .ytb-button-menu {
padding:2px 1px;
display:block;
}
.ytoolbar .ytb-button-menu-over {
background:#c3d3ed url(../images/toolbar/btn-over-bg.gif) repeat-x;
border:1px solid #6593cf;
padding:1px 0px;
}
Let me know if you have any suggestions, problems or fixes.
Example usage:
var tb = new YAHOO.ext.Toolbar('tb');
tb.addMenu({
id:'buttonid',
className: 'b1',
click: this.clickButton1.createDelegate(this),
useArrow: true,
arrowClick: myMenu.showAt.createDelegate(myMenu, ['buttonid'])
});
tb.addMenu({
id:'buttonid2',
className: 'b2',
useArrow: false,
click: myMenu2.showAt.createDelegate(myMenu2, ['buttonid2'])
});
The javascript code...
/**
* Adds element(s) to the toolbar - this function takes a variable number of
* arguments of mixed type and adds them to the toolbar...
*
* @param {Mixed} arg If arg is a ToolbarButton, it is added. If arg is a string, it is wrapped
* in a ytb-text element and added unless the text is "separator" in which case a separator
* is added. Otherwise, it is assumed the element is an HTMLElement and it is added directly.
*/
YAHOO.ext.Toolbar.prototype.add = function() {
for(var i = 0; i < arguments.length; i++){
var el = arguments[i];
var td = document.createElement('td');
this.tr.appendChild(td);
if(el instanceof YAHOO.ext.ToolbarMenu){
el.initMenu(td);
}else if(el instanceof YAHOO.ext.ToolbarButton){
el.init(td);
}else if(el instanceof Array){
this.addButton(el);
}else if(typeof el == 'string'){
var span = document.createElement('span');
if(el == 'separator'){
span.className = 'ytb-sep';
}else{
span.innerHTML = el;
span.className = 'ytb-text';
}
td.appendChild(span);
}else if(typeof el == 'object' && el.nodeType){ // must be element?
td.appendChild(el);
}else if(typeof el == 'object'){ // must be button config?
this.addButton(el);
}
}
};
/**
* Add a menu (or menus), see {@link YAHOO.ext.ToolbarMenu} for more info on the config
* @param {Object/Array} config A menu config or array of configs
* @return {YAHOO.ext.ToolbarMenu/Array}
*/
YAHOO.ext.Toolbar.prototype.addMenu = function(config){
if(config instanceof Array){
var menus = [];
for(var i = 0, len = config.length; i < len; i++) {
menus.push(this.addMenu(config[i]));
}
return menus;
}
var b = config;
if(!(config instanceof YAHOO.ext.ToolbarMenu)){
b = new YAHOO.ext.ToolbarMenu(config);
}
this.add(b);
return b;
};
/**
* Inserts a menu (or menus) at the specified index
* @param {Number} index The index where the menus are to be inserted
* @param {Object/Array} config A menu config or array of configs
* @return {YAHOO.ext.ToolbarMenu/Array}
*/
YAHOO.ext.Toolbar.prototype.insertMenu = function(index, config){
if(config instanceof Array){
var menus = [];
for(var i = 0, len = config.length; i < len; i++) {
menus.push(this.insertMenu(index + i, config[i]));
}
return menus;
}
var b = new YAHOO.ext.ToolbarMenu(config);
var td = document.createElement('td');
var nextSibling = this.tr.childNodes[index];
if (nextSibling)
this.tr.insertBefore(td, nextSibling);
else
this.tr.appendChild(td);
b.init(td);
return b;
};
/**
* @class YAHOO.ext.ToolbarMenu
* Extends {@link YAHOO.ext.ToolbarButton} .
@extends YAHOO.ext.ToolbarButton
* A toolbar menu. The config has the following options:
* <ul>
* className - The CSS class for the button. Use this to attach a background image for an icon.
* text - The button's text
* tooltip - The buttons tooltip text
* click - function to call when the button is clicked, only used when usearrow is true
* useArrow - whether or not to include an arrow to activate the menu instead of the button
* arrowClick - function to call when the arrow is clicked, only used when usearrow is true
* mouseover - function to call when the mouse moves over the button
* mouseout - function to call when the mouse moves off the button
* scope - The scope of the above event handlers
*
*
* @constructor
* @param {Object} config
*/
YAHOO.ext.ToolbarMenu = function(config){
YAHOO.ext.util.Config.apply(this, config);
};
YAHOO.extendX(YAHOO.ext.ToolbarMenu, YAHOO.ext.ToolbarButton);
/** @private */
YAHOO.ext.ToolbarMenu.prototype.initMenu = function(appendTo) {
// build the normal ToolbarButton
this.init(appendTo);
var td = document.createElement('td');
appendTo.parentNode.appendChild(td);
appendTo = td;
if (this.useArrow) {
var arrow = document.createElement('span');
arrow.className = 'ytb-menu';
if (this.id) {
arrow.id = this.id += '_arrow';
}
var inner = document.createElement('span');
inner.className = 'ytb-menu-inner ' + this.className;
inner.unselectable = 'on';
if (this.tooltip) {
arrow.title = this.tooltip;
}
arrow.appendChild(inner);
appendTo.appendChild(arrow);
this.arrow = getEl(arrow, true);
this.arrow.unselectable();
inner.innerHTML = ' ';
this.arrowInner = inner;
this.arrow.mon('click', this.arrowClick, this, true);
this.arrow.mon('mouseover', this.onMouseOver, this, true);
this.arrow.mon('mouseout', this.onMouseOut, this, true);
this.el.removeClass('ytb-button');
this.el.addClass('ytb-button-menu');
getEl(this.inner).removeClass('ytb-button-inner');
getEl(this.inner).addClass('ytb-button-menu-inner');
} else {
this.el.mon('click', this.click, this, true);
}
};
/** @private */
YAHOO.ext.ToolbarMenu.prototype.onMouseOver = function(){
if(!this.disabled && this.useArrow) {
this.arrow.addClass('ytb-menu-over');
this.el.addClass('ytb-button-menu-over');
} else {
YAHOO.ext.ToolbarButton.prototype.onMouseOver.call(this);
}
};
/** @private */
YAHOO.ext.ToolbarMenu.prototype.onMouseOut = function(){
if (this.useArrow) {
this.arrow.removeClass('ytb-menu-over');
this.el.removeClass('ytb-button-menu-over');
} else {
YAHOO.ext.ToolbarButton.prototype.onMouseOut.call(this);
}
};
And here is the css....
Note: The image paths are relative the yui-ext/resources directory
Note: I had some trouble with the positioning of the arrow image so I manually modified the width/height/padding/margin properties to get it to fit properly. You will most likely need to do the same, unless someone wants to take a crack at making it universal.
.ytoolbar .ytb-menu {
display: block;
white-space: nowrap;
width: 11px;
}
.ytoolbar .ytb-menu-inner{
margin-top: 5px;
background-position: center;
background-repeat: no-repeat;
// specify the arrow image here
background-image: url(../images/down_arrow.gif);
cursor:pointer;
white-space: nowrap;
width: 12px;
height: 16px;
}
.ytoolbar .ytb-menu-disabled{
color:gray;
cursor:default;
}
.ytoolbar .ytb-menu-over{
background:#c3d3ed url(../images/toolbar/btn-over-bg.gif) repeat-x;
border-top:1px solid #6593cf;
border-bottom:1px solid #6593cf;
border-right:1px solid #6593cf;
width: 10px;
height: 19px;
}
.ytoolbar .ytb-button-menu-inner{
background-position: center;
background-repeat: no-repeat;
display: block;
height: 16px;
width: 16px;
cursor:pointer;
white-space: nowrap;
margin-right:-5px;
}
.ytoolbar .ytb-button-menu {
padding:2px 1px;
display:block;
}
.ytoolbar .ytb-button-menu-over {
background:#c3d3ed url(../images/toolbar/btn-over-bg.gif) repeat-x;
border:1px solid #6593cf;
padding:1px 0px;
}
Let me know if you have any suggestions, problems or fixes.