Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

SharePoint like GridView menu

4.00/5 (1 vote)
19 Mar 2009CPOL2 min read 46.5K  
A SharePoint like GridView menu.
In IE:

GridView menu IE

In Mozilla:

GridView menu MZ

Introduction

Normally, in any application, if we want to edit / delete a row, we add different columns in the GridView to add Edit/Delete links/buttons. But, I wanted to do something different. I think many of us have seen the SharePoint List style GridView where we can see a dropdown menu while clicking any particular column of the GridView. In this article, I am going to show something like that.

Background

I saw an article in CodeProject about GridView Hover Menu. I started with that sample code and modified/added some techniques. I also searched Google about how to generate a menu in a GridView control.

Using the Code

First, I would like to explain the technique in brief. Let us first discuss the code-behind file. In the code-behind file, in the Page_Load event, I bind the GridView.

C#
gridViewExample.DataSource = getDataSource();
gridViewExample.DataBind();

The data source is a DataTable with columns: Id, Name, Class, Roll, and Address. We can provide some sample data there. Then, in the gridViewExample_RowDataBound event, we will attach some JavaScript method with some events of the controls of a column in the GridView.

In the GridView, we have a tempaletfield in which we have three things: a label - which will show the content of the column, an image (similar to a dropdown icon) - which will be be hidden first and then shown in the onmouseover event of the grid's particular column, and a Div containing the menu - it will also be hidden at load time, and will be shown when the dropdown icon is clicked. The menu will disappear if we click the icon again, or if we move the cursor from the menu area. Here is the portion of the GridView code:

ASP.NET
<%--  column 1   --%>

<asp:templatefield headertext="Name"  >
    <itemtemplate>
        
        <table class="linktableover" 
        style="" cellpadding="0" cellspacing="0" >
        <tr>
        <td style="width:160px"><asp:label runat="server" id="lblName" 
                      Text='<%# Bind("Name")%>'/></td>
        <td><asp:Image  ID="gridPopup_img" 
              style="border-width: 0px; visibility: hidden; vertical-align: middle;"
              runat="server" ImageUrl="~/img/dd.gif" /></td>
        </tr>
        </table>  

    <%--  pop up menu   --%>
    <div id="gridPopup" 
         style="width:130px; position: absolute; z-index: 101; visibility: hidden;" 
         runat="server">
    <table class="DropDropMenu" >
    <tbody><tr>
    <td style="border-style: solid; border-width: 1px; ">
    <table>
    <tr>
    <td><img alt="EDIT" src="img/edit.gif" /></td>
    <td><asp:linkbutton id="btnEdit" text="EDIT" runat="server" 
      onmouseover="window.status='';this.style.textDecoration = 'underline'; return true" 
      onmouseout="window.status='';this.style.textDecoration = 'none'; return true"
      commandargument='<%#Bind("Id")%>' commandname="Print" 
      causesvalidation="false"/></td>
    </tr>
    <tr>
    <td><img alt="DELETE" src="img/delete.gif" /></td>
      <td><asp:linkbutton id="btnDelete" text="DELETE" runat="server" 
        onmouseover="window.status='';this.style.textDecoration = 'underline'; return true" 
        onmouseout="window.status='';this.style.textDecoration = 'none'; return true"
        OnClientClick="return confirm('Are you sure you want to delete the student ?');"
        commandargument='<%#Bind("Id")%>' commandname="Email" 
        causesvalidation="false"/></td>
    </tr>
    <tr>
    <td><img alt="SEARCH" src="img/search.gif" /></td>
    <td><asp:linkbutton id="btnSearch" text="SEARCH INFO" runat="server" 
      onmouseover="window.status='';this.style.textDecoration = 'underline'; return true" 
      onmouseout="window.status='';this.style.textDecoration = 'none'; return true"
      commandargument='<%#Bind("Id")%>' commandname="Search" 
      causesvalidation="false"/></td>
    </tr>
    <tr>
    <td><img alt="ATTACH" src="img/attach.gif" /></td>
    <td><asp:linkbutton id="btnAttach" text="ATTACH FILE" runat="server" 
       onmouseover="window.status='';this.style.textDecoration = 'underline'; return true" 
       onmouseout="window.status='';this.style.textDecoration = 'none'; return true"
       commandargument='<%#Bind("Id")%>' commandname="Attach" 
       causesvalidation="false"/></td>
    </tr>
    </table>
     </td></tr>
     </tbody></table>   
    </div>
     <%-- end - pop up menu   --%>
    </itemtemplate>
    <ItemStyle Width="100px" ></ItemStyle>
</asp:templatefield>

