ASP.NET Custom Server Controls: Cute ToolTip Control

This article introduces you to creating a customized “ToolTip” control for your use in ASP.NET web applications.

Contributed by
Rating: 4 stars4 stars4 stars4 stars4 stars / 43
October 17, 2005
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

A downloadable file for this application is available here.

The sample downloadable solution (zip) is entirely developed using Visual Studio.NET 2003 Enterprise Architect on Windows Server 2003 Standard Edition.  But, I am confident that it would work with other versions of Windows (which support .NET 1.1) as well.

What sort of “tooltip” is this?

This is the main question for which everyone wants the answer.  Everyone knows that tooltips are essential for showing brief “help” for a particular task (or link).  If it is a desktop application (not a web application) we can expose the tool tip's functionality very easily.  Even HTML provides some of the tool tip's functionality for web pages (using the “alt” attribute).  But it is not very customizable. For example, I might like to change the background color or foreground color of the tool tip; that is impossible.

Considering all of the above scenarios, I decided to design and create my own tooltip control for my web applications.  At the beginning, I thought that it would be very easy to implement (by simply working with “DIV” tag).  But there exists a problem with those tool tips, because they will always be behind “windowed” controls (like dropdown lists) on the web page.  Finally I became mad when I found out the solution.  After searching with Google, I found this solution: my tooltip needs to be equipped with an IFRAME (for Internet explorer only) tag.

When any content is written to IFRAME, the content always stays ahead of any other control (including windowed controls) on the web page (be careful to provide the proper z-index accordingly).  But, we should always make sure that the “z-index” value is always higher than any other control on the web page.  Some of the custom control designers would always give a z-index value of something like “99999”, thinking that there will not be 100,000 controls on a single page. They are correct.  No web page would ever contain 100,000 controls!  I am also trying to implement the same type of trick in my control.

But there is one drawback.  Not every browser supports IFRAME!  Consider Netscape; it could not support IFRAME (but supports LAYER in place of it).  As this article mainly focuses on IFRAME, it would only work for Internet Explorer.  But you can enhance this control according to your requirement for cross-browser independence (as I am enclosing full source code as part of a download).

And another issue is that, I am not simply confirming that this is the only way (or method) to support tooltips in web applications.  This article only gives you an idea of how to start and get working with IFRAMEs in ASP.NET web applications (supporting Internet Explorer) as part of server controls.  I suggest that you enhance the same according to your requirements and all the flavors necessary.

So, let us start into the details of “tooltip” control.

What are the properties declared and how do we work with the control?

As I wanted the tooltip control to be as simple as possible, I declared only one property i.e., “IsDesignTime”.  It is declared as “private” within the control class.  It is created with the following code:

Private ReadOnly Property IsDesignTime()
       
Get
            Return (Not Me.Site Is Nothing) AndAlso
(Me.Site.DesignMode)
        End
Get
    End Property

It checks whether the control is at the stage of design-time or run-time.  This is essential for me to determine whether the control needs to emit required JavaScript or not.  During design-time, no JavaScript emission is necessary!  It needs to be emitted only at run-time.  You also need to observe that the property is “readonly” (no changes) and it is private (can be used only within the class and not outside the class).  I used it only within the “Render” method.

To work with this control, we need to drag it from the toolbox (after adding it to the toolbox) onto the design surface.  We can drag it to any location, as it is by default invisible at run-time.  After placing it on the surface, we need to bind the tooltip to all of our respective controls during the “page load” event.  The following is the code-fragment I used as part of the demonstration.

