PDA

View Full Version : YAHOO.ext.ToolbarMenu class



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.

jack.slocum
11 Dec 2006, 8:09 PM
Nice. Any chance you have a page where I can see it in action? I'd set it up myself but setting up YUI menus is like setting up an entire application. ;)

mscifo
11 Dec 2006, 8:53 PM
Made a quick fix in the method YAHOO.ext.ToolbarMenu.prototype.initMenu above.

Jack, I pm'd you a url you can view. As far as the YUI menu code, I'm using an earlier version of whouseit's menu classes at http://www.yui-ext.com/forum/viewtopic.php?t=1246.

Animal
12 Dec 2006, 12:38 AM
I think enabling menus on a toolbar is a very good idea. Often, you want a few options to choose from. I can see this being useful in, say an email viewer.

It's not using the super-heavyweight YUI menu system, so I think it would fit right in. The YUI menu system is a bit overdone IMHO!

jack.slocum
12 Dec 2006, 6:49 AM
I agree Animal. This class seems very nice and as soon as I get a chance I will integrate it.

whouseit
12 Dec 2006, 7:05 PM
Made a quick fix in the method YAHOO.ext.ToolbarMenu.prototype.initMenu above.

Jack, I pm'd you a url you can view. As far as the YUI menu code, I'm using an earlier version of whouseit's menu classes at http://www.yui-ext.com/forum/viewtopic.php?t=1246.

Good job. When I first wrote the menu basing on YUI-EXT, because the YUI' menu
is too complex and difficult to use and there was no menu class in YUI-EXT, I had
to complete it. I saw the ToolBar class was so good, so I decided to write the menu
which was just like ToolBar and the menu should be indepent and have the common
menu functions like 'right click menu(contentMenu), sub-menu, dynamic add and delete
the menu item and sub menu', etc.
mscifo, your menu class looks better and can you provide one full example? So I
can integrate my function in it.
Thanks

Animal
13 Dec 2006, 12:35 AM
The only thing that's been slightly bugging me about the Toolbar class is that the MenuButtons are disposable.

You add them, and they are discarded. Only the generated DOM elements remain. You can never access a ToobarButton from a toolbar to check its status (disabled/hidden... whether a certain ID button is present, get an Array of them etc...)

galdaka
18 Jan 2007, 12:21 PM
functional example pleaseeeeeeeee. Yui-ext 0.40 would contain toolbarmenu?

ericd
20 Jan 2007, 6:04 AM
Looks very nice, but I have to ask.... is this thread dead? some examples are required... for example, menus, submenus, etc

Animal
20 Jan 2007, 6:28 AM
I don't think it's dead. When Jack says he's going to do something, he usually does. I think it's a matter of patience, Jack has obviously been at the coding coalface this week because he's only just surfaced today!

I'm sure we'll get supported ToolbarMenus soon enough!

jack.slocum
20 Jan 2007, 6:30 AM
The whole Toolbar code has finally been upgraded. Button, MenuButton, ToggleButton and groups are in there now. An items collection is also available. ToolbarItem was created for separators and text (allowing them to be hidden/removed). There's also some nice new theming.

ericd
20 Jan 2007, 9:01 AM
Oh please, I hope no one takes this the wrong way and of me showing signs of impatience, not at all like that. I though this code belonged to mscifo and was wondering if he had dropped it. I had no clue anyone else was involved in it. My apologies if anyone got offended

Eric


I don't think it's dead. When Jack says he's going to do something, he usually does. I think it's a matter of patience, Jack has obviously been at the coding coalface this week because he's only just surfaced today!

I'm sure we'll get supported ToolbarMenus soon enough!

jack.slocum
20 Jan 2007, 9:39 AM
Animal, I have been on quite the coding rampage. The next release has offcially been dubbed:

Ext 1.0

Along with all the new stuff and enhancements (Toolbar, Grid, Template, DomQuery, MessageBox, DD, QuickTips, Button, Themes, etc) I am also working on lightweight menus (finally). Once they are done, I will move back to finishing the grid (I had to take a break, I was gridded out ;)). There will also finally be a new website that glues everything together.

If it's going to be 1.0 (and I really like the idea of it), I want everything to be ready. Please bare with me. I will get something into SVN soon! :)

Animal
20 Jan 2007, 9:52 AM
I'm really looking forward to dumping YUI superheavyweight Menus! They are a pain.

The only widget we're now using from YUI is the Calendar. (Oh, and I put the Calendar in a YAHOO.widget.Overlay). I know you plan to refactor that, so that will go eventually, and I'll be down to YUI's Dom+Event+Anim+DD

Are you going to consult the forum about plans for the new Calendar control? I've just been working with a colleague on integrating the YUI Calendar int a larger control which inputs a Date+time combination, storing the result in ISO 8601 format (YYYY-MM-DDTHH:MM) in a hidden input. I have a lot of ideas for this input. Our app relies a lot on timelines - our vertical market is logistics.

jack.slocum
20 Jan 2007, 11:25 AM
I don't think I will try to duplicate the YUI Calendar. It has a lot of features and I want to keep it a simple DatePicker. When it does come time for the refactor, I will definitely get your input. Thanks!

ilazarte
22 Jan 2007, 9:01 AM
Best of luck Jack, we're rooting for ya! As for YCal, I think it's the only widget really usable out of the box ;)

jack.slocum
22 Jan 2007, 12:09 PM
In case anyone is interested, Menu and Toolbar screenshots:

http://www.yui-ext.com/forum/viewtopic.php?t=2273

vk_phoenixfr
25 Jan 2007, 1:34 AM
Thanx for the screencaps ! I can't wait to replace my yahoo basic menu with this one.
You're really doing a great job !!