This is a migrated thread and some comments may be shown as answers.

tooltip positioning on boundary detection

7 Answers 228 Views
ToolTip
This is a migrated thread and some comments may be shown as answers.
Sub
Top achievements
Rank 1
Sub asked on 02 Feb 2012, 10:54 PM
Hi,

I am using the latest version fo the telerik control. I have the tooltip control displayed for each cell in the RadGrid. It automatically repositions on the boundary detection but relative to the wrong element / grid cell. Here is the code. I want it to position either topleft or bottomleft based on the position of the grid cell on boundary detection. Currently, If the tooltip is not closer to the boundary then it looks ok. But when it is closer to the boundary then it moves down the tooltip pointing to the wrong element to display the whole tooltip. What am I missing in the code? Thanks in advance!

<telerik:RadToolTipManager runat="server" ID="vsRadToolTipManager" VisibleOnPageLoad="false"
                EnableViewState="false" AutoTooltipify="false"
                ShowEvent="FromCode"  EnableAjaxSkinRendering="true"  Modal="true"
                HideEvent="ManualClose"
                RelativeTo="Element"        
                Width="180px" Height="255px"                      
                Skin="Hay" OffsetY="-6" OffsetX="-55"
                OnAjaxUpdate="OnAjaxUpdate" OnClientHide="OnVsTooltipHide"
                OnClientBeforeShow="OnRadTooltipBeforeShow" OnClientShow="CancelAJAX"
                >
                <TargetControls>
                    <telerik:ToolTipTargetControl TargetControlID="fieldForTooltip" IsClientID="false" />
                </TargetControls>
            </telerik:RadToolTipManager>            

7 Answers, 1 is accepted

Sort by
0
Princy
Top achievements
Rank 2
answered on 03 Feb 2012, 05:16 AM
Hello,

Take a look into the following demo.
ToolTip / Relative to

Thanks,
Princy.
0
Sub
Top achievements
Rank 1
answered on 03 Feb 2012, 06:33 PM
Thanks for the link. But it does not seem to be helping in my scenario.

I have to set the RelativeTo = 'Element' because I want to position the tooltip to point to a particular grid cell. but when it detects the boundary it moves down and pointing to the wrong grid cell. Any work around for this particular scenario? Thanks in Advance!
0
rdmptn
Top achievements
Rank 1
answered on 06 Feb 2012, 03:32 PM

Hi Sub,

The first thing I do not see in your markup is the Position property. Set it to TopLeft and see how it behaves.

Are you sure you are using the latest version of the controls? With it things are working fine for me, just make sure that you pass correct ClientIDs when you populate the TargetControls collection. You can see how this is done in this demo: http://demos.telerik.com/aspnet-ajax/tooltip/examples/targetcontrolsandajax/defaultcs.aspx. To persist them you need ViewState, however, try turning it back on, as currently you have only one target from the markup.

Another important bit is that the size you set in the markup must match the size of the content you get - if you get more content this will stretch the popup and it will appear incorrectly positioned. If you cannot fix this in your code/markup you can force the tooltip to reporition itself in the OnClientResponseEnd event, something like this:

function OnClientResponseEnd() 
    var activeTooltip = Telerik.Web.UI.RadToolTip.getCurrent(); 
    if (activeTooltip) activeTooltip.updateLocation(); 
}

You should also try removing the offsets, in a grid 50px may be more than one row/column as well, so this may be confusing you.

0
Sub
Top achievements
Rank 1
answered on 06 Feb 2012, 11:14 PM

Hi,

I have tried setting the Position="TopLeft" with no luck.I enabled the Viewstate as well, but no difference.I have a fixed size of tooltip and it does not have to stretch dynamically.I removed the offset as well.

Also I don't set the TargetControl collection and I am using the client-side API to show the tooltip as Telerik suggested this as I was looking for maximum efficiency and minimum footprint as specified in the below link.

http://www.telerik.com/DEMOS/ASPNET/Prometheus/ToolTip/Examples/RadToolTipManagerClientAPI/DefaultCS.

