View Full Version : Tooltip to "capture" the target element which triggered it's showing.
Animal
12-19-2008, 06:04 AM
Sometimes, a single Tooltip instance can be used on a higher level element which should display different data depending upon where in that element the mouse is over.
A very good example is a tooltip of a GridPanel. Best thing is one ToolTip instance which knows what cell it is over.
But currently, there's no way it knows because the event that triggered it is gone, and the only thing ToolTip captures is the XY position.
I suggest
Ext.override(Ext.ToolTip, {
onTargetOver : function(e){
if(this.disabled || e.within(this.target.dom, true)){
return;
}
this.clearTimer('hide');
this.triggerElement = e.getTarget();
this.targetXY = e.getXY();
this.delayShow();
},
onMouseMove : function(e){
this.triggerElement = e.getTarget();
this.targetXY = e.getXY();
if(!this.hidden && this.trackMouse){
this.setPagePosition(this.getTargetXY());
}
},
});
Then a beforeshow handler can interrogate the tiggerElement, and find out what it is supposed to be displaying.
So if you were using the Tooltip in a GridPanel, you might do
var myGrid = grid;
function updateTipBody(tip) {
var i = myGrid.getView().findRowIndex(tip.triggerElement);
tip.body.dom.innerHTML = "Over row " + i;
}
myGrid.on('render', function() {
myGrid.tip = new Ext.ToolTip({
target: myGrid.getView().mainBody,
trackMouse: true,
renderTo: document.body,
autoHide: false,
listeners: {
beforeshow: updateTipBody,
move: updateTipBody
}
});
});
Condor
12-19-2008, 06:54 AM
+1
ps. Your updateTipBody method should really use some buffering, e.g.
function updateTipBody(tip) {
var rowIndex = myGrid.getView().findRowIndex(tip.triggerElement);
if (tip.rowIndex !== rowIndex) {
tip.rowIndex = rowIndex;
tip.body.update("Over row " + rowIndex);
}
}
(mouseover events get fired often)
Animal
12-19-2008, 07:15 AM
Very true, a bit of an iefficient sketch of what might be done.
Animal
12-19-2008, 07:17 AM
In fact, what might be better is a "delegate" option to tooltip which causes it to trigger a show when the mouse enters an element of the main target which matches a certain selector.
Obviously the triggerElement would be the selected matching element.
So we could do
myGrid.on('render', function() {
myGrid.tip = new Ext.ToolTip({
target: myGrid.getView().mainBody,
delegate: '.x-grid3-row',
listeners: {
beforeshow: updateTipBody
}
});
});
Animal
12-19-2008, 07:33 AM
Right, this is nice. A Delegate option which means that a single tooltop can handle multiple targets in a single target:
Ext.override(Ext.ToolTip, {
onTargetOver : function(e){
if(this.disabled || e.within(this.target.dom, true)){
return;
}
var t = e.getTarget(this.delegate);
if (t) {
this.triggerElement = t;
this.clearTimer('hide');
this.targetXY = e.getXY();
this.delayShow();
}
},
onMouseMove : function(e){
var t = e.getTarget(this.delegate);
if (t) {
this.targetXY = e.getXY();
if (t === this.triggerElement) {
if(!this.hidden && this.trackMouse){
this.setPagePosition(this.getTargetXY());
}
} else {
this.hide();
this.lastActive = new Date(0);
this.onTargetOver(e);
}
} else if (!this.closable && this.isVisible()) {
this.hide();
}
},
hide: function(){
this.clearTimer('dismiss');
this.lastActive = new Date();
delete this.triggerElement;
Ext.ToolTip.superclass.hide.call(this);
}
});
All code released under the WTF public license: http://sam.zoy.org/wtfpl/
Then simply:
myGrid.on('render', function() {
myGrid.tip = new Ext.ToolTip({
view: myGrid.getView(),
target: myGrid.getView().mainBody,
delegate: '.x-grid3-row',
trackMouse: true,
renderTo: document.body,
listeners: {
beforeshow: function updateTipBody(tip) {
tip.body.dom.innerHTML = "Over row " + tip.view.findRowIndex(tip.triggerElement);
}
}
});
});
No need for buffering in client code there. It only gets into onTargetOver if the target has changed.
Condor
12-19-2008, 08:01 AM
+2 - I really like this!
Now you can even use:
beforeshow: function updateTipBody(tip) {
tip.body.update('Over row ' + tip.triggerElement.rowIndex);
}
(triggerElement == row element)
mystix
12-19-2008, 09:33 AM
+3. i'm loving this :)
thejoker101
12-23-2008, 10:00 AM
Now you can even use:
beforeshow: function updateTipBody(tip) {
tip.body.update('Over row ' + tip.triggerElement.rowIndex);
}(triggerElement == row element)
That's assuming you use "delegate: '.x-grid3-row', ", if you use "delegate: '.x-grid3-col', " then you have to use "view.findRowIndex(tip.triggerElement)", right? Also, if you do use the '-col' you can use "view.findCellIndex(tip.triggerElement)" to find the column you're over if you need that for anything (I did).
Also, findRowIndex() and findCellIndex() are private, should they stay that way?
vmorale4
02-09-2009, 09:55 AM
+1 for this!
TommyMaintz
02-10-2009, 10:08 AM
Added this in revision 3082 with a slight modification to the onMouseMove function to have backward compatibility.
Tested the sample Animal provided with some additional quicktips on buttons in a toolbar. It seems to work properly.
If anyone experiences weird behaviour with QuickTips, ToolTips or Tips, please let me know.
mjlecomte
02-10-2009, 10:23 AM
Might be good to update the title of thread to say [added ver# rev#]
And/or indicate that this is for Ext3 only.
Animal
02-10-2009, 10:24 AM
I'll add some docs to it, and a simple example assuming a pre-constructed GridPanel.
vBulletin® v3.8.4, Copyright ©2000-2010, Jelsoft Enterprises Ltd.