Disablinking link after clicking on RadTreeNode

8 posts, 0 answers
  1. Chris
    Chris avatar
    10 posts
    Member since:
    Jan 2012

    Posted 31 Oct 2012 Link to this post

    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
  2. Bozhidar
    Admin
    Bozhidar avatar
    1102 posts

    Posted 01 Nov 2012 Link to this post

    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.
  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. Chris
    Chris avatar
    10 posts
    Member since:
    Jan 2012

    Posted 01 Nov 2012 Link to this post

    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.
  5. Bozhidar
    Admin
    Bozhidar avatar
    1102 posts

    Posted 05 Nov 2012 Link to this post

    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.
  6. Chris
    Chris avatar
    10 posts
    Member since:
    Jan 2012

    Posted 05 Nov 2012 Link to this post

    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
  7. Bozhidar
    Admin
    Bozhidar avatar
    1102 posts

    Posted 06 Nov 2012 Link to this post

    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.
  8. Chris
    Chris avatar
    10 posts
    Member since:
    Jan 2012

    Posted 06 Nov 2012 Link to this post

    Bozhidar,

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

    Thanks,
    Chris
  9. Aarsh
    Aarsh avatar
    192 posts
    Member since:
    Jun 2012

    Posted 06 Nov 2012 Link to this post

    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
Back to Top
UI for ASP.NET Ajax is Ready for VS 2017