Please refer to the attached code. Here are some of the main issues:
-The call out does not point to the correct grid cell on boundary detection.
-Normally, with out boundary detection, randomly it displays the tooltip itself somewhere else (far away). If you click again the same cell then it displays in a correct position. The behavior is inconsistent.

I expect to display TopLeft position, call out pointing to the correct cell. Only when the bottom boundary is detected it should display BottomLeft position instead of TopLeft. When right boundary is detected it should still display topleft with call out adjusted to point to the correct cell. Please help me to fix this. I appreciate it!

I put together some sample with this. It almost mimics the behavior that I am getting in my applicaiton. I have tooltip displayed for the last n number of columns of the grid in my actual application.

Default2.aspx
.

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" %>
<%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %>
  
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  
<head runat="server">
    <title></title>
    <style type="text/css">
        .title
        {
            font-size: 12px;
            display: block;
            font-weight: bold;
            color: #ff6fb9;
        }
        .info
        {
            color: black;
            font-size: 11px;
        }
        .TooltipCell
        {
            background-color:#fe8!important;
            cursor: pointer;
            _cursor: hand;  
        }
    </style>
  
    <telerik:RadCodeBlock runat="server">
 <script type="text/javascript">
     var clickedCell;
     var mouseOvercell;
     var shouldHideCellColor = true;
  
     function OnCellClick() {
         clickedCell = mouseOvercell;
         shouldHideCellColor = false;
  
         var tooltipManager = $find("<%= vsRadToolTipManager.ClientID %>");
         if (tooltipManager != null) {
             tooltipManager.set_manualClose(true);
             //Find the tooltip for this element if it has been created    
             var tooltip = tooltipManager.getToolTipByElement(clickedCell);
             //Create a tooltip if no tooltip exists for such element   
             if (!tooltip) {
                 tooltip = tooltipManager.createToolTip(clickedCell);
             }
             tooltip.show();
         }
     }
  
     function SetCellStyle(id) {
         if (clickedCell == null) {
             mouseOvercell = document.getElementById(id);
             if (mouseOvercell != null) {
                 mouseOvercell.className = "TooltipCell";
             }
         }
     }
  
     function ResetCellStyle() {
         if (mouseOvercell != null && shouldHideCellColor) {
             mouseOvercell.className = "";
         }
         if (clickedCell != null && shouldHideCellColor) {
             clickedCell.className = "";
         }
     }
  
     function OnHide(sender, eventArgs) {
         clickedCell = null;
         shouldHideCellColor = true;
         ResetCellStyle();
     }
    </script>
</telerik:RadCodeBlock>
</head>
<body>
    <form id="form1" runat="server">
    <div>
 <telerik:RadScriptManager ID="RadScriptManager1" runat="server">
    </telerik:RadScriptManager>
    <telerik:RadAjaxPanel ID="ajaxPanel" EnableAJAX ="true" EnableOutsideScripts="false" 
EnablePageHeadUpdate="false" runat="server" LoadingPanelID="ajaxLoadingImage" EnableViewState="false"
  EnableHistory="false" EnableTheming="false">       
<telerik:RadToolTipManager runat="server" ID="vsRadToolTipManager" VisibleOnPageLoad="false"
                EnableViewState="true" AutoTooltipify="false"
                ShowEvent="FromCode"  EnableAjaxSkinRendering="true"  Modal="true"
                HideEvent="ManualClose" ShowCallout="true"
                RelativeTo="Element" Position="TopLeft"     
                Width="180px" Height="255px"                      
                Skin="Hay"  OnClientHide="OnHide"
                OnAjaxUpdate="OnAjaxUpdate"
                >
              </telerik:RadToolTipManager>            
             <telerik:RadGrid ID="RadGrid1" runat="server" DataSourceID="AccessDataSource1" GridLines="Vertical"  OnItemDataBound="RadGrid1_ItemDataBound">
        </telerik:RadGrid>   
         </telerik:RadAjaxPanel>
             
    <asp:AccessDataSource ID="AccessDataSource1" runat="server" DataFile="~/App_Data/Nwind.mdb"
        SelectCommand="SELECT  ProductID,ProductName,SupplierID,CategoryID,QuantityPerUnit,UnitsOnOrder,UnitsInStock,UnitPrice FROM [Products]"></asp:AccessDataSource>
    </div>
    </form>
