PDA

View Full Version : Problems when positioning Rich HTML Balloon Tooltip



mike_k12003
02-18-2009, 08:03 AM
1) Script Title: Rich HTML Balloon Tooltip

2) Script URL (on DD):
http://www.dynamicdrive.com/dynamicindex5/balloontooltip.htm

3) Describe problem:
I have a div with a scrollbar and links inside it. for links appearing without scrolling the div the ballontip show fine but as you scroll the div the balloontip goes further and further down, it is as if the javascript calculates the position the link would have if it weren't inside the div, a friend suggested adding the scrollTop property but I am cluless where. I have searching two months for a solution and founded nothing can anyone help?
Many thanks for your time

Snookerman
02-18-2009, 08:17 AM
Please post a link to the page on your site that contains the problematic script or attach your code so we can check it out and help you.

mike_k12003
02-18-2009, 10:50 AM
Go here (http://www.pournara.gr/temp/a11.JPG) to see what I get. My coursor is above the 2nd (visible) row but the ballontip is way lower

I have a div in which I put a scroll through css
and then populate it dynamically with the content of a database table.
The CSS part is this


#Layerartist{
scrollbar-base-color: #3e808e;
scrollbar-arrow-color: #ffffff;
scrollbar-face-color: #3e808e;
scrollbar-track-color: #c1d4e0;
scrollbar-width:1px;
width:558px;
height:300px;
z-index:1;
visibility: no;
overflow: auto;
font:Verdana, Arial, Helvetica, sans-serif;
}

and in my php page after I declare


<script type="text/javascript" src="js/balloontip.js">
/***********************************************
* Rich HTML Balloon Tooltip- Dynamic Drive DHTML code library (www.dynamicdrive.com)
* This notice MUST stay intact for legal use
* Visit Dynamic Drive at http://www.dynamicdrive.com/ for full source code
***********************************************/
</script>

I use this


<tr>
<td colspan="2">
<table width="556">
<tr>
<td width="86" class="tdheders">ΕΙΔΟΣ</td>
<td width="154" class="tdheders">ΤΙΤΛΟΣ ALBUM</td>
<td width="149" class="tdheders">ΤΡΑΓΟΥΔΙΣΤΗΣ</td>
<td width="147" class="tdheders">ΚΑΤΗΓΟΡΙΑ</td>
</tr>
</table> </td>
</tr>

<tr>
<td >
<div id=Layerartist>
<table width="539">
<?php
$bb=0;
$c1=1;
$acnt=count($cd_data);
for($aa=0; $aa<$acnt; $aa++ ) {
if ($cd_data[$aa]['songer']==$description)
{
$code=$cd_data[$aa]['Code'];
?>
<tr >
<td class="tdcontain<?php if(($c1%2)==0){ echo "A"; } ?> " width="86" ><?php echo $cd_data[$aa]['eidos']; ?></td>
<td class="tdcontain<?php if(($c1%2)==0){ echo "A"; } ?> " width="154">
<div id="balloon<?php echo $aa; ?>" class="balloonstyle" style="width:300px;background-image:url(images/big_area_bg.jpg) ; background-repeat:repeat-y">
<table>
<tr>
<td align="left">
<?php
$Qtimi= mssql_query("select retailprice,aa from clroot.material where code=$code");
$Rtimi=mssql_fetch_array($Qtimi);
$timi1=round("$Rtimi[0]");
if ($timi1>$Rtimi[0]) $timi1=$timi1-1;
$timi11=stristr("$Rtimi[0]",".");
$timi2=substr($timi11,0,3);
$timi=$timi1.$timi2;

if (file_exists("./UserFiles/Image/$code.jpg"))
{
$imname="$code.jpg";

}
else
{
$imname="gm_song.jpg";
}
?>
<img src="UserFiles/Image/<?php echo $imname; ?>" width="142"/>
</td>
<td align="left">
<span style="color: #000078; font-size:13px ; font-weight: 800;"><?php echo $timi." ";?>&euro;</span>
<br/>
<div id="container">
<?php
$id=str_replace(".","",$code);
echo rating_bar($id,5,'static');
?>
</div>
ΚΩΔ.: <?php echo $code; ?>
</td>
</tr>
</table>
</div>
<a href="?var=&page=7&kwd=<?php echo $cd_data[$aa]['Code']; ?>" rel="balloon<?php echo $aa;?>"><?php echo $cd_data[$aa]['description']; ?></a>
</td>
<td class="tdcontain<?php if(($c1%2)==0){ echo "A"; } ?> " width="148" ><a href="?var=<?php echo $var; ?>&page=7&kwd=<?php echo $cd_data[$aa]['songer_code']; ?>"><a href="?var=<?php echo $var; ?>&page=7&kwd=<?php echo $cd_data[$aa]['songer_code']; ?>"><?php echo $cd_data[$aa]['songer']; ?></a></td>
<td width="131" class="tdcontain<?php if(($c1%2)==0){ echo "A"; } ?>"><?php echo $cd_data[$aa]['album_category']; ?></td>
</tr>

<?php $c1++;
}//1o if

}//for
?>
</table>
</div> </td>
</tr>

