Click here to Skip to main content
15,881,715 members
Articles / Web Development / HTML
Article

Context Menu on TreeView

Rate me:
Please Sign up or sign in to vote.
4.80/5 (14 votes)
27 May 2007CPOL6 min read 180K   3.7K   72   27
Microsoft Treeview control Event Capturing on Nodes
Screenshot - outPut.jpg

Introduction

Tree structures are part of today's interactive web development. These structures allow us to show hierarchical information on our web pages. To accomplish such structures, nothing is easier than using the tree view control shipped by Microsoft within ASP.NET 2.0. This tree control has the ability to consume hierarchical data sources like XML files and then display the information.

The client-side user can expand and collapse nodes and click on nodes to send requests to the server. Today's need for user interaction is much higher than that provided by the tree view control. This control would have more flexibility if the programmers were able to capture several other client-side events, thus providing the users more advanced features on the tree structure.

In this article, I am going to show:

  • How to capture the right click event on the node of the tree
  • How to produce a custom context menu on right click

Background

We know that all Microsoft server-side controls are rendered as HTML/DHTML with a combination of JavaScript on the browser. If we can combine JavaScript with the HTML rendered by the tree view control, we will be able to accomplish our task.

Tree View HTML Rendering

The programmer can decide to create a tree view with the help of the tools available in Visual Studio or can program the tree view in the source. This is the tree view that we are going to use in our example:

Screenshot - treeDesign.jpg

ASP Code

ASP.NET
<asp:TreeView ID="TreeView1" runat="server" BackColor="#FFFFC0" Height="180px"
    Width="172px">
    <Nodes>
        <asp:TreeNode Text="Root" Value="sroot">
            <asp:TreeNode  Text="Parent 1" Value="sParent 1">
                <asp:TreeNode Text="this is a test" Value="sLeaf 1" >
                </asp:TreeNode>
                <asp:TreeNode Text="Leaf 2" Value="sLeaf2">
                </asp:TreeNode>
            </asp:TreeNode>
            <asp:TreeNode Text="Parent 2" Value="sParent2">
                <asp:TreeNode Text="Leaf 1" Value="sLeaf 1">
                </asp:TreeNode>
                <asp:TreeNode Text="Leaf 2" Value="sLeaf 2">
                </asp:TreeNode>
            </asp:TreeNode>
        </asp:TreeNode>
    </Nodes>
</asp:TreeView>  

When viewed on the browser, the whole tree is rendered as a nested HTML TABLE and DIV with some JavaScript. A typical tree node...

ASP.NET
<asp:TreeNode Text="this is a test" Value="sLeaf 1" ></asp:TreeNode>  

...is rendered as:

ASP.NET
<table cellpadding="0" cellspacing="0" style="border-width:0;">
    <tr>
        <td>
            <div style="width:20px;height:1px"></div>
        </td>
        <td>
            <div style="width:20px;height:1px"></div>
        </td>
        <td>
            <img 
                src="http://www.mydomain.com/xTreeView/
                WebResource.axd?d=EiQ7rX7B8TmWKbku-S5G9ciFFidk-r05cDK5-
                8iUkl41&amp;t=633045505810781250" alt="" />
        </td>
        <td style="white-space:nowrap;">
            <a class="TreeView1_0" 
                href="javascript:__doPostBack('TreeView1',
                'ssroot\\sParent 1\\sLeaf 1')" 
                onclick="TreeView_SelectNode(TreeView1_Data, this,
                'TreeView1t2');" id="TreeView1t2"> this is a test
            </a>
        </td>
    </tr>
</table> 

The Trick

As we can see, the node text "this is a test" is rendered inside an anchor <a> tag. There is a number of text formatting tags that support JavaScript and that can be nested inside the anchor tag. For example, the bold tag <b>. The HTML would still be in correct format if we can embrace the node text inside tags that can be nested inside the <a></a> tag, so that the HTML rendering of the node looks like this:

ASP.NET
<a class="TreeView1_0" 
    href="javascript:__doPostBack('TreeView1','ssroot\\sParent
    1\\sLeaf 1')" onclick="TreeView_SelectNode(TreeView1_Data,
    this,'TreeView1t2');" id="TreeView1t2">
    <b> this is atest</b>
</a>

The bold tag also supports a number of browser events like click, double click, mouse over, etc. Any of the events can be used in the tag, but we are interested in the event oncontextmenu. This event fires up whenever the user right clicks on the browser to bring up the context menu. Therefore in our tag we can call any JavaScript function on this event. Thus, our tag now looks like this:

<b oncontextmenu="return showmenuie5(event)" > this is a test</b> 

This kind of HTML rendering can easily be achieved by writing the complete HTML as the node text. Thus, in the tree code the node looks like this:

ASP.NET
<asp:TreeNode Text="&lt;b id='b1' oncontextmenu=&quot;return
    showmenuie5(event)&quot; &gt; this is a test&lt;/b&gt;"
    Value="sLeaf 1"  >
</asp:TreeNode>

Alternatively, in the text property of the node you can write the HTML:

<b oncontextmenu="return showmenuie5(event)" > this is a test</b> 