</body>
</html>

Default2.aspx.cs
.
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Telerik.Web.UI;
  
public partial class Default2 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
  
    }
  
    protected void OnAjaxUpdate(object sender, ToolTipUpdateEventArgs args)
    
        Control ctrl = Page.LoadControl("ProductDetails.ascx");
        args.UpdatePanel.ContentTemplateContainer.Controls.Add(ctrl);
        ProductDetails details = (ProductDetails)ctrl;
        details.ProductID = "1";
    }
  
    protected void RadGrid1_ItemDataBound(object sender, GridItemEventArgs e)
    {
  
        if ((e.Item.ItemType == GridItemType.Item) || (e.Item.ItemType == GridItemType.AlternatingItem))
        {
            // Show the tooltip
            GridDataItem dataItem = e.Item as GridDataItem;
            //AttachtTooltipEvents(dataItem["ProductID"]);
           // AttachtTooltipEvents(dataItem["ProductName"]);
            //AttachtTooltipEvents(dataItem["RecorderLevel"]);
            AttachtTooltipEvents(dataItem["UnitsOnOrder"]);
            AttachtTooltipEvents(dataItem["UnitsInStock"]);
            AttachtTooltipEvents(dataItem["UnitPrice"]);
         }
    }
  
    private void AttachtTooltipEvents(TableCell dataCell)
    {
        dataCell.Attributes.Add("onclick", "OnCellClick();");
        dataCell.Attributes.Add("onmouseover", "SetCellStyle('" + dataCell.ClientID + "');");
        dataCell.Attributes.Add("onmouseout", "ResetCellStyle();");
    }
}
ProductDetails.ascx
.
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="ProductDetails.ascx.cs" Inherits="ProductDetails" %>
 <asp:FormView ID="ProductsView" DataSourceID="ProductDataSource" DataKeyNames="ProductID"
                        runat="server" OnDataBound="ProductsView_DataBound">
                        <ItemTemplate>               
        <span class="title">Product Name: </span>
        <asp:Label CssClass="info" ID="ProductName" runat="server"><%# Eval("ProductName") %></asp:Label>  
        <br />          
        <span class='title'>Category:</span>
        <asp:Label CssClass="info" ID="Category" runat="server">Seafood</asp:Label
                <br />            
        <span class='title'>Quantity Per Unit:</span>
        <asp:Label CssClass="info" ID="Label1" runat="server"><%# Eval("QuantityPerUnit")%></asp:Label
                <br />            
        <span class='title'>Unit Price:</span>
        <asp:Label CssClass="info" ID="Label2" runat="server"><%# Eval("UnitPrice")%></asp:Label>   
                <br />          
        <span class='title'>Units In Stock:</span>
        <asp:Label CssClass="info" ID="Label3" runat="server"><%# Eval("UnitsInStock")%></asp:Label>  
                <br />           
        <span class='title'>Units On Order:</span>
        <asp:Label CssClass="info" ID="Label4" runat="server"><%# Eval("UnitsOnOrder")%></asp:Label>        
          
        <span class='title'>Supplier's Company Name:</span>
        <asp:Label CssClass="info" ID="Label6" runat="server"><%# Eval("CompanyName")%></asp:Label>       
        <span class='title'>Supplier's Contact Name:</span>
        <asp:Label CssClass="info" ID="Label5" runat="server"><%# Eval("ContactName")%></asp:Label>        
                        </ItemTemplate>
                    </asp:FormView>                    
  
<asp:AccessDataSource ID="ProductDataSource" runat="server" DataFile="~/App_Data/Nwind.mdb"
    SelectCommand="SELECT * FROM [Products] INNER JOIN [Suppliers] ON Products.SupplierID=Suppliers.SupplierID   WHERE ([ProductID] = ?)"
    <SelectParameters>
        <asp:Parameter Name="ProductID" Type="Int32" />
    </SelectParameters>