I didn't included this in my first post cause the population of the table inside the div actually doesn't matter but give it here for a broader view of what I am doing)
as said in the 1st post, the ballontip shows in the place each link would have been if out of the scrolling div (e.g. for a link way at the bottom of the div the ballontip will be displayed somewhere at the bottom of the page and not at the correct place within the div)
Certainly at fault is the positioning the balloontip.js which follows


//Rich HTML Balloon Tooltip: http://www.dynamicdrive.com/dynamicindex5/balloontooltip.htm
//Created: September 10th, 2006

var disappeardelay=250 //tooltip disappear delay (in miliseconds)
var verticaloffset=0 //vertical offset of tooltip from anchor link, if any
var enablearrowhead=1 //0 or 1, to disable or enable the arrow image
var arrowheadimg=["arrowdown.gif", "arrowup.gif"] //path to down and up arrow images
var arrowheadheight=11 //height of arrow image (amount to reveal)

/////No further editting needed

var ie=document.all
var ns6=document.getElementById&&!document.all
verticaloffset=(enablearrowhead)? verticaloffset+arrowheadheight : verticaloffset

function getposOffset(what, offsettype){
var totaloffset=(offsettype=="left")? what.offsetLeft : what.offsetTop;
var parentEl=what.offsetParent;
while (parentEl!=null){
totaloffset=(offsettype=="left")? totaloffset+parentEl.offsetLeft : totaloffset+parentEl.offsetTop;
parentEl=parentEl.offsetParent;
}
return totaloffset;
}

function showhide(obj, e){
dropmenuobj.style.left=dropmenuobj.style.top="-500px"
if (e.type=="mouseover")
obj.visibility="visible"
}

function iecompattest(){
return (document.compatMode && document.compatMode!="BackCompat")? document.documentElement : document.body
}

function clearbrowseredge(obj, whichedge){
if (whichedge=="rightedge"){
edgeoffsetx=0
var windowedge=ie && !window.opera? iecompattest().scrollLeft+iecompattest().clientWidth-15 : window.pageXOffset+window.innerWidth-15
dropmenuobj.contentmeasure=dropmenuobj.offsetWidth
if (windowedge-dropmenuobj.x < dropmenuobj.contentmeasure)
edgeoffsetx=dropmenuobj.contentmeasure-obj.offsetWidth
return edgeoffsetx
}
else{
edgeoffsety=0
var topedge=ie && !window.opera? iecompattest().scrollTop : window.pageYOffset
var windowedge=ie && !window.opera? iecompattest().scrollTop+iecompattest().clientHeight-15 : window.pageYOffset+window.innerHeight-18
dropmenuobj.contentmeasure=dropmenuobj.offsetHeight
if (windowedge-dropmenuobj.y < dropmenuobj.contentmeasure) //move up?
edgeoffsety=dropmenuobj.contentmeasure+obj.offsetHeight+(verticaloffset*2)
return edgeoffsety
}
}

