Hi,
I've noticed that on my site some of the rightmost drop down elements on a Navigation menu open partially off screen. In the demo I have seen that they seem to work better. Is there some css based mechanism on the parent div that will force menus to open on screen. I saw the menus open to the left on the demo here (http://demos.telerik.com/aspnet-ajax/navigation/overview/defaultvb.aspx?show-source=true), on my bar the last element would open displaying the menu off screen...
Regards
Jon
14 Answers, 1 is accepted
In the linked demo the last element on the Navigation bar is the sandwich button. Its not a standard navigation node but acts as a container for nodes that cannot be shown on the navigation when there is not enough space to display them. You will notice in the demo that the Navigation is placed in a div, which limits its width and some of the nodes are hidden under the button.
The sandwich button's dropdown automatically expands to the left unlike the Navigation nodes' dropdowns. Currently the Navigation control does not support setting the expand direction of its nodes.
Regards,
Ivan Danchev
Telerik
Hi Ivan,
Yes sorry it's the normal drop downs that cause the issue. With some of them being nested they open off screen - see the attached image. The parent divs are set to be 100% width. Do I need to force an explicit width?
Regards
Jon
Since the Nodes expand direction cannot be set and boundary detection is not supported we can suggest setting margins (left and right) to the Navigation's container div so that the control does not occupy 100% of the screen width. This way the nodes will be rendered farther from the right side of the window leaving more room for the child nodes to expand.
You can also vote for adding screen boundary detection to the Navigation in this feature request in our Feedback Portal.
Regards,
Ivan Danchev
Telerik
Hi Ivan,
I think that the width will always have issues when using the margin work around.
In theory would a custom mechanism using the OnClientNodeExpanding event be able to detect if the new child menu will go off screen and adjust accordingly? If it would work I'll whip one together.
Regards
Jon
We were not able to come up with a workaround other than keeping the control occupy less than 100% of the window's width. Here's a short video showing how leaving an extra space to the right of the control will allow to expand the nodes within the boundaries of the window and on resize the items are be collapsed under the sandwich button.
Implementing the boundary detection would not be a trivial task and we are considering adding this feature in one of our future releases.
Regards,
Ivan Danchev
Telerik
Hi Ivan,
Given that I have a limited set of situations I now have it kind of working (see js below). The issues that I have with the below are:
1)I need to work out if the expanding node is under the more menu and do nothing if that is the case - I may need to detect the css class as there seems to be no flag for this?
2) The sub menus on normal nodes go to the left if they'd go off screen BUT they still open left to right. Small issue but being able to get them to open opposite the normal way would be a nice to have.
Have a good weekend
Regards
Jon
Code so far is as follows:
function
uxRadNavigationMainPage_OnClientNodeExpanded(sender, args) {
var
node = args.get_node();
var
nodePanelRect = node.get_element().getBoundingClientRect();
var
childPanelRect = node.get_nodes()._data[0]._element.parentElement.getBoundingClientRect();
if
(node.get_level()===0){
if
(childPanelRect.right > (getClientWidth() - 10)) {
node.get_nodes()._data[0]._element.parentElement.parentElement.parentElement.style.left = (getClientWidth() - 10 - childPanelRect.width) +
'px'
;
}
}
else
{
var
parentNodeRight = nodePanelRect.left + nodePanelRect.right;
if
((parentNodeRight + childPanelRect.width) > (getClientWidth() - 10)) {
node.get_nodes()._data[0]._element.parentElement.parentElement.parentElement.style.left = (nodePanelRect.left - 10 - childPanelRect.width) +
'px'
;
}
}
}
Well the following works although if there is a more elegant way to detect the more menu then this would be a lot shorter. And I'd still like to resolve the issue with the menu opening from left to right when its been moved. Butter than falling off the page though.
Please still look at an integrated detection mechanism though as the control seems broken without an integral self check.
function
uxRadNavigationMainPage_OnClientNodeExpanded(sender, args) {
var
node = args.get_node();
var
parentNode = node;
while
(parentNode.get_level() !== 0) {
// While below is true the element is a node
if
(
typeof
parentNode.get_parent().get_level ===
'function'
){
parentNode = parentNode.get_parent();
}
}
var
parentNodePanelRect = parentNode.get_element().getBoundingClientRect();
var
uxRadNavigationMainPageRect = $find(
'uxRadNavigationMainPage'
).get_element().getBoundingClientRect();
var
inMoreDropDown =
false
;
// If the top level isn't at the same height as teh menu it must be in the more column
if
(parentNodePanelRect.top - 10 > uxRadNavigationMainPageRect.top) { inMoreDropDown =
true
}
if
(!inMoreDropDown) {
var
nodePanelRect = node.get_element().getBoundingClientRect();
var
childPanelRect = node.get_nodes()._data[0]._element.parentElement.getBoundingClientRect();
if
(node.get_level()===0){
if
(childPanelRect.right > (getClientWidth() - 10)) {
node.get_nodes()._data[0]._element.parentElement.parentElement.parentElement.style.left = (getClientWidth() - 10 - childPanelRect.width) +
'px'
;
}
}
else
{
var
parentNodeRight = nodePanelRect.left + nodePanelRect.width;
if
((parentNodeRight + childPanelRect.width) > (getClientWidth() - 10)) {
node.get_nodes()._data[0]._element.parentElement.parentElement.parentElement.style.left = (nodePanelRect.left - 10 - childPanelRect.width) +
'px'
;
}
}
}
}
I am glad you have come up with a workaround, even though I was not able to fully test it at my end, because I am not sure what value do you return with the getClientWidth() function.
As for another way to detect when a node is collapsed under the sandwich button, you can do so by checking the wrapping div's class:
var
nodeElement = node.get_element();
if
(nodeElement.parentNode.parentNode.className !==
"rnvRootGroupWrapper"
) {
inMoreDropDown =
true
;
}
We will look into implementing the boundary detection that's missing in the Navigation control, as this is a useful feature that is already present for other controls (the Menu for example).
Regards,
Ivan Danchev
Telerik
Hi Ivan
Thanks for the code although it would only work on a fixed level wouldn't it ?
The getClientWidth just gets the width of the client window. It all seems to work well.
Is there any way of changing the opening direction of the child menu items? That would be the final component to my collision detection.
Regards
Jon
One way to change the direction of the nodes dropdown is to use the code below for example that will make the node expand to the top:
var
nav = $find(
"<%=RadNavigation1.ClientID%>"
);
nav.get_nodes().getNode(0)._dropDown.set_direction(1);
Regards,
Plamen
Telerik
Hi Ivan,
In the video, I like how the menu shows some extra space and makes use of it when needed. Can you post the code on how to do that?
Sincerely,
Keith Jackson
This is done by adding right and left margin to the div that contains the Navigation:
.container {
margin
:
0
100px
0
100px
;
}
<
div
class
=
"container"
>
<
telerik:RadNavigation
ID
=
"RadNavigation1"
runat
=
"server"
RenderMode
=
"Lightweight"
>
</
telerik:RadNavigation
>
</
div
>
Regards,
Ivan Danchev
Telerik by Progress
Thanks Ivan!
Sincerely,
Keith Jackson