PDA

View Full Version : How to put a tooltip on a menuitem?



mabra
14 Aug 2009, 8:49 AM
Hi All !

I have really to explain something on some rarely used and possibly not intentional understand menuitems and thought, it's a snap with tooltips. But it's not working. Then I found, that this is just not possible [http://extjs.com/forum/showthread.php?t=23854] (http://extjs.com/forum/showthread.php?t=23854%5D), but many users wish exactly this.

So I started to create the item manually and put an eventhandler for mouseover on it. But I cannot see the event mouseover on menuitem in the docs.

Is there any way to do this?

Thanks anyway.


br--mabra

Animal
14 Aug 2009, 9:29 AM
I helped someone out with this just two days ago. Do a search.

Animal
14 Aug 2009, 9:48 AM
Here's an override which gives Menu Items a tooltip config



Ext.override(Ext.menu.Item, {
onRender : function(container, position){
if (!this.itemTpl) {
this.itemTpl = Ext.menu.Item.prototype.itemTpl = new Ext.XTemplate(
'<a id="{id}" class="{cls}" hidefocus="true" unselectable="on" href="{href}"',
'<tpl if="hrefTarget">',
' target="{hrefTarget}"',
'</tpl>',
'>',
'<img src="{icon}" class="x-menu-item-icon {iconCls}"/>',
'<span class="x-menu-item-text">{text}</span>',
'</a>'
);
}
var a = this.getTemplateArgs();
this.el = position ? this.itemTpl.insertBefore(position, a, true) : this.itemTpl.append(container, a, true);
this.iconEl = this.el.child('img.x-menu-item-icon');
this.textEl = this.el.child('.x-menu-item-text');
if (this.tooltip) {
this.tooltip = new Ext.ToolTip(Ext.apply({
target: this.el
}, Ext.isObject(this.tooltip) ? this.toolTip : { html: this.tooltip }));
}
Ext.menu.Item.superclass.onRender.call(this, container, position);
}
});


I've submitted an Enhancement Request to add this.

mabra
15 Aug 2009, 2:54 AM
Hi Animal !

Much, much thanks for your help!!:)

Although, before I post, I usually search, but was not able to find it, until your reply .... sorry.

In that thread, I thought, it's too complicated for me - looks like, due to my javascript experience :( - I need years with ext, because one has to find everything in the forums ;)

Today, I'll sit down with you code sample and try to make it running. I bet, I'll get it ....;)

Thanks a lot!

br--mabra

Animal
15 Aug 2009, 4:17 AM
I've added an Enhancement Request to the internal system, so maybe all you have to do is wait.... maybe... It's only a small addition, so they could add it easily.

mabra
15 Aug 2009, 6:03 AM
Hi Animal!

Although, it's good the most of the time, to have that in the basic library, I am working on my first ext-app and cannot wait :-?

Thanks, for requesting this functionality to have in the basic lib!

To your code:If I include it - I made a separate short menu sample - a menu no longer appears, but without raising a script error [verified in IE/FF] ! I am calling your code in onready. I found a small typo - I think - and corrected it, but that was not the reason.

Inserted a double quote, changed from [in "onRender"]:

ext:qtip={tooltip}"'to:

ext:qtip="{tooltip}"'But the problem lies in "getTemplateArgs". If I reduce it to return:


return
{
//Omit everythings else from the code-sample
text: this.itemText||this.text||' '
};
the menu is visible again!

My menu is this:


var menu = new Ext.menu.Menu
(
{
id: 'basicMenu',
items:
[
{
id: '1',
text: 'An item',
handler: clickHandler
//tooltip: { title: 'Title', text: 'SomeText' }
},
new Ext.menu.Item({
text: 'Another item',
handler: clickHandler
}),
'-',
new Ext.menu.CheckItem({
text: 'A check item',
checkHandler: checkHandler
})
]
}
);

var mb = new Ext.SplitButton();
mb.render('menubutton');
mb.menu = menu;
I added an id to my menuitems, but that don't change anything. If I click on the button, a runtime error appears, pointing to the library. So, is there something wrong/missing in the override?

So, in opposite to my hope this noon, it looks like, I cannot make it running.

Could you possible give me a hint??

Thanks anyway!

br--mabra

Animal
15 Aug 2009, 6:07 AM
OK, I edited the code to add that quote.