function displayballoontip(obj, e){ //main ballooon tooltip function
if (window.event) event.cancelBubble=true
else if (e.stopPropagation) e.stopPropagation()
if (typeof dropmenuobj!="undefined") //hide previous tooltip?
dropmenuobj.style.visibility="hidden"
clearhidemenu()
//obj.onmouseout=delayhidemenu
dropmenuobj=document.getElementById(obj.getAttribute("rel"))
showhide(dropmenuobj.style, e)
dropmenuobj.x=getposOffset(obj, "left")
dropmenuobj.y=getposOffset(obj, "top")+verticaloffset
dropmenuobj.style.left=dropmenuobj.x-clearbrowseredge(obj, "rightedge")+"px"
dropmenuobj.style.top=dropmenuobj.y-clearbrowseredge(obj, "bottomedge")+obj.offsetHeight+"px"
if (enablearrowhead)
displaytiparrow()
}

function displaytiparrow(){ //function to display optional arrow image associated with tooltip
tiparrow=document.getElementById("arrowhead")
tiparrow.src=(edgeoffsety!=0)? arrowheadimg[0] : arrowheadimg[1]
var ieshadowwidth=(dropmenuobj.filters && dropmenuobj.filters[0])? dropmenuobj.filters[0].Strength-1 : 0
//modify "left" value depending on whether there's no room on right edge of browser to display it, respectively
tiparrow.style.left=(edgeoffsetx!=0)? parseInt(dropmenuobj.style.left)+dropmenuobj.offsetWidth-tiparrow.offsetWidth-10+"px" : parseInt(dropmenuobj.style.left)+5+"px"
//modify "top" value depending on whether there's no room on right edge of browser to display it, respectively
tiparrow.style.top=(edgeoffsety!=0)? parseInt(dropmenuobj.style.top)+dropmenuobj.offsetHeight-tiparrow.offsetHeight-ieshadowwidth+arrowheadheight+"px" : parseInt(dropmenuobj.style.top)-arrowheadheight+"px"
tiparrow.style.visibility="visible"
}

function delayhidemenu(){
delayhide=setTimeout("dropmenuobj.style.visibility='hidden'; dropmenuobj.style.left=0; if (enablearrowhead) tiparrow.style.visibility='hidden'",disappeardelay)
}

function clearhidemenu(){
if (typeof delayhide!="undefined")
clearTimeout(delayhide)
}

function reltoelement(linkobj){ //tests if a link has "rel" defined and it's the ID of an element on page
var relvalue=linkobj.getAttribute("rel")
return (relvalue!=null && relvalue!="" && document.getElementById(relvalue)!=null && document.getElementById(relvalue).className=="balloonstyle")? true : false
}

function initalizetooltip(){
var all_links=document.getElementsByTagName("a")
if (enablearrowhead){
tiparrow=document.createElement("img")
tiparrow.setAttribute("src", arrowheadimg[0])
tiparrow.setAttribute("id", "arrowhead")
document.body.appendChild(tiparrow)
}
for (var i=0; i<all_links.length; i++){
if (reltoelement(all_links[i])){ //if link has "rel" defined and it's the ID of an element on page
all_links[i].onmouseover=function(e){
var evtobj=window.event? window.event : e
displayballoontip(this, evtobj)
}
all_links[i].onmouseout=delayhidemenu
}
}
}

if (window.addEventListener)
window.addEventListener("load", initalizetooltip, false)
else if (window.attachEvent)
window.attachEvent("onload", initalizetooltip)
else if (document.getElementById)
window.onload=initalizetooltip

But what should I fix?

codeexploiter
02-18-2009, 10:53 AM
Can you post a link where the issue is visible?

