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

Sliding Pane set_clickToOpen() doesn't override closing behaviour

3 Answers 82 Views
Splitter
This is a migrated thread and some comments may be shown as answers.
Massimiliano
Top achievements
Rank 1
Massimiliano asked on 09 Apr 2013, 07:48 PM
I'm trying to have a responsive sliding pane so that when the windows shrinks below tot pixels all the panes close and their behaviour is to auto-close themselves like setting ClickToOpen="false" in the markup.
When the window is bigger instead, I want them to stay open always, exactly what happens having ClickToOpen="true" in the markup.
So I thought this was a simple matter. With JS/Jquery I dedect windows resize (and orientation change for mobiles) and when windows goes below tot pixels I set set_clickToOpen(false), when the window size gets bigger I set set_clickToOpen(true).
I check with an alert(myslidingzoneID.get_clickToOpen()) and everything is set correctly on window resizes but for some reason the auto-close behaviour won't change, it always remains the same I set in the markup (default false if I don't set it in the markup).
How can make this to work? I'm opening the panes clicking on external buttons and calling code like (it's a prototype):

function ButtonClick(x) {
    var sz = $find("RadSlidingZoneMainAdminMenu");
    alert(sz.get_clickToOpen(false));
    if (x == '1') {
        OpenPane('AdminMenuGeneral');
    }
    if (x == '2') {
        OpenPane('AdminMenuComponents');
    }
}
function OpenPane(x) {
    //ExpandSlider();
    var sz = $find("<%= RadSlidingZoneMainAdminMenu.ClientID%>");
    sz.ExpandPane(x);
}

And it work perfect so I don't use the  set_clickToOpen() method to change the opening behaviour but I need it to change the CLOSING behaviour (from auto close to manual close and vice versa).

Also a related question is... can I change the autoclose timing to make it faster when you mouseover from the opened pane?
And is it possible (in addittion to the standard autoclose with its default time) to close the pane clicking out of it? I know this is possible with a simple function like:

$('body').bind('click', function (event) {
    ' check open pane and collapse it
});

But this will collapse the pane even if I click INSIDE it, so how could I check it the click was made outside the pane to anticipate the autoclose feature?

Hoping in your always enlightning support.
Best regards

3 Answers, 1 is accepted

Sort by
0
Massimiliano
Top achievements
Rank 1
answered on 09 Apr 2013, 10:03 PM
I founda workaround for my main question (that I will post tomorrow) but is kind of an "hack" so if there is a more neat solution for the switch from auto-close to "never-close", you are welcome.

For the other question, the "close on click just outside" one, I have also the solution (and this makes trival the need to change the autoclose timing, since you can simply click out of the pane to close it). I will post it tomorrow as well for other users to benefit from.
0
Massimiliano
Top achievements
Rank 1
answered on 10 Apr 2013, 01:43 PM
Ok here is how I solved but if you have some suggestion to make it more "neat" and "robust" please...

PROBLEM: I wanted the sliding panes to change behaviour together with my responsive design. I wanted the panes to stay open on large screens and to auto-close (or close clicking outside of them) on smaller screens.
I also don't use the panes tabs to open the panes or to switch from one to another (in the case when they are always open), but I use standard HTML elements (links <a> in this case) with onclick behaviour wich triggers the panes.