Use a config like tooltip: 'Some help text'

Animal
15 Aug 2009, 6:36 AM
I changed the code agin. QuickTips is not very good for things with DOM structure. The latest code is much better.

mabra
16 Aug 2009, 5:54 AM
Hi Animal !

Thanks a lot for your ongoing help!

As I mentioned in one of my earlier post, the problem lies in the "getTemplateArgs" function [your first posted code for method]:


getTemplateArgs: function()
{
return {
id: this.id,
cls: this.itemCls + ....///snip
href: this.href || '#',
tooltip: this.tooltip,
hrefTarget: this.hrefTarget,
icon: this.icon || Ext.BLANK_IMAGE_URL,
iconCls: this.iconCls || '',
text: this.itemText || this.text || ' '
};
}
After I changed the method to this:


getTemplateArgs: function()
{
var result = {
id: this.id,
cls: this.itemCls + ... ///snip
href: this.href || '#',
tipCfg: this.tipCfg,
tooltip: this.tooltip,
hrefTarget: this.hrefTarget,
icon: this.icon || Ext.BLANK_IMAGE_URL,
iconCls: this.iconCls || '',
text: this.itemText || this.text || ' '
};
return result;
}
the GUI appears and the tooltips starts showing ...

I am not a jacscript guru and I really do not understand, why the original code does not work. I read some code, which works this way, especially functions, which return objects. And it was not an browser issue [different script implemenations]. I discovered this with debugging the code. Except for the "text" property, all other values were "undefined", until I made my change.

So, finally, I have a basic working example, thanks to your help.

Allow me a question about the code. In the "onRender" method, you are accessing "this.el = position ...". I "el" the ext element, and can I access this always [especially without a check]?

Anyway, thanks a lot!

br--mabra

Animal
16 Aug 2009, 12:36 PM
Look at the latest code! No getTemplateArgs. I create a ToolTip instance rather than relying on the QuickTips singleton.

mabra
16 Aug 2009, 3:49 PM
Hi Animal!

If you will excuse me, but this line is in your latest code:

var a = this.getTemplateArgs();
this.el = position ? this.itemTpl.insertBefore(position, a, true) : this.itemTpl.append(container, a, true);
Sorry! I refreshed my browser, just to be sure.

I have not understand everything therein, so I came to my question about the use of "this.el ...". This is, were you refer to the result of "getTemplateArgs".

I put my code here http://www.manfbraun.de/cont/tech/probs/ExtMenuWithTooltip2d.html , mostly to have it at company...

br--mabra

Animal
16 Aug 2009, 9:26 PM
So wgar are you saying? That it doesn't work somehow?

Animal
16 Aug 2009, 9:27 PM
Looks like you don't want trackMouse: true doesn't it? And autoHide: false if you want that to be fixed there until they click the "x" close tool.

mabra
17 Aug 2009, 8:22 AM
Hi Animal !

No, it IS working, but, as I wrote, the "getTemplateArgs" method is needed!!!!

Yes, I tried "trackMouse:true/false" to allow the user to click the help/close tools on the tooltip. But this was not of any help. If the user moves the mouse in the direction to the tools, the tooltip authides, anyway, what I have configed this property. If I would set "autoHide: false", this really would annoy the user, because this way, he has to close each tooltip manually ...

I'll try to make some additional script to find a workaround.

br--mabra

Animal
17 Aug 2009, 11:40 AM
That method is in Menu!

Just use



Ext.override(Ext.menu.Item, {
onRender : function(container, position){
if (!this.itemTpl) {
this.itemTpl = Ext.menu.Item.prototype.itemTpl = new Ext.XTemplate(
'<a id="{id}" class="{cls}" hidefocus="true" unselectable="on" href="{href}"',
'<tpl if="hrefTarget">',
' target="{hrefTarget}"',
'</tpl>',
'>',
'<img src="{icon}" class="x-menu-item-icon {iconCls}"/>',
'<span class="x-menu-item-text">{text}</span>',
'</a>'
);
}
var a = this.getTemplateArgs();
this.el = position ? this.itemTpl.insertBefore(position, a, true) : this.itemTpl.append(container, a, true);
this.iconEl = this.el.child('img.x-menu-item-icon');
this.textEl = this.el.child('.x-menu-item-text');
if (this.tooltip) {
this.tooltip = new Ext.ToolTip(Ext.apply({
target: this.el
}, Ext.isObject(this.tooltip) ? this.toolTip : { html: this.tooltip }));
}
Ext.menu.Item.superclass.onRender.call(this, container, position);
}
});