</asp:AccessDataSource>
ProductDetails.ascx
.
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
  
public partial class ProductDetails : System.Web.UI.UserControl
{
     public string ProductID
        {
            get
            {
                if (ViewState["ProductID"] == null)
                {
                    return "";
                }
                return (string)ViewState["ProductID"];
            }
            set
            {
                if (this.ProductID != value)
                {
                    
                }
                ViewState["ProductID"] = value;
                  
               ConfigureView();
            }
        }
         
        private void ConfigureView()
        {
            this.ProductDataSource.SelectParameters["ProductID"].DefaultValue = this.ProductID;
  
            this.DataBind();
        }
  
        protected void ProductsView_DataBound(object sender, EventArgs e)
        {
             
        }
}
0
Marin Bratanov
Telerik team
answered on 09 Feb 2012, 10:09 AM
Hello,

Thank you for the additional information. It helps narrow down the problem's origin. Please examine carefully the code from the demo you are using as base. The correct URL is as follows, by the way: http://demos.telerik.com/aspnet-ajax/tooltip/examples/radtooltipmanagerclientapi/defaultcs.aspx. You will see that when the show() method of the tooltip is called there is a small timeout:

. . . .
//Let the tooltip's own show mechanism take over from here - execute the onmouseover just once
element.onmouseover = null;
 
//show the tooltip
setTimeout(function ()
{
    tooltip.show();
}, 10);
. . . . .


This is required because the browser needs some time to create the entire markup and calculate positions and sizes. Once I added this to your code things seem to work as expected and - the tooltip points to the correct cell and changes its position as needed: http://screencast.com/t/1nb1stpr7GVw. I am also attaching my test page here as a reference. I have used a programmatic datasource and I do not load data inside the tooltip as you stated it is not relevant and has static size.

Greetings,
Marin
the Telerik team
Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
0
Sub
Top achievements
Rank 1
answered on 09 Feb 2012, 11:19 PM
Thank you so much for the solution. That makes the position to work correctly.

1.However I expect to display TopLeft position and only when the bottom boundary is detected it should display BottomLeft position instead of TopLeft. currently it is not consistant whether it displays TopLeft or BottemLeft even though it did not detect the bottom boundary. You can notice the behavior in the sample code that I sent before.

2. Another thing I am trying is to do is to position the call out pointing to the right most corner of the cell. I used to achieve this in 2008 version of telerik by setting the OffsetX property. But now I can only set upto -10 to move a littilebit. If I set more than that then it points to the wrong cell. I am trying to mimic the same behavior that I got with 2008 version. So, I want the call out to point to the right corner of the cell for both TopLeft and BottomLeft (on boundary detection) position. Please let me know of any way to achive this.

Thanks in advance!!
0
Marin Bratanov
Telerik team
answered on 13 Feb 2012, 02:02 PM
Hello Subha,

The boundary detection works properly and changes the position only when needed.  In this case it first detects it cannot be displayed with the top position when the TOP boundary is detected, not when the bottom is detected, so it tries to switch to bottomLeft position, if detects the left boundary and switches to bottomRight. This is the case when the grid is in the top left corner of the page. The logic is similar even if it is positioned further down the page. What you are asking for is to display it with TopLeft when the grid is in the top left corner of the viewport and with BottomRight when the grid is in the bottom of the browser. This is the exact opposite of the viewport detection the RadToolTip has. Thus you can simply turn boundary detection off, as shown in this forum thread.

That being said, f you want the tooltip to point to the right part of the cell I advise that you simply set its position to TopRight, as using an offset when boundary detection is present cannot be guaranteed to yield the same results, as in this case the position of the tooltip is relevant to the browser's size, which is not something the developer can control, while the offsets are static - they are applied regardless of the position, as it is considered the developer has chosen them for a specific reason.


All the best,
Marin
the Telerik team
Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
Tags
ToolTip
Asked by
Sub
Top achievements
Rank 1
Answers by
Princy
Top achievements
Rank 2
Sub
Top achievements
Rank 1
rdmptn
Top achievements
Rank 1
Marin Bratanov
Telerik team
Share this question
or