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

Disablinking link after clicking on RadTreeNode

7 Answers 106 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
Chris
Top achievements
Rank 1
Chris asked on 31 Oct 2012, 06:18 PM
I'm trying to disable the link of a RadTreeNode after it's clicked to prevent machine gun clicking/request flooding. We have some code that handles that, but I'm having trouble getting the link part of the RadTreeNode.

Here's what I'm assuming: the actual RadTreeNode consists of:

<li class="rtLI">
     <div class="rtTop rtHover">
          <span class="rtSp"></span>
          <span class="rtPlus"></span>
          <a class="rtIn" style="font-weight:bold;" href="/course-catalog/social-studies-3-part-1/fall/lesson-1">Lesson 1</a>
     </div>
</li>
Which is what I actually get when I call:

var selectedNode = sender.get_selectedNode();

I'm trying to figure out how to get the actual link object. Once I have that, I can check that it actually goes somewhere with jQuery and set up my disabling code.

Any help would be greatly appreciated.

Thanks,
Chris

7 Answers, 1 is accepted

Sort by
0
Bozhidar
Telerik team
answered on 01 Nov 2012, 08:52 AM
Hello Chris,

Once you have a reference to a RadTreeNode's client object, you can use the get_linkElement() function to get a reference to the link element.
var selectedNode = sender.get_selectedNode();
var linkElement = selectedNode.get_linkElement();

 
All the best,
Bozhidar
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now.
0
Chris
Top achievements
Rank 1
answered on 01 Nov 2012, 01:53 PM
For some reason, it doesn't matter which node I click, but when I call selectedNode.get_linkElement().href, I always get the URL of the current page that I am on, not the href of the link I just clicked. Have you seen this before?

Some notes about the tree:

1. The tree is partially dynamically created. It looks something like this:

-- Course Group
---- Course
------ Unit
-------- Lesson
---------- Lesson Component

The Lesson and Lesson Component nodes of the tree are only created dynamically, except when on one of the lesson/lesson component pages. The node will be visible on load if you're on the page of the node.

2. The Course Group, Course, and Unit nodes don't actually go anywhere. Those aren't actually pages we want people going to.

Any help is greatly appreciated.
0
Bozhidar
Telerik team
answered on 05 Nov 2012, 10:51 AM
Hello Chris,

Can you elaborate a bit on your scenario. Where exactly are you making the call to selectedNode.get_linkElement().href. Could you provide some sample code and a detailed sequence of steps that produce the unwanted behavior, so that we can determine what is the underlying issue.
 
All the best,
Bozhidar
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now.
0
Chris
Top achievements
Rank 1
answered on 05 Nov 2012, 02:18 PM
Sure.

First, the declaration of the RadTreeView:

<telerik:RadTreeView ID="LBCourseNavTreeView" runat="server"
    EnableEmbeddedSkins="false" SingleExpandPath="true" Height="100%"
    OnClientLoad="LbNavTree_ClientLoad"
    OnClientNodeExpanding="LbNavTree_ClientNodeExpanding"
    OnClientNodePopulated="LbNavTree_ClientNodePopulated"   
    OnClientNodeCollapsed="LbNavTree_ClientNodeCollapsed"
    OnClientNodePopulationFailed="LbNavTree_ClientNodePopulationFailed"
    OnClientNodeClicking="LbNavTree_ClientNodeClicking">
    <WebServiceSettings Path="/LessonBuilder/Services/CourseNavTreeService.svc" Method="GetChildren" />
</telerik:RadTreeView>

There is Javascript that actually takes care of the disabling of the link. This Javascript is located in a file that is minified and combined in the project:

LB.Util.DisableLink = function (object) {
    if ($(object).hasClass("loading"))
        return false;
    $(object).addClass("loading");
    document.body.style.cursor = "progress";
    window.location.href = object[0];
    return false;
};

This code is located in the webservice that actually populates the nodes in question (from my little treeview map, these are lesson component nodes):