mike_k12003
02-18-2009, 12:41 PM
OK go here (http://www.generalmusic.gr/demo/index.php?var=3&page=7&kwd=9.00001&img=) scroll the div and go the cursor to a link, notice that as you go to links further down the balloontip goes lower. Iam sure that the I must add something to ballontip.js and the advice of a friend to use scrollTop property is correct (somehow to substract from the total vertical postion the amount of vertical scrolling) but I do not know which line to modify

mike_k12003
02-20-2009, 08:12 AM
OK after some mods in lines 17 and 20 where substracted the scrollTop property (in the function getposOffset when putting a value in totalofset) the javasrcipt runs fine in IE but not on firefox/safari. Why? plz somenone help further again the link is this (http://www.generalmusic.gr/demo/index.php?var=3&page=7&kwd=9.00001&img=)
The ballontip.js now is


//Rich HTML Balloon Tooltip: http://www.dynamicdrive.com/dynamicindex5/balloontooltip.htm
//Created: September 10th, 2006

var disappeardelay=250 //tooltip disappear delay (in miliseconds)
var verticaloffset=0 //vertical offset of tooltip from anchor link, if any
var enablearrowhead=1 //0 or 1, to disable or enable the arrow image
var arrowheadimg=["images/arrowdown.gif", "images/arrowup.gif"] //path to down and up arrow images
var arrowheadheight=14 //height of arrow image (amount to reveal)

/////No further editting needed

var ie=document.all
var ns6=document.getElementById&&!document.all
verticaloffset=(enablearrowhead)? verticaloffset+arrowheadheight : verticaloffset;

function getposOffset(what, offsettype){
var totaloffset=(offsettype=="left")? what.offsetLeft-what.scrollLeft : what.offsetTop-what.scrollTop;
var parentEl=what.offsetParent;
while (parentEl!=null){
totaloffset=(offsettype=="left")? totaloffset+parentEl.offsetLeft-parentEl.scrollLeft : totaloffset+parentEl.offsetTop-parentEl.scrollTop;
parentEl=parentEl.offsetParent;
}
return totaloffset;
}

function showhide(obj, e){
dropmenuobj.style.left=dropmenuobj.style.top="-500px"
if (e.type=="mouseover")
obj.visibility="visible"
}

function iecompattest(){
return (document.compatMode && document.compatMode!="BackCompat")? document.documentElement : document.body
}

function clearbrowseredge(obj, whichedge){
if (whichedge=="rightedge"){
edgeoffsetx=0
var windowedge=ie && !window.opera? iecompattest().scrollLeft+iecompattest().clientWidth-15 : window.pageXOffset+window.innerWidth-15
dropmenuobj.contentmeasure=dropmenuobj.offsetWidth
if (windowedge-dropmenuobj.x < dropmenuobj.contentmeasure)
edgeoffsetx=dropmenuobj.contentmeasure-obj.offsetWidth
return edgeoffsetx
}
else{
edgeoffsety=0
var topedge=ie && !window.opera? iecompattest().scrollTop : window.pageYOffset
var windowedge=ie && !window.opera? iecompattest().scrollTop+iecompattest().clientHeight-15 : window.pageYOffset+window.innerHeight-18
dropmenuobj.contentmeasure=dropmenuobj.offsetHeight
if (windowedge-dropmenuobj.y < dropmenuobj.contentmeasure) //move up?
edgeoffsety=dropmenuobj.contentmeasure+obj.offsetHeight+(verticaloffset*2)
return edgeoffsety
}
}

function displayballoontip(obj, e){ //main ballooon tooltip function
if (window.event) event.cancelBubble=true
else if (e.stopPropagation) e.stopPropagation()
if (typeof dropmenuobj!="undefined") //hide previous tooltip?
dropmenuobj.style.visibility="hidden"
clearhidemenu()
//obj.onmouseout=delayhidemenu
dropmenuobj=document.getElementById(obj.getAttribute("rel"))
showhide(dropmenuobj.style, e)
dropmenuobj.x=getposOffset(obj, "left")
dropmenuobj.y=getposOffset(obj, "top")+verticaloffset
dropmenuobj.style.left=dropmenuobj.x-clearbrowseredge(obj, "rightedge")+"px"
dropmenuobj.style.top=dropmenuobj.y-clearbrowseredge(obj, "bottomedge")+obj.offsetHeight+"px"
if (enablearrowhead)
displaytiparrow()
}

function displaytiparrow(){ //function to display optional arrow image associated with tooltip
tiparrow=document.getElementById("arrowhead")
tiparrow.src=(edgeoffsety!=0)? arrowheadimg[0] : arrowheadimg[1]
var ieshadowwidth=(dropmenuobj.filters && dropmenuobj.filters[0])? dropmenuobj.filters[0].Strength-1 : 0
//modify "left" value depending on whether there's no room on right edge of browser to display it, respectively
tiparrow.style.left=(edgeoffsetx!=0)? parseInt(dropmenuobj.style.left)+dropmenuobj.offsetWidth-tiparrow.offsetWidth-10+"px" : parseInt(dropmenuobj.style.left)+5+"px"
//modify "top" value depending on whether there's no room on right edge of browser to display it, respectively
tiparrow.style.top=(edgeoffsety!=0)? parseInt(dropmenuobj.style.top)+dropmenuobj.offsetHeight-tiparrow.offsetHeight-ieshadowwidth+arrowheadheight+"px" : parseInt(dropmenuobj.style.top)-arrowheadheight+"px"
tiparrow.style.visibility="visible"
}

function delayhidemenu(){
delayhide=setTimeout("dropmenuobj.style.visibility='hidden'; dropmenuobj.style.left=0; if (enablearrowhead) tiparrow.style.visibility='hidden'",disappeardelay)
}

function clearhidemenu(){
if (typeof delayhide!="undefined")
clearTimeout(delayhide)
}

function reltoelement(linkobj){ //tests if a link has "rel" defined and it's the ID of an element on page
var relvalue=linkobj.getAttribute("rel")
return (relvalue!=null && relvalue!="" && document.getElementById(relvalue)!=null && document.getElementById(relvalue).className=="balloonstyle")? true : false
}

function initalizetooltip(){
var all_links=document.getElementsByTagName("a")
if (enablearrowhead){
tiparrow=document.createElement("img")
tiparrow.setAttribute("src", arrowheadimg[0])
tiparrow.setAttribute("id", "arrowhead")
document.body.appendChild(tiparrow)
}
for (var i=0; i<all_links.length; i++){
if (reltoelement(all_links[i])){ //if link has "rel" defined and it's the ID of an element on page
all_links[i].onmouseover=function(e){
var evtobj=window.event? window.event : e
displayballoontip(this, evtobj)
}
all_links[i].onmouseout=delayhidemenu
}
}
}

if (window.addEventListener)
window.addEventListener("load", initalizetooltip, false)
else if (window.attachEvent)
window.attachEvent("onload", initalizetooltip)
else if (document.getElementById)
window.onload=initalizetooltip

mike_k12003
02-23-2009, 06:32 AM
any luck finding anything? Been troubled for some time and really wanted it to work

mike_k12003
03-03-2009, 06:43 AM
Still strugling but I cannot find why it is working only on IE -with my changes :mad:, and I dont see anyone finding something..is it that hard eh? plZZZ cause I really want it to work (been trying to make it to work for 2 months) any suggestions would be appreciated:(

buenchaval
03-08-2009, 11:35 PM
thanks to :

http://www.howtocreate.co.uk/tutorials/javascript/browserspecific

here the solution :), at least it works for me..

replace the funcion getposOffset by the attached findPositionWithScrolling2 and change these two lines of the script:

dropmenuobj.x=findPositionWithScrolling2(obj)[0]
dropmenuobj.y=findPositionWithScrolling2(obj)[1]+verticaloffset


function findPositionWithScrolling2( oElement ) {
function getNextAncestor( oElement ) {
var actualStyle;
if( window.getComputedStyle ) {
actualStyle = getComputedStyle(oElement,null).position;
} else if( oElement.currentStyle ) {
actualStyle = oElement.currentStyle.position;
} else {
//fallback for browsers with low support - only reliable for inline styles
actualStyle = oElement.style.position;
}
if( actualStyle == 'absolute' || actualStyle == 'fixed' ) {
//the offsetParent of a fixed position element is null so it will stop
return oElement.offsetParent;
}
return oElement.parentNode;
}
if( typeof( oElement.offsetParent ) != 'undefined' ) {
var originalElement = oElement;
for( var posX = 0, posY = 0; oElement; oElement = oElement.offsetParent ) {
posX += oElement.offsetLeft;
posY += oElement.offsetTop;
}
if( !originalElement.parentNode || !originalElement.style || typeof( originalElement.scrollTop ) == 'undefined' ) {
//older browsers cannot check element scrolling
return [ posX, posY ];
}
oElement = getNextAncestor(originalElement);
while( oElement && oElement != document.body && oElement != document.documentElement ) {
posX -= oElement.scrollLeft;
posY -= oElement.scrollTop;
oElement = getNextAncestor(oElement);
}
return [ posX, posY ];
} else {
return [ oElement.x, oElement.y ];
}
}

mike_k12003
03-11-2009, 08:11 AM
Cannot believe in my eyes but worked!:eek::):D Many many thanks buenchaval for your solution, you can't imagine in how many forum I have posted this and how much time I spent trying to figure it out.
As a side note how many time did you need to solve this and you found that article by googling it?