Building the Menu

Once we are able to capture the contextmenu event, we want to produce our own menu instead of the default browser context menu. We can write any HTML combination within the DIV tags. This DIV division/section in the document can be moved around the document with the help of JavaScript.

We can also use the ASP panel control. When this control is rendered, it is rendered as DIV division with the same ID and the panel control's ID. Therefore we can safely write our JavaScript function using the ID. Using the panel will allow more simplicity in building the menu and controlling the menu object through ASP.NET 2.0. features. The menu that we have used in this example is:

Screenshot - customContextMenu.jpg

In the ASP code, we would like to add more functionality to make the menu more interactive:

ASP.NET
<asp:Panel ID="Panel2"  runat="server" display:none BorderColor="Black"
    CssClass="skin0" onMouseover="highlightie5(event)" 
    onMouseout="lowlightie5(event)" onClick="jumptoie5(event)"  > 
<div class="menuitems"><asp:LinkButton ID="LinkButton1" runat="server"  
    CssClass="menuitems" >New Node</asp:LinkButton></div>
<div class="menuitems"><asp:LinkButton ID="LinkButton2" runat="server"  
    CssClass="menuitems">Edit Node</asp:LinkButton></div> 
<hr />
<div class="menuitems"><asp:LinkButton ID="LinkButton3" runat="server"  
    CssClass="menuitems">Delete Node</asp:LinkButton></div> 
<hr /> 
<div class="menuitems"><asp:LinkButton ID="LinkButton4" runat="server"  
    CssClass="menuitems">FAQS</asp:LinkButton></div> 
<div class="menuitems"><asp:LinkButton ID="LinkButton5" runat="server"  
    CssClass="menuitems">Online Help</asp:LinkButton></div>
<hr /> 
<div class="menuitems"><asp:LinkButton ID="LinkButton6" runat="server"  
    CssClass="menuitems">Email Me</asp:LinkButton></div>
</asp:Panel>

JavaScript Overview

Before we begin with writing the JavaScript for our context menu function, I would like to give an overview of some JavaScript objects and their properties that will help us in bringing our right click menu.

Document: Document is the parent object of numerous other objects, such as "images", "forms" etc.

document.getElementById("ID")

A cross-browser (IE5+/NS6+) DOM method for accessing any element on the page via its ID attribute.

document.body.clientWidth

document.body.clientHeight

Specifies the width and height, in pixels, of the window's content area respectively. Read/Write. Does not include the toolbar, scrollbars, etc.

NS4 and NS6 equivalent are

window.innerWidth, window.innerHeight

document.body.scrollLeft

document.body.scrollTop

Returns an integer representing the pixels the current document has been scrolled from the upper left corner of the window, horizontally and vertically, respectively. NS4 and NS6+ IE4+ equivalents are window.pageXOffset and window.pageYOffset

Event: The Event object (IE5+/NS6+) keeps tracks of various events that occur on the page, such as the user moving the mouse or clicking on the link, and allows the programmer to react to them.

event.clientX

event.clientY

Returns the mouse coordinates at the time of the event relative to upper-left corner of the window

event.cancelBubble

Set to true to prevent the event from bubbling.

NS equivalent stopPropagation()

Object.offsetWidth

Object.offsetHeight

Retrieves the width and height of the object relative to the layout or coordinate parent, as specified by the offsetParent property.

Style: The Style object of the DOM allows you to dynamically change the values of your CSS properties, whether defined inline or via an external style sheet. The changes are instantly reflected on the page

Event Bubbling

Internet Explorer 4.0x+ initially directs an event to its intended target. For example, if a button is clicked, the click event is directed to the button. The event invokes an event handler if one is defined for that object. If no event handler is defined to take care of the event, or if the event handler does not return false (to cancel the event), the event proceeds to the parent object for handling. The event bubbles up the object hierarchy until it is handled, or until it reaches the topmost level, the document object.

We are able the capture the oncontextmenu event and with the help of our JavaScript, we will also be able to produce a custom menu. However, at the same time, we need to stop the browser's default menu from coming up. The most important feature in Internet Explorer 4.0x+'s new event model is the event bubbling mechanism. In order to cancel bubbling for a specific event, we must set the cancelBubble property of the event object to true:

window.event.cancelBubble = true;

cancelBubble is a read-write property that takes a Boolean value. Its default value is false, specifying that the event should be bubbled up the hierarchy as usual. However, if explicitly set to true, the event isn't bubbled, preventing the next event handler in the hierarchy to receive the event.

Another way to stop an event from bubbling is to entirely cancel the event by returning false in its event handler script or event processing function. However, unlike canceling bubbling for an event, if you cancel the event itself the default action associated with the event does not take place.

The JavaScript showmenuie5(event) Function

JavaScript
var ie5=document.all&&document.getElementById
var ns6=document.getElementById&&!document.all
if (ie5||ns6)
var menuobj=document.getElementById("Panel2")