From the above code, we can see that there are some link buttons as menu items, and we have bound the commandargument with the value of Id.

C#
if (e.Row.RowType == DataControlRowType.DataRow)
{
    //get the controls from particular column
    Label lblName = (Label)e.Row.Cells[0].FindControl("lblName");
    HtmlGenericControl popupMenu = 
      (HtmlGenericControl)e.Row.Cells[0].FindControl("gridPopup");
    Image gridCellImage = (Image)e.Row.Cells[0].FindControl("gridPopup_img");

    //show the menu in onclick event of image
    string menuShowOnImgClick = "menuShowOnImgClick(this,'" + popupMenu.ClientID + "')";
    gridCellImage.Attributes.Add("onclick", "javascript:" + menuShowOnImgClick);

    //show the image onmouseover of the column
    string showImg = "showImg(this,'" + gridCellImage.ClientID + "');";
    e.Row.Cells[0].Attributes.Add("onmouseover", "javascript:" + showImg);

    //hide img and menu onmouseout of the column and menu
    string hideImgAndMenu = "hideImgAndMenu(this)";
    popupMenu.Attributes.Add("onmouseout", "javascript:" + hideImgAndMenu);
    e.Row.Cells[0].Attributes.Add("onmouseout", "javascript:" + hideImgAndMenu);
    
    //keep showing the menu onmouseover of the menu
    string showMenu = "showMenu(this);";
    popupMenu.Attributes.Add("onmouseover", "javascript:" + showMenu);
}

Here are the JavaScript functions that have been used:

JavaScript
//called on image click
function menuShowOnImgClick(imge,menuDivId) {
    var menuDiv = document.getElementById(menuDivId);
    if(menuDiv)
    {
        if(objSel && objSel != menuDiv)
        {
            objSel.style.visibility='hidden';
            imageObjSel.style.visibility='hidden';  
            if(document.all)
                {
                    selectedTableCell.childNodes[0].border='2';
                    selectedTableCell.childNodes[0].bordercolor='black';
                }
                else
                {
                    selectedTableCell.childNodes[1].className='linktable';
                } 
        }
        if(menuDiv.style.visibility=='visible')
        {
            menuDiv.style.visibility='hidden';
        }
        else
        {
            menuDiv.style.visibility='visible'; 
            var iLen=0;
            {
                   MoveMenuToRight(imge,menuDiv,0);
                   //move the menu right ..exact under the img
            }
        }
    }
    flagDisplaymenu = 1;
    objSel = menuDiv;
}

//called on td mouse over
function showImg(event,imageId) { 
    var img = document.getElementById(imageId);     //get the image
    if(imageObjSel)
    {
        if(objSel) 
        {
            if(img != imageObjSel)
            objSel.style.visibility='hidden';
        }
        imageObjSel.style.visibility='hidden';
    }            
    if(img)  //if img is found
    {
        flagDisplaymenu = 1;                    //set flag to show menu
        img.style.visibility='visible';         //show the img
        imageObjSel = img;                      //set the global obj value
        selectedTableCell = event;              //get the table cell
        selectedTableCell.border='1';
        if(document.all)
        {
            selectedTableCell.childNodes[0].border='2';
            selectedTableCell.childNodes[0].bordercolor='black';
        }
        else
        {
            selectedTableCell.childNodes[1].className='linktable';
        }
    }
}

//called on menu mouse out , called on td mouse out
function hideImgAndMenu(event)
{
    
    flagDisplaymenu = 0;     //set flag to hide menu
    timerID = setTimeout('updateTimer()', 5000);
    if(document.all)
    {             
        selectedTableCell.childNodes[0].border='0';
        selectedTableCell.childNodes[0].bordercolor='white';
    }
    else
    {
        selectedTableCell.childNodes[1].className='linktableover';
    }
}

//called on menu item mouse over ,called on menu mouse over
function updateTimer()
{
   if(objSel && flagDisplaymenu == 0)
   {
      objSel.style.visibility='hidden';        //hide the menu div
      imageObjSel.style.visibility='hidden';   //hide the img
      selectedTableCell.border='1';//0 
   }
}

//called on menu item mouse over ,called on menu mouse over
function showMenu(event)
{
    flagDisplaymenu = 1;
}

After running the app, we can see that the menu shows right under the column value. And, whenever we click any of the menu items, the gridViewExample_RowCommand event is fired. In that event, we can detect which row's menu item was clicked by using the command argument - e.CommandArgument which is the ID column of the data source of our GridView.

Conclusion

That's all. I have tested this application on Mozilla 3.0 and IE 6.0. I hope this will be helpful to you .Try it, modify it, extend, and enjoy.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)