That's all you need.

There's nothing to work around.

Animal
17 Aug 2009, 11:45 AM
I'm at a loss to know why this thread is alive. That is performing exactly as you tell it for perform. You are adding weird configurations like tools, and a very long dismissDelay, and a weird offset so that it appears UNDER the mouse pointe instead of offset a little way.

mabra
17 Aug 2009, 4:40 PM
Hi !

I am very sorry, if this may bother you.

I feel, the content in my menu needs good explanation, so I display a long tooltip-text. To allow the user to read this completely, the longer "dismissDelay" is right. Even this may not be enough, so I enabled the tools for the displayed tooltip. I think ext offers this and this is really a good idea. If the user does not understand the meaning of the menu-item and/or the tooltip-text, he can just click the help button from the tools! I find, this is really a good thing [I will even integrate this in a simple help system with keyboard support, if my ext knowledge will allow me this some day].

It is more or less a matter of taste, but I cannot see, that this is weird.

The problem with my attempts is still, that the user can never reach the help button with his mouse, to click onto it. So I came to different settings for the menu-items, just to learn their behavior.

In the meantime, I attempted another solution:Open the tooltip by script and position it so, that the mouse it completely over it. So the user can move the mouse to the help-button. Astoundingly, if the user clicks that, it does not handle the click event.

I added this attempt to my experiment here: http://www.manfbraun.de/cont/tech/probs/ExtMenuWithTooltip2e.html

I am reading the docs, to better understand them. May be, I find other options, using listeners;Will see.

Anyway, thanks again for your help and opinion.

br--mabra

Animal
17 Aug 2009, 9:31 PM
You don't need all kinds of code and listeners. You need closable: true, autoHide: false if you want it to be there until the user clicks a close button. As in that first menu item.

The only thing there is hiding the tooltip on mousedown. Try changing that code to render the tooltip instance to the Menu's element.

"Astoundingly, if the user clicks that, it does not handle the click event" What????

mabra
18 Aug 2009, 12:54 PM
Hi !

Again, thanks for all your help, I have the final, nearly perfect solution!:)

My scripts were my attempt to close the tooltip, if the menuitem was left.
I found something out about the eventhandling, which helps me perfectly out!

With my previous variant one of my menuitems, one has to live with the problem, that
sometimes a tip is open for each menuitem ... ;-)

You may see it here: http://www.manfbraun.de/cont/tech/probs/ExtMenuWithTooltip2i.html

br--mabra

outaTiME
30 Sep 2011, 8:02 AM
Guys, i fix the trouble with opera ...

and update the override to use the same code of Ext.menu.Item (v. 3.4) ...


Ext.override(Ext.menu.Item, { onRender: function (container, position) {
if (!this.itemTpl) {
this.itemTpl = Ext.menu.Item.prototype.itemTpl = new Ext.XTemplate(
'<a id="{id}" class="{cls}" hidefocus="true" unselectable="on" href="{href}"',
'<tpl if="hrefTarget">',
' target="{hrefTarget}"',
'</tpl>',
'>',
'<img alt="{altText}" src="{icon}" class="x-menu-item-icon {iconCls}"/>',
'<span class="x-menu-item-text">{text}</span>',
'</a>'
);
}
var a = this.getTemplateArgs();
this.el = position ? this.itemTpl.insertBefore(position, a, true) : this.itemTpl.append(container, a, true);
this.iconEl = this.el.child('img.x-menu-item-icon');
this.textEl = this.el.child('.x-menu-item-text');
if (!this.href) {
this.mon(this.el, 'click', Ext.emptyFn, null, { preventDefault: true });
}
if (this.tooltip) {
if (Ext.isObject(this.tooltip)) {
Ext.QuickTips.register(Ext.apply({
target: this.el.id
}, this.tooltip));
} else {
this.el.dom['qtip'] = this.tooltip;
}
}
Ext.menu.Item.superclass.onRender.call(this, container, position);
}
});

one question ... im experimenting a "mousetrack" with tooltip code (this version and animal version) why ??? if qtip default was no mouse track ... some DOM logic ??