Me.TextBox1.Attributes.Add("onMouseOver", "showToolTip
(event,'<font face=\'verdana\' size=2>this is some
info</font>');")
Me.TextBox1.Attributes.Add("onMouseOut", "hideToolTip();")

The first statement adds the “OnMouseOver” event attribute to “TextBox1” by calling the JavaScript function “showToolTip”.  This is similar to the second statement with “onMouseOut” event and “hideToolTip” JavaScript function.

In that way, the same control can be used by any number of controls which exist on the same web page.

How is it rendered?

In my previous examples, I used to define “RenderBeginTag”, “Render”, “RenderEndTag” and several other methods of rendering.  In this scenario, as the control (tooltip) will not be displayed immediately after the web page gets rendered, there is no reason to use certain methods.

Finally, I am overriding only two methods from the base class “webcontrol”.  They are as follows:

  • AddAttributesToRender
  • Render

Even though it is not quite essential to use “AddAttributesToRender” method in this case, I just used it to separate the registration of JavaScript code from the “Render” method.  It is defined as follows:

MyBaseAddAttributesToRender(writer)
       
'emit javascript only at run-time
        If Not IsDesignTime Then

            'mouse events
            If Not Page.IsStartupScriptRegistered("ShowToolTip")
Then
                Page.RegisterStartupScript("ShowToolTip",
getJS4ShowToolTip)
           
End If
            If Not Page.IsStartupScriptRegistered("HideToolTip")
Then
                Page.RegisterStartupScript("HideToolTip",
getJS4HideToolTip)
           
End If
        End If

Within the above method, I am trying to call the “MyBaseAddAttributesToRender(Writer)” statement to add any design-time attributes to my control.  It is not  essential for this control in this scenario, but this is a must when we design interactive controls (as explained in my previous articles in this series). 

And you can even observe that I am using the “IsDesignTime” method here.  I would like to emit JavaScript code out, if and only if, it is not design time in Visual Studio.NET.  I think you can understand the rest.  It just involves emitting JavaScript contained in “getJS4ShowToolTip” and “getJS4HideToolTip” (which we will see in later sections).  Coming to the “Render” method, it is defined as follows:

Protected Overrides Sub Render(ByVal writer As
System.Web.UI.HtmlTextWriter)
        AddAttributesToRender(writer)
        writer.Write("<div id=""frDiv""overflow:visible;position:absolute;visibility:
hidden;z-index:500""><iframe id=""ifr""
src=""javascript:null""overflow:visible;position:relative;z-
index:500;width:150px""  scrolling=""no"" frameborder=""0""
marginwidth=""0"" marginheight=""0"" vspace=""0"" hspace=""0""
></iframe></div>")
    End Sub

The above method gets executed immediately when the control has to render itself.  The first statement tries to emit JavaScript code (if it is not design time).  Immediately after that, I am emitting an embedded IFRAME enclosed in DIV.  But you should observe that DIV is emitted with the “visibility:hidden” style, which makes it invisible (including IFRAME) by default.

You can specify your own value for the z-index property according to your needs.  Just for the demonstration, I specified a value of 500 to z-index property.  To be on the safe side, try to specify the same, at about 9999 or so.

Javascripts: the heart of tooltip

Until now, we have seen only the ASP.NET custom control code, but didn’t go through the JavaScript code at all.  Now we shall go through both methods, “getJS4ShowToolTip” and “getJS4HideToolTip”.

First of all, here is “getJS4ShowToolTip” step by step:

js &= "var ifr = document.frames(""ifr"").document; "
        js &= "var e_html = ifr.createElement(""html""); "
        js &= "var e_body = ifr.createElement(""body"");"
        js &= "e_body.style.marginLeft = ""0px""; "
        js &= "e_body.style.marginTop = ""0px""; "
        js &= "e_body.style.marginBottom = ""0px"";"
        js &= "e_body.style.marginRight = ""0px""; "

We get the reference of the IFRAME name “ifr” into the variable “ifr”.  We then create the new elements “HTML” and “BODY” to write to IFRAME.  Proceeding further we have:

js &= "var e_div = ifr.createElement(""div"");"
        js &= "e_div.id = ""divContent""; "
        js &= "e_div.style.wordWrap=""break-word""; "
        js &= "e_div.style.backgroundColor=""#aad5ff"";"
        js &= "e_div.style.borderStyle=""solid""; "
        js &= "e_div.style.borderWidth=""1px""; "
        js &= "e_div.style.borderColor=""#336699""; "
        js &= "e_div.style.paddingLeft = ""3px""; "
        js &= "e_div.style.paddingTop = ""3px""; "
        js &= "e_div.style.paddingBottom = ""3px""; "
        js &= "e_div.style.paddingRight = ""3px""; "
        js &= "e_div.innerHTML = msg; "

The above creates a DIV element, specifies the style and finally adds our message (the value available in “text” property).  Proceeding further, we have the following:

        js &= "e_body.appendChild(e_div); "
        js &= "e_html.appendChild(e_body); "
        js &= "ifr.appendChild(e_html); "
        js &= "var oBody = document.frames
(""ifr"").document.getElementById(""divContent""); "
        js &= "var oFrame = document.all(""ifr""); "
        js &= "var oFrDiv = document.all(""frDiv""); "
        js &= "oFrame.style.height = oBody.offsetHeight; "
        js &= "oFrDiv.style.visibility=""visible""; "
        js &= "oFrDiv.style.left = (evt.x + 10) + ""px"";"
        js &= "oFrDiv.style.top = (evt.y + 10) + ""px""; "
        js &= "oFrDiv.style.height = oFrame.style.height;"

The above code adds “DIV” (inner DIV of the IFRAME) to “BODY” and “BODY” gets added to “HTML”.  We finally resize IFRAME accordingly and make it visible.

The second JavaScript method, “HideToolTip” is defined as follows:

Dim js As String
        js = "<script language=""javascript"">"
        js &= "function hideToolTip() "
        js &= "{"
        js &= "     parent.document.getElementById
(""frDiv"").style.visibility=""hidden""; "
        js &= "}"
        js &= "</script>"
        Return js

The above is very simple.  It hides only the DIV (which encloses the IFRAME).

What is the ToolTip Designer class?

That is a special type of class, which gets executed when the control is about to be rendered only at design time.  Here it makes sense to use it, as there exists no involvement of design-time properties to be set.  It is defined something like the following:

Public Class ToolTipDesigner
    Inherits System.Web.UI.Design.ControlDesigner
    Public Overrides Function GetDesignTimeHtml()
As String
        Return "You will be able to see the tooltips only at
runtime"
   
End Function
End Class

The method “GetDesignTimeHtml” gets executed when our tooltip control is dragged from the toolbox onto the web page at design time.  As the control does nothing here and it does not have any properties, we simply return a message.

This class (“ToolTipDesigner”) gets linked to our control with the “<Designer>” attribute at class level.  The class declaration of our ToolTip control would be something like the following:

<Designer(GetType(ToolTipDesigner)), DefaultProperty("Text"),
ToolboxData("<{0}:ToolTip runat=server></{0}:ToolTip>")> Public
Class
ToolTip
    Inherits System.Web.UI.WebControls.WebControl

That finishes our matter.  I leave it to the developers to further enhance the same control.  The areas of improving the same control would include eventing, better JavaScript, data-binding, cross browser support, and so on.  Good luck.

Any comments, suggestions, bugs, errors, feedback etc. are highly appreciated at jag_chat@yahoo.com.

blog comments powered by Disqus
ASP.NET ARTICLES

- Implementing ASP.NET 4.0 Page.MetaDescriptio...
- ASP.Net Development Tips
- Intro to Sessions in ASP.Net
- Google Maps API Introduction in ASP.NET usin...
- Creating an ASP.NET 3.5 Gridview Image Galle...
- Encrypt QueryString in ASP.NET 3.5 using VB....
- ASP.NET 3.5 Drop Down List Controls
- Connect to Access Database with ASP.Net
- Secure Audio Streaming with ASP.Net and Flash
- Dynamic Sitemap and Navigation in ASP.Net
- Implement Gzip and Deflate Compression in AS...
- Run ASP.Net in Ubuntu with Apache
- ASP.Net Mono Website Contact Forms
- ASP.Net URL Rewriting Methods
- Murach`s ASP.NET 4 Web Programming with C# 2...

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
 
 
 

ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 6 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials