January 2018 : Instructor-led Online Course in ASP.NET Core 2.0. Conducted by Bipin Joshi. Read more...
Registration for January 2018 batch of ASP.NET Core 2.0 instructor-led online course has already started. Conducted by Bipin Joshi. Register today ! Click here for more details.

Showing Tooltips for GridView Items using ASP.NET AJAX

Introduction

ASP.NET AJAX has opened several possibilities to make your web applications richer and more user responsive. In this article I will show you how to develop a popup tooltip for items in data bound controls such as GridView with the help of ASP.NET AJAX.

At first glance you may think of using AJAX control toolkit for this purpose. The AJAX control toolkit does comes with hover menu component. However, you can not use in dynamic way. One hover menu extender can be attached with only one target control. Imagine, for example, that you have a GridView with a HyperLinkField type of column. When users hover mouse pointer over the hyperlinks you wish to display a popup tooltip showing extra details about the item. Something like this cannot be achieved using the AJAX control toolkit. In this article I am going to illustrate how to accomplish just that.

Illustration of Tooltip

Before going into any further details let's see how the tooltip is going to look like. Have a look at figure below:

The above figure shows a web form with a GridView control. The GridView control consists of just one column that is of type HyperLinkField. When you hover on any of the hyperlinks a tooltip pops up showing more details about the item. The descriptive text shown by the tooltip also resides in database i.e. it is not a static text.

Let's begin developing the tooltip!

First of all create a new ASP.NET AJAX Enabled Web site called AJAXTooltip.

Creating Sample Database

For the purpose of this example you need to create a database with one table named Menus. To do so right click on the App_Data folder and choose "Add New Item...". Then add a SQL Database called Database.mdf.

Using Server Explorer create a new tabled called Menus. The schema of Menus table is shown below:

The MenuID column is the primary key and represents a unique ID for each menu. The Text column stores menu item text to be displayed in the browser. The NavigateUrl column stores the URL where the user should be taken to after clicking a menu option. FInallt, TooltipText column stores the text that is to be displayed when user hovers over a menu item.

After creating the table add few rows into it so that you can easily test your web form later on.

Creating a Web Service

ASP.NET AJAX allows you to call web services via client side script. We use the same technique in our example. To begin with add a new web service (WebService.asmx) in your web application and add a web method to it as shown below:

[WebMethod]
public string GetToolTipText(int menuid) 
{
string strConn = ConfigurationManager.ConnectionStrings
["connstr"].ConnectionString;
SqlConnection cnn = new SqlConnection(strConn);
cnn.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = cnn;
cmd.CommandText = "select tooltiptext 
from menus where menuid=@id";
SqlParameter p = new SqlParameter("@id", menuid);
cmd.Parameters.Add(p);
object obj = cmd.ExecuteScalar();
cnn.Close();
return obj.ToString();
}

The GetToolTipText() web method accepts a menu ID and returns its tooltip text. The code retrieves the database connection string from web.config file using ConfigurationManager class. It then creates an SqlConnection and SqlCommand objects. It then retrieves TooltipText for the supplied menu ID by using ExecuteScalar() method of SqlCommand class.

The database connection string is stored in the <connectionStrings> section of web.config as shown below:

<connectionStrings>
<add name="connstr" 
connectionString="Data Source=.\SQLEXPRESS;
AttachDbFilename=|DataDirectory|\Database.mdf;
Integrated Security=True;User Instance=True" 
providerName="System.Data.SqlClient" />
</connectionStrings>

Notice how the path of Database.mdf file is specified using AttachDbFilename attribute. This way the database from App_Data folder (DataDirectory) is attached to the SQL Server Express engine on the fly.

Till this point our web service is like any other web service that you might have developed in the past. This web service is to be called from client side script. That means the client side script should have proxy for this web service so as to call web methods. This feature is enabled by an attribute called [ScriptService]. The [ScriptService] attribute resides in System.Web.Script.Services namespace. The System.Web.Script.Services namespace in turn resides in System.Web.Extensions assembly. The [ScriptService] attribute must be applied to the web service class as shown below.

[ScriptService]
public class WebService : System.Web.Services.WebService
...

This completes our web service.

Developing a Web Form

Now open the default web form - Default.aspx - and ensure that it contains an instance of ScriptManager control. Then drag and drop an SQL data source control and configure it to select all the records from Menus table.

Next, drag and drop a GridView control and set its DataSourceID property to SqlDataSource1. Configure the grid in such a way that it has one column of type HyperLinkField. Set the properties of HyperLinkField column as shown below:

The DataNavigateUrlFields property specifies a comma separated list of columns whose values are to be used in the resultant URL. The DataNavigateUrlFormatString property indicates the format of the resultant URL. Recollect that the NavigateUrl column of Menus table contains URLs and hence we don't need any further formatting. The DataNavigateUrlFormatString property thus contains a placeholder - {0}. At runtime the actual value of NavigateUrl will be substituted for {0}. Finally, the DataTextField property governs the text to be displayed for the hyperlink.

After configuring the GridView, drag and drop a Panel control on the form. Set its BorderStyle property to Solid, BorderColor property to #FF8000 and BackColor property to Yellow. This panel will be used to display the tooltip.

Finally, we need to add a reference to our web service using the ScriptManager control. TO do so locate Services property of ScriptManager and add a reference to our web service.

Creating an AJAX class

ASP.NET AJAX adds some object oriented features to the client side script. Using these features we need to develop a class called ToolTip. The ToolTip class is responsible to show the tooltip, hide the tooltip and call our web service. The following markup shows the complete code of the ToolTip class.

<script type="text/javascript">
Type.registerNamespace("Demo");

Demo.ToolTip=function(panelid)
{
  this._panelid=panelid;
  this.x=0;
  this.y=0;
}
        
Demo.ToolTip.prototype=
{
  get_PanelID:function()
  {
    return this._panelid;
  },
            
  set_PanelID:function(panelid)
  {
    this._panelid=panelid;
  },
            
  BeginShowToolTip:function(event,menuid)
  {
    WebService.GetToolTipText(menuid,this.
    EndShowToolTip,this.OnError,this.OnTimeOut);
    this.x=event.clientX + 10;
    this.y=event.clientY + 10;
  },
            
  EndShowToolTip:function(result)
  {
    var pnl=$get(tooltip.get_PanelID());
    if(pnl.innerText!=null)
    {
      pnl.innerText=result;
    }
    else
    {
      pnl.textContent=result;
    }
  pnl.style.visibility="visible";
  pnl.style.display="inline";
  pnl.style.position="absolute";
  pnl.style.left= tooltip.x + "px";
  pnl.style.top= tooltip.y + "px";
  },
            
  HideToolTip:function()
  {
    var pnl=$get(this.get_PanelID());
    pnl.style.visibility="hidden";
    pnl.style.display="none";
  },
            
  OnError:function(result)
  {
    alert(result.get_message());
  },         
           
  OnTimeOut:function(result)
  {
    alert(result);
  }
}
        
Demo.ToolTip.registerClass("Demo.ToolTip");
</script>

We need to the script block shown above after the ScriptManager control markup. Typically you will place it after the </form> tag.

The code declares and registers a namespace called Demo using registerNamespace() method of Type class.

Then it creates a class called ToolTip. The constructor of the ToolTip class accepts the ID of the Panel that will be used to show the tooltip. The panel ID is stored in a private variable named panelid. The constructor also declares two more private variables - x and y - to store mouse coordinates.

The prototype of ToolTip class contains property and method definitions. The getter and setter methods make ParentID property. The ParentID property simply sets or returns the parentid variable.

The BeginShowToolTip() method is used to call the GetToolTipText() method of the web service. It accepts two parameters - event and menuid. The former parameter supplies information about the current JavaScript event and the later supplies the ID of the menu item for which the tooltip is to be displayed. Inside it calls the GetToolTipText() method of the web service. Note that WebService represents a client side proxy for the actual web service. The menuid is passed as the first parameter to the GetToolTipText() method. The second, third and fourth parameters supply methods to be called after successful execution, on error and on timeout respectively. Finally x and y variables are set to the current location of the mouse pointer. An offset value of 10 is added to the coordinates just to ensure that popup is not directly under the mouse pointer. You can adjust this offset as per your requirement. The BeginShowToolTip() method is called when user moves mouse pointer over a hyperlink of the HyperLinkField column.

The EndShowToolTip() method is called once the web service returns the tooltip text. The return value of the web service is received as result parameter of the method. The code then displays the panel by setting its CSS style properties such as visibility, position, left and top. Note that the if condition that checks the availability of innerText property is necessary to make our class workable in IE as well as FireFox.

The HideToolTip() method is called when the user moves away from a hyperlink.  It hides the panel by setting its CSS properties.

The OnError() and OnTimeout() methods simply display an alert with corresponding error message.

Finally, the registerClass() method of the newly created type ToolTip registers the class with ASP.NET AJAX client side framework.

Now add the following script block in the <HEAD> section of the web form.

<script type="text/javascript">
var tooltip=null;    
function pageLoad()
{
tooltip=new Demo.ToolTip("Panel1");
tooltip.HideToolTip();
}
</script>

The script block contains a function called pageLoad(). This function is called automatically by ASP.NET AJAX framework when the page is loaded in the browser. Inside a new instance of ToolTip class is created. Initially the panel must be hidden and hence HideToolTip() method of ToolTip class is called.

Attaching JavaScript Event Handlers

Our GridView can contain many rows depending on the number of records in the Menu table. In order to call BeginShowToolTip() method when user hovers the mouse on any of the link we need to handle RowDataBound event of the GridView. The complete event handler of this event is shown below:

protected void GridView1_RowDataBound
(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
HyperLink hl = e.Row.Cells[0].Controls[0] 
as HyperLink;
int menuid = Convert.ToInt32
(GridView1.DataKeys[e.Row.RowIndex].Value);
hl.Attributes.Add("onmouseover", 
"tooltip.BeginShowToolTip(event," + menuid + ")");
hl.Attributes.Add("onmouseout", 
"tooltip.HideToolTip()");
}
}

The RowDataBound event is raised for each and every row in the GridView including header and footer row. Hence the code first checks if the current row is DataRow i.e. a row containing actual data values. If so it retrieves a reference to the HyperLink using Controls collection of the Cell. The menu ID for that row is retrieved via DataKeys collection of GridView. Finally, client side event handler for onmouseover event is added using Attributes collection of the hyperlink. The  BeginShowToolTip() method accepts two parameters event and the menu ID. Similarly, onmouseout event handler is set to HideToolTip() method of ToolTip class.

That's it! You can now run the web form and see our tooltip in action.

Summary

ASP.NET AJAX allows you to consume web services via client side script. This feature can be used in many innovative ways. In this example we created dynamic tooltips for GridView items. The ASP.NET AJAX extensions to the client side script allow us to organize our functions in objected oriented way making our code arrangement structured and neat.


Bipin Joshi is a software consultant, an author and a yoga mentor having 22+ years of experience in software development. He also conducts online courses in ASP.NET MVC / Core and Design Patterns. He is a published author and has authored or co-authored books for Apress and Wrox press. Having embraced the Yoga way of life he also teaches Meditation and Mindfulness to interested individuals. To know more about him click here.

Get connected : Twitter  Facebook  Google+  LinkedIn

Posted On : 06 May 2007


Tags : ASP.NET AJAX Web Forms Server Controls Data Controls