Auto collapse sliding pane on mouse leave or mouse click

7 posts, 0 answers
  1. Manu
    Manu avatar
    5 posts
    Member since:
    Jan 2009

    Posted 09 Jun 2010 Link to this post

    Requirements

    RadControls version: 10.1.5.19

     

    .NET version: n/a (needs to be compatible with RadControls version)

     

    Visual Studio version: n/a

     

    programming language: javascript, jQuery

     

    browser support

    all browsers supported by RadControls (tested in IE, but should work for all browsers).


    PROJECT DESCRIPTION
    In an earlier version of the RadSplitter control, when the user either clicked outside of a sliding pane, or left their mouse outside of the sliding pane for a couple of seconds, the sliding pane would automatically close (when it wasn't pinned).  With version 10.1.5.19 this functionality was removed.

    Our users were accustomed to this behavior so we decided to add it back.  The following code is a straightforward set of javascript functions that are named so that it's obvious which event handlers to attach them to.  Please note that a small amount of jQuery is used, so anyone using this will have to either reference the jQuery library, or use the syntax $telerik.$  or else rewrite that part in javascript.

    Javascript:


    var timeoutID; //id to track our timeout function for cancellation  
           var slidingZoneID;
           var slidingPaneID;
           function RadSlidingPane_OnClientExpanded(sender, args)
           {
               var timeoutMS = 2000; //time until the pane will close in milliseconds.  
               slidingZoneID = sender.get_parent().get_id();
               slidingPaneID = sender.get_id();
               document.body.onclick = body_onclick;
               //Set the pane to close if the user doesn't "enter" the pane within the time frame.  
               timeoutID = setTimeout("CollapseOnTimeout('" + slidingPaneID + "')", timeoutMS);
               //Set up mouse enter and leave events to track auto close:
               sender.getContentContainer().onmouseleave = function() { timeoutID = setTimeout("CollapseOnTimeout('" + slidingPaneID + "')", timeoutMS); };
               sender.getContentContainer().onmouseenter = function() { clearTimeout(timeoutID); };
           }
           function RadSlidingPane_OnClientCollapsing(sender, args)
           {
               document.body.onclick = null; //no longer need to collapse on body click as pane is closed.  
               clearTimeout(timeoutID);
           }
           //Closes the sliding pane if elements outside the pane are clicked.  
           function body_onclick(e)
           {
               var eventIsFiredFromElement;
               if (e == null)
               {
                   // I.E.  
                   eventIsFiredFromElement = event.srcElement;
               }
               else
               {
                   // Firefox  
                   eventIsFiredFromElement = e.target;
               }
               //Only close pane if the user clicked outside of the sliding pane:  
               var isChildOfSlidingPane = false;
               //Below is the only jQuery, which is used to test all the parents of our  
               //clicked control to see if it's in our sliding pane.  
               if (eventIsFiredFromElement.id == slidingZoneID)
                   isChildOfSlidingPane = true;
               else if (eventIsFiredFromElement.id != "" && $telerik.$("#" + eventIsFiredFromElement.id).parents("[id=" + slidingZoneID + "]").length > 0)
                   isChildOfSlidingPane = true;
               if (!isChildOfSlidingPane)
                   CollapseOnTimeout(slidingPaneID);
           }
           function CollapseOnTimeout(radSlidingPaneID)
           {
               $find(radSlidingPaneID).get_parent().collapsePane(radSlidingPaneID);
           }

    Sample ASPX file:

    <telerik:RadSplitter ID="Radsplitter2" runat="server" Height="500px" Width="500px"
            Orientation="Vertical">
            <telerik:RadPane ID="Radpane1" runat="server" Width="24" Scrolling="None" Height="800px">
                <telerik:RadSlidingZone ID="RadSlideZone" runat="server" SlideDirection="Right" Width="22"
                    Height="800px" ClickToOpen="true">
                    <telerik:RadSlidingPane ID="RadSlidingPaneFilters" runat="server" OnClientExpanded="RadSlidingPane_OnClientExpanded"
                        OnClientCollapsing="RadSlidingPane_OnClientCollapsing" Title="First" Width="350px"
                        Height="800px" Scrolling="None">
                        <div style="padding: 5px 0px 0px 5px">
                            content for sliding pane here.
                        </div>
                    </telerik:RadSlidingPane>
                </telerik:RadSlidingZone>
            </telerik:RadPane>
            <telerik:RadPane Scrolling="None" ID="Radpane2" runat="server">
                <div style="padding-left: 5px;">
                    content for right pane here.
                </div>
            </telerik:RadPane>
        </telerik:RadSplitter>



    With that, we were able to successfully reproduce the old "auto close" behavior.  Hopefully that helps some other people out!
  2. Svetlina Anati
    Admin
    Svetlina Anati avatar
    2795 posts

    Posted 15 Jun 2010 Link to this post

    Hi Manu,

    Thank you very much for taking the time and effort to share your solution with our community, we highly appreciate and encourage this!

    We examined the demo code we prepared a sample page based on it which is attached ti the thread. We also replaced some private methods/properties you have used and improved the markup a bit - all the above explained changes are applied to the snippet you initially wrote as well. Note, also that you can reference the built in jQuery in Telerik.Web.UI by using the $telerik.$ syntax and we also changed this accordingly.

    Thank you once again for your kind cooperation, we updated your account with 1500 Telerik points for it!

    Greetings,
    Svetlina
    the Telerik team

    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
  3. Manu
    Manu avatar
    5 posts
    Member since:
    Jan 2009

    Posted 15 Jun 2010 Link to this post

    Hello Svetlina,

    I appreciate the approved submission.  Since then I did some more testing and found a couple of bugs when the sliding pane contained certain rad controls.  In certain cases the pane would close when clicking a control inside the pane.

    I've modified the javascript code (and included your changes) so that it addresses this issue:

    var timeoutID; //id to track our timeout function for cancellation 
    var slidingZoneID; 
    var slidingPaneID; 
    var timeoutMS = 2000; //time until the pane will close in milliseconds. 
    function RadSlidingPane_OnClientExpanded(sender, args) {     
        slidingZoneID = sender.get_parent().get_id(); 
        slidingPaneID = sender.get_id(); 
     
        document.body.onclick = body_onclick; 
     
        //Set the pane to close if the user doesn't "enter" the pane within the time frame. 
        timeoutID = setTimeout("CollapseOnTimeout('" + slidingPaneID + "')", timeoutMS); 
     
        //Set up mouse enter and leave events to track auto close: 
        sender.getContentContainer().onmouseleave = contentElement_OnMouseLeave; 
        sender.getContentContainer().onmouseenter = function () { clearTimeout(timeoutID); }; 
     
    //Closes the sliding pane if elements outside the pane are clicked. 
    function body_onclick(e) { 
        var element; 
        if (e == null
            element = event.srcElement; // I.E. 
        else  
            element = e.target; // Firefox 
     
        var slidingPane = $find(slidingPaneID); 
     
        if (!slidingPane.get_docked() && !slidingPane.get_collapsed()) //Make sure dock isn't pinned and that it's expanded when setting time out javascript!!! 
            if (!IsChildOfSlidingPane(element)) //Only close pane if the user clicked outside of the sliding pane: 
                CollapseOnTimeout(slidingPaneID); 
     
    function RadSlidingPane_OnClientCollapsing(sender, args) { 
        document.body.onclick = null//no longer need to collapse on body click as pane is closed.   
        clearTimeout(timeoutID); 
     
    function contentElement_OnMouseLeave(e) { 
        var element; 
        var posx = 0; 
        var posy = 0; 
         
        //get the source of the event (should always be the contentElement object of the rad sliding zone: 
        if (!e) { 
            var e = window.event; 
            element = e.srcElement; 
        } 
        else 
            element = e.target; 
     
        //get our mouse coordinates: 
        if (e.pageX || e.pageY) { 
            posx = e.pageX; 
            posy = e.pageY; 
        } 
        else if (e.clientX || e.clientY) { 
            posx = e.clientX + document.body.scrollLeft 
                + document.documentElement.scrollLeft; 
            posy = e.clientY + document.body.scrollTop 
                + document.documentElement.scrollTop; 
        } 
     
        //get our element coordinates 
        var xleft = element.offsetLeft; 
        var xelement = element; 
        while (xelement = xelement.offsetParent) xleft += xelement.offsetLeft; 
        var xright = element.clientWidth + xleft; 
     
        var ytop = element.offsetTop; 
        var yelement = element; 
        while (yelement = yelement.offsetParent) ytop += yelement.offsetTop; 
        var ybottom = element.clientHeight + ytop; 
     
        //only set time out if the mouse left the contentElement: 
        if (posx < xleft || posx > xright || posy < ytop || posy > ybottom) 
            timeoutID = setTimeout("CollapseOnTimeout('" + slidingPaneID + "')", timeoutMS); 
     
    function CollapseOnTimeout(radSlidingPaneID) { 
        $find(radSlidingPaneID).get_parent().collapsePane(radSlidingPaneID); 
     
    function IsChildOfSlidingPane(element) { 
        var isChildOfSlidingPane = false
           
        while (element.id == "" && element.parentElement) 
            element = element.parentElement; 
        if (element.id == slidingZoneID) 
            isChildOfSlidingPane = true
        else if (element.id != "") { 
            if ($telerik.$("#" + element.id).parents("[id=" + slidingZoneID + "]").length > 0) 
                isChildOfSlidingPane = true
            else if ($telerik.$("#" + element.id).parents("[class=rcbSlide]").length > 0)  //make sure that the element isn't the iframe part of a radcombobox: 
                isChildOfSlidingPane = true
        } 
        return isChildOfSlidingPane; 

    Note that we also had an issue with some RadComboBoxes not closing when the sliding pane closed (automatically or otherwise).  If anyone experiences this issue let me know and I'll post our solution.

    Thanks!
  4. Svetlina Anati
    Admin
    Svetlina Anati avatar
    2795 posts

    Posted 18 Jun 2010 Link to this post

    Hi Manu,

    Thank you for pointing out and solving the problems with the code library. Please, log in your account and correct the text description if this is needed and update the demo as well.

    On a side note I checked your points history and I noticed that for some reason the points I added to your account were not there - please, accept our apologies for this, we readded them again.

    As to the combo box scenario, what you describe is the expected behavior and it should be solved by catching the OnClientCollapse event and explicitly hiding the dropdown. Note, that this is so for all controls with popup behavior, e.g you can also examine the following KB article:

    http://www.telerik.com/support/kb/aspnet-ajax/tooltip/radcontrols-with-a-popup-in-radtooltip.aspx

    The article is for RadToolTip but the sliding pane goes through the same logic - it shows and it is hidden after that and the core logic is the same.

    Thank you once again for your kind cooperation, we highly appreciate it!

    Kind regards,
    Svetlina
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  5. Patrick
    Patrick avatar
    1 posts
    Member since:
    Dec 2007

    Posted 13 Aug 2012 Link to this post

    Is this work-around still relevant, or has a new auto-collapse feature (property) been added directly to the RadSlidingZone control (i.e. built-in functionality on the control)?  We are using Telerik.Web.UI, v.2012.1.418.35.

    Thanks.
  6. Vessy
    Admin
    Vessy avatar
    1382 posts

    Posted 15 Aug 2012 Link to this post

    Hi Patrick,

    This code library (and respectively the proposed workaround) is made about the Classic RadSplitter, while Telerik.Web.UI is the RadControls for ASP.NET AJAX suite. The auto-collapse (expand) functionality is implemented as a default behavior of RadSplitter for ASP.NET AJAX.

    The ClickToOpen property is in control of that. If it is set to false the SlidingPane displays itself on hover (which is set by default), otherwise (ClickToOpen="true") it is displayed after a click.

    Kind regards,
    Veselina
    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.
  7. Julius
    Julius avatar
    8 posts
    Member since:
    Dec 2012

    Posted 02 Apr 2013 Link to this post

    Hi,

    This script doesn't really work for me. It works when I move my mouse off the sliding pane, but when I click an item of a DropDownList inside the sliding pane or scrolling through items in the DropDownList, the sliding pane collapses straight away. Any ideas?
Back to Top