private IEnumerable<RadTreeNodeData> GetComponents(ClaimsPrincipalProxy user, int userId, bool lessonCanNavigate, Guid bookmarkPageGuid,
                                                   Guid currentNodePageGuid, string pageTheme, string baseTreeIconPath)
{
    // fetch children
    var lcViewModels = NewLessonComponentService.GetLCCustom1ViewModels(currentNodePageGuid, userId).ToList();
 
    var gameVis = SettingService.GetGameVisibility(userId, CourseService.GetGbCourseIdFromLessonGuid(currentNodePageGuid));
    if (!gameVis)
        lcViewModels = lcViewModels.Where(x => x.LCTypeId != Constant.LESSON_COMPONENT_TYPE_GAME).ToList();
 
    var componentNodes = new List<RadTreeNodeData>();
 
    // if all the items are completed then the lesson is completed and we can navigate to all the components
    bool lessonIsComplete = lcViewModels.All(en => en.CompletionStatus == CompletionStatusEnum.Completed);
    // if all the items are completed then don't show any icons
    bool showStatusIcons = !lessonIsComplete;
 
    // we need to know if the lesson is locked
    // aka if the components need to be done in order
    bool isLocked;
    bool? lessonIsLocked = LessonService.GetLessonIsLocked(currentNodePageGuid);
    if (lessonIsLocked != null)
        isLocked = lessonIsLocked.Value;
    else
        isLocked = false;   //We assume this if the Lesson record is not found
 
    bool firstComponent = true;
 
    // are we high enough in the food chain to not be gated by progress?
    var hasFullBrowsing = UserService.IsUserGrantedFullBrowsing(user);
 
    // NOTE: we're duplicating the list here in order to keep track of which components are complete
    // system doesn't like it much if we try to modify a collection we're in
    var componentList = lcViewModels.ToArray();
 
    foreach (var lcViewModel in lcViewModels)
    {
        var radTreeNode = new RadTreeNodeData
                              {
                                  Text = lcViewModel.DefaultTitle,
                                  Value = lcViewModel.LCGuid.ToString()
                              };
 
        var nodeImageName = string.Empty;
        // image icon based on completion status
        bool canNavigate;
        switch (lcViewModel.CompletionStatus)
        {
            case CompletionStatusEnum.Completed:
                {
                    if (showStatusIcons)
                    {
                        nodeImageName = "green.png";
                    }  
                    canNavigate = true;
                    break;
                }
            case CompletionStatusEnum.Skipped:
                {
                    if (showStatusIcons)
                    {
                        nodeImageName = "red.png";
                    }      
                    canNavigate = true;
                    break;
                }
            default//CompletionStatusEnum.NotSet
                {
                    var current = lcViewModels.IndexOf(lcViewModel);
                    if (current != 0)
                    {
                        // check previous component to see if it was completed/skipped, if so, we can navigate to this one
                        var prevComp = componentList[current - 1];
                        if (prevComp.CompletionStatus != CompletionStatusEnum.NotSet)
                        {
                            canNavigate = true;
                            break;
                        }
                    }
 
                    // if we weren't completed or skipped
                    // we can't navigate to the next component
                    canNavigate = false;
                    break;
                }
        }
         
        // if the lesson is complete we can navigate
        // if we have full browsing rights, show everything
        if (lessonIsComplete || hasFullBrowsing)
        {
            radTreeNode.NavigateUrl = string.Format("/{0}",lcViewModel.URL);
            radTreeNode.Attributes.Add("onclick", "return LB.Util.DisableLink($(this), this);");
        }
        else if (lessonCanNavigate)
        {
            // see if we can navigate to the component at all
            // if the lesson was still "locked" we won't
            // be able to visit the lesson
 
            // if we are the first component or we can navigate, set the link
            if ((firstComponent || canNavigate) || (!isLocked))
            {
                radTreeNode.NavigateUrl = string.Format("/{0}", lcViewModel.URL);
                // clear our states
                radTreeNode.Attributes.Add("onclick", "return LB.Util.DisableLink($(this), this);");
                firstComponent = false;
            }
        }
 
        radTreeNode.ExpandMode = TreeNodeExpandMode.ClientSide;
        radTreeNode.Attributes[Constant.COURSETREE_KEY_NODETYPE] = Constant.COURSETREE_CATEGORY_COMPONENT;
        radTreeNode.Attributes[Constant.COURSETREE_KEY_PAGETHEME] = pageTheme;
        //radTreeNode.Attributes[Constant.COURSETREE_KEY_ISBOOKMARKCONTAINER] = falseString;
 
        if (lcViewModel.LCGuid == bookmarkPageGuid)
        {
            // TODO this seems hacky
            radTreeNode.ImageUrl = !string.IsNullOrEmpty(nodeImageName) ? string.Format("{0}bookmark.{1}", baseTreeIconPath, nodeImageName)
                                                                        : string.Format("{0}bookmark.png", baseTreeIconPath);
        }
        else if (!string.IsNullOrEmpty(nodeImageName))
            radTreeNode.ImageUrl = string.Format("{0}{1}", baseTreeIconPath, nodeImageName);
 
        componentNodes.Add(radTreeNode);
    }
 
    return componentNodes;
}