SOLUTION: Since switching the ClickToOpen state client side didn't change the closing behaviour, I had to resort to some "tricks".
First of all I set the ClickToOpen to false so that the "auto-close" was always triggered.
Then I had to prevent the auto-close when window size was confortable enought to have them always open.
This was the focal point. Then I added the option to close the panes (only when the auto-close is allowed, when screen size is small and I don't want to keep the panes open) clicking OUTSIDE of them.

Here is how I did everything.
In the markup side:
<telerik:RadSplitter ID="MainAdminMenu" ClientIDMode="Static" runat="server" Width="310" Height="500" Orientation="Vertical" BorderSize="0" BorderWidth="0" PanesBorderSize="0">
     <telerik:RadPane ID="RadPaneMainAdminMenu" ClientIDMode="Static" runat="server" Scrolling="None" Width="312" Collapsed="false" Locked="true" BorderWidth="0">
         <telerik:RadSlidingZone  ID="RadSlidingZoneMainAdminMenu" ClientIDMode="Static" runat="server" Width="90" ClickToOpen="false" OnClientLoaded="ExpandInitialPane">
             <telerik:RadSlidingPane ID="AdminMenuGeneral" ClientIDMode="Static" runat="server" Scrolling="Y" EnableResize="false" EnableDock="true" Width="208px" OnClientCollapsing="CollapsePane" OnClientCollapsed="CollapsedPane" OnClientExpanded="ExpandedPane">

As you can see the trick here is manly obtained calling client side methods. The first one is in the main RadSlidingZone:
ClickToOpen="false" OnClientLoaded="ExpandInitialPane"

This calls a js function wich checks the widht of the window. If the window is big enough it will display the pane (panes have to be always opened). If the windows is small it doesn't display anything (panes are opened clickin con HTML links and then auto-close or are closed clicking outside of them)
function ExpandInitialPane(sender, args) {
    if ($(window).width() > 1239) {
        sender.ExpandPane("AdminMenuGeneral");
    }
}
Here I put a fixed AdminMenuGeneral pane but this should be handled by you application (based on page URL or whatever)

The second javascript "trick" goes in EACH RadSlidingPane control and is 
OnClientCollapsing="CollapsePane" OnClientCollapsed="CollapsedPane" OnClientExpanded="ExpandedPane"

Here it's a bit more complex. Let's say that preventing auto-close (with OnClientCollapsing) when window was big and I always wanted a pane open, wasn't enought. That's because when you click to switch from one pane to another, the first pane actually HAS to close. So if you just prevent auto-close based on window size you won't be able to switch from one pane to another.
I solved declaring a global JS variable wich is actually a flag that tells the code if the pane can be closed or not.
This way I can "force" the closing of a pane when I click to open another one and disable it to prevent the auto-close feature of the ClickToOpen="false" state, checking this variable TOGETHER with the window size.
The other two client methods are there just to set this control flag to the right state after the tab has closed (OnClientCollapsed) and after it has opened (OnClientExpanded - note I also use here another control flag for the "click oustisde to close" trick).
So, including the function that let me open/switch the panes clicking on standard HTML links here is the full code:

var SlidingPaneForceClose = 0;
var SlidingPaneOpened = 0;
 
$(document).ready(function () {
    // Adjust the Admin Main Menu RadSlidingPane properties for responsive design
    $(window).on("throttledresize", function (event) {
        var sz = $find("RadSlidingZoneMainAdminMenu");
        if ($(window).width() >= 768 && $(window).width() <= 1239) {
            // Close any open pane
            SlidingPaneForceClose = 1;
            sz.collapsePane(sz.get_expandedPaneId());
        }
        if ($(window).width() > 1239) {
            SlidingPaneForceClose == 0
            if (sz.get_expandedPaneId() == null) { sz.ExpandPane("AdminMenuGeneral") }
        }
    });
 
    // Listen for orientation changes
    window.addEventListener("orientationchange", function () {
        $(window).trigger("throttledresize", [true]);
    }, false);
});
 
// RadSlidingPane Admin Main Menu functionalities and responsive fixes
function ButtonClick(x) {
    SlidingPaneForceClose = 1
    if (x == "1") {
        OpenPane("AdminMenuGeneral");
    }
    if (x == "2") {
        OpenPane("AdminMenuComponents");
    }
}
function OpenPane(x) {
    var sz = $find("RadSlidingZoneMainAdminMenu");
    sz.ExpandPane(x);
}
function CollapsedPane(sender, args) {
    SlidingPaneForceClose = 0
    SlidingPaneOpened = 0
}
function ExpandedPane(sender, args) {
    SlidingPaneOpened = 1
}
function ExpandInitialPane(sender, args) {
    if ($(window).width() > 1239) {
        sender.ExpandPane("AdminMenuGeneral");
    }
}
function CollapsePane(sender, args) {
    if ($(window).width() > 1239 && SlidingPaneForceClose == 0) {
        args.set_cancel(true);
    }
}

The "ThrottledResize" function is just a little external js snippet wich makes uniform the resizing behaviour on every browser (I set this at 15 checks per second) but it's not really needed. You could simply resort to checking window resize and orientationchange events.
Anyway if you want to check this external js you can find it here: https://github.com/louisremi/jquery-smartresize
I choose 1240 as my "ok to keep the panes always open" windows size. The code is a prototype so this number should be moved to a costant and everything else refactored.
The ButtonClick function is triggered by standard HTML links <a> onclick event wich calls the function with a number like onclick="ButtonClick(1);return false"

0
Massimiliano
Top achievements
Rank 1
answered on 10 Apr 2013, 01:52 PM
Now about the "click outside the pane" to close it ONLY when the windows is small and the panes have to be opened on click and they auto-close.
The only main issue I found with this approach was that, clicking on my HTML links <a> to trigger the onclick event and call the ButtonClick(n) function, would immediatly also close the pane with the result that no pane at all ever opened anymore.
To solve this I had to intruduce another flag wich allowed the "close on click outside" behaviour together with the window size.
This flag was set by the ExpandedPane function, called by the OnClientExpanded event attached to each pane.
This will tell the code when a pane is actually really opened and allow the closing clicking outside of it, without preventing the opening from the start (because the links that open the panes are in effect OUT of the panes).

The other part was simply to bind the click event to the whole document and checking that the click didn't happen inside the pane.
The code for this part is:
var SlidingPaneForceClose = 0;
var SlidingPaneOpened = 0;
 
$(document).ready(function () {
    $('html').bind('click', function (event) {
        // RadSlidingPane Admin Menu close on click outside of it when in small desktop mode
        var sz = $find("RadSlidingZoneMainAdminMenu");
        if ($(event.target).closest("#RadPanelBarMainAdminMenu").length == 0) {
            if ($(window).width() <= 1239 && SlidingPaneOpened == 1) {
                // Close any open pane
                SlidingPaneForceClose = 1;
                sz.collapsePane(sz.get_expandedPaneId());
            }
        }
    });
});


So the whole JS code that handles all the events is:

var SlidingPaneForceClose = 0;
var SlidingPaneOpened = 0;
 
$(document).ready(function () {
    $('html').bind('click', function (event) {
        // RadSlidingPane Admin Menu close on click outside of it when in small desktop mode
        var sz = $find("RadSlidingZoneMainAdminMenu");
        if ($(event.target).closest("#RadPanelBarMainAdminMenu").length == 0) {
            if ($(window).width() <= 1239 && SlidingPaneOpened == 1) {
                // Close any open pane
                SlidingPaneForceClose = 1;
                sz.collapsePane(sz.get_expandedPaneId());
            }
        }
    });
 
    // Adjust the Admin Main Menu RadSlidingPane properties for responsive design
    $(window).on("throttledresize", function (event) {
        var sz = $find("RadSlidingZoneMainAdminMenu");
        if ($(window).width() >= 768 && $(window).width() <= 1239) {
            // Close any open pane
            SlidingPaneForceClose = 1;
            sz.collapsePane(sz.get_expandedPaneId());
        }
        if ($(window).width() > 1239) {
            SlidingPaneForceClose == 0
            if (sz.get_expandedPaneId() == null) { sz.ExpandPane("AdminMenuGeneral") }
        }
    });
 
    // Listen for orientation changes
    window.addEventListener("orientationchange", function () {
        $(window).trigger("throttledresize", [true]);
    }, false);
});
 
// RadSlidingPane Admin Main Menu functionalities and responsive fixes
function ButtonClick(x) {
    SlidingPaneForceClose = 1
    if (x == "1") {
        OpenPane("AdminMenuGeneral");
    }
    if (x == "2") {
        OpenPane("AdminMenuComponents");
    }
}
function OpenPane(x) {
    var sz = $find("RadSlidingZoneMainAdminMenu");
    sz.ExpandPane(x);
}
function CollapsedPane(sender, args) {
    SlidingPaneForceClose = 0
    SlidingPaneOpened = 0
}
function ExpandedPane(sender, args) {
    SlidingPaneOpened = 1
}
function ExpandInitialPane(sender, args) {
    if ($(window).width() > 1239) {
        sender.ExpandPane("AdminMenuGeneral");
    }
}
function CollapsePane(sender, args) {
    if ($(window).width() > 1239 && SlidingPaneForceClose == 0) {
        args.set_cancel(true);
    }
}


I hope this helps someone. If you need additional infos on this code let me know. If you have suggestions to improve it you are more than welcome!
Actually I tested it with all desktop browser down to IE7 and everything works GREAT.
Tags
Splitter
Asked by
Massimiliano
Top achievements
Rank 1
Answers by
Massimiliano
Top achievements
Rank 1
Share this question
or