function showmenuie5(e){
//Find out how close the mouse is to the corner of the window

var rightedge=ie5? document.body.clientWidth-event.clientX : 
    window.innerWidth-e.clientX
var bottomedge=ie5? document.body.clientHeight-event.clientY : 
    window.innerHeight-e.clientY

//if the horizontal distance isn't enough to accomodate the width of 

//the context menu

if (rightedge<menuobj.offsetWidth)
//move the horizontal position of the menu to the left by it's width

menuobj.style.left=ie5? 
    document.body.scrollLeft+event.clientX-menuobj.offsetWidth : 
    window.pageXOffset+e.clientX-menuobj.offsetWidth
else
//position the horizontal position of the menu where the mouse was clicked

menuobj.style.left=ie5? document.body.scrollLeft+event.clientX : 
    window.pageXOffset+e.clientX

//same concept with the vertical position

if (bottomedge<menuobj.offsetHeight)
menuobj.style.top=ie5? 
    document.body.scrollTop+event.clientY-menuobj.offsetHeight : 
    window.pageYOffset+e.clientY-menuobj.offsetHeight
else
menuobj.style.top=ie5? document.body.scrollTop+event.clientY : 
    window.pageYOffset+e.clientY

if(ie5)
    window.event.cancelBubble = true;
else if(ns6)
    e.stopPropagation();

menuobj.style.visibility="visible"

     return false
}

The Output

Screenshot - outPut.jpg

Although this article demonstrates the capture of right click events on the tree node and producing a menu, the concepts in this article can be applied for many other user-interactive effects on web pages, like mouse-over effects on links to show little information dialog, draggable dialogs on the web page, etc.

History

  • 26 May, 2007 -- Original version posted

License

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


Written By
Web Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Questiontreeview Pin
Member 861737321-Apr-12 7:35
Member 861737321-Apr-12 7:35 
Questionhow right click on new nod? Pin
shima-201113-Mar-11 8:15
shima-201113-Mar-11 8:15 
QuestionHow does code pass selected tree node value to server Pin
rhjiv13-Jan-11 8:15
rhjiv13-Jan-11 8:15 
GeneralMy vote of 3 Pin
rhjiv13-Jan-11 8:12
rhjiv13-Jan-11 8:12 
QuestionHelp in using iframe? Pin
Jollyguy1-Sep-10 2:46
Jollyguy1-Sep-10 2:46 
GeneralAbout X treeview Pin
Mohanraj Selvarathinam20-Mar-10 1:03
Mohanraj Selvarathinam20-Mar-10 1:03 
Hi

Thanks for sharing your xtreeview context menu.

I have included xtreeveiw in master page.

In treeview.js file, var menuobj=document.getElementById("PnlMenu") this code is assigning null value.


Thanks,
S.Mohanraj.
GeneralHelp plz Pin
comphead31-Aug-09 23:56
comphead31-Aug-09 23:56 
Generalxtreeview in updatepanel Pin
iceLand2413-Aug-09 21:58
iceLand2413-Aug-09 21:58 
QuestionCan we do it with left click Pin
nipun ambastha14-Apr-08 2:45
nipun ambastha14-Apr-08 2:45 
Generaleach node or at different level will have different contextmenu Pin
Member 364896517-Mar-08 5:02
Member 364896517-Mar-08 5:02 
GeneralRe: each node or at different level will have different contextmenu Pin
Member 141693027-Nov-08 1:03
Member 141693027-Nov-08 1:03 
GeneralRe: each node or at different level will have different contextmenu Pin
iceLand2413-Aug-09 22:16
iceLand2413-Aug-09 22:16 
Generalfixed the menu not displaying in firefox Pin
maxppp25-Oct-07 5:21
maxppp25-Oct-07 5:21 
GeneralBrowse with firefox Pin
Tuanhung1894-Oct-07 18:00
Tuanhung1894-Oct-07 18:00 
GeneralHelp me ! Pin
Tuanhung18912-Sep-07 17:43
Tuanhung18912-Sep-07 17:43 
GeneralI need your help Pin
Tuanhung18911-Sep-07 21:24
Tuanhung18911-Sep-07 21:24 
AnswerRe: I need your help Pin
Rakesh Krishna Bhatt12-Sep-07 18:19
Rakesh Krishna Bhatt12-Sep-07 18:19 
GeneralContext Menu + ASCX Pin
diablo6420-Jul-07 8:12
diablo6420-Jul-07 8:12 
GeneralValueField property value inside the Text property Pin
tachikaw5-Jul-07 9:06
tachikaw5-Jul-07 9:06 
QuestionHow to select right clicked node? Pin
adka1-Jul-07 23:39
adka1-Jul-07 23:39 
AnswerRe: How to select right clicked node? Pin
tachikaw9-Jul-07 8:15
tachikaw9-Jul-07 8:15 
GeneralRe: How to select right clicked node? Pin
amarbehera14-Jan-08 1:34
amarbehera14-Jan-08 1:34 
QuestionRe: How to select right clicked node? Pin
shima-201113-Mar-11 0:26
shima-201113-Mar-11 0:26 
AnswerRe: How to select right clicked node? Pin
diablo6418-Jul-07 12:30
diablo6418-Jul-07 12:30 
GeneralGetting handle to the selected node Pin
timheff23-Jun-07 4:49
timheff23-Jun-07 4:49 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.