The important line in the above C# code is: radTreeNode.Attributes.Add("onclick", "return LB.Util.DisableLink($(this), this);");

This code is called on both initial page load and asynchronously through a web service. On the iniital expansion the disabling code works fine. If you expand any other node, however, and you try to click the links, the disabling Javascript code will not fire.

As far as the selectedNode.get_linkElement().href code, I tried putting that code in the ClientNodeClicking handler below:

function LbNavTree_ClientNodeClicking(sender, e) {
     
    var selectedNode = sender.get_selectedNode();
    var linkElement = selectedNode.get_linkElement().href.toLowerCase().trim();
    var currPage = document.URL.toLowerCase().trim();
    if (linkElement != currPage) {
        alert('true: le = ' + linkElement + ', cP = ' + currPage);
        return false;
    } else {
        alert('false: le = ' + linkElement + ', cP = ' + currPage);
        return false;
    }
}
It's not picking up linkElement properly. I want to be able to add my Lb.Util.DisableLink call to the new nodes, but even though the code is called, it doesn't seem to add the onclick attribute.

I should also mention: what I'm trying to do above is determine whether or not the node actually has a link href. If it does, I don't want to add the disabling code because it's not an active link to begin with. (That is possible because sometimes people can't actually access the pages in question.)

If you need any more information, please let me know.

Thanks,
Chris
0
Bozhidar
Telerik team
answered on 06 Nov 2012, 11:41 AM
Hello Chris,

Looking at the code I could not determine why it shouldn't work. Could you provide a live Url where a could test the TreeView, or better yet - a simplified working sample solution ( with minimized use of web services, data models and external libraries ), so that we can investigate the issue locally.
 
All the best,
Bozhidar
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now.
0
Chris
Top achievements
Rank 1
answered on 06 Nov 2012, 01:04 PM
Bozhidar,

I will do what I can, but please be advised it may take some time.

Thanks,
Chris
0
Aarsh
Top achievements
Rank 1
answered on 07 Nov 2012, 05:37 AM
I have had to do something similar where I was using a custom template and was using hyperlinks (href thing), some code like the sample below did the trick for me, I just hope if the same inspires you :

<html>
<head>
    <title>Untitled Page</title>
</head>
<body>
    <a href="http://www.google.com" onclick="alert('Stop that!'); return false;">Don't Click
        Here</a>
</body>
</html>

Thanks,
-Aarsh
Tags
TreeView
Asked by
Chris
Top achievements
Rank 1
Answers by
Bozhidar
Telerik team
Chris
Top achievements
Rank 1
Aarsh
Top achievements
Rank 1
Share this question
or