Stuart Hemming
Top achievements
Rank 2
Stuart Hemming
asked on 13 Aug 2010, 02:02 PM
I think this is a non-starter, but here goes ...
I have a requirement to have a menu across the top of the page. The menu should occupy 100% of the screen width.
I need to have a number of items appear left aligned in the menu and then a number right-aligned. And I mean in the menu itself, so, If I had 5 items in my menu they'd look like this for a normal menu (forgive the text layout of this example)...
My user wants ...
Is this possible?
--
Stuart
I have a requirement to have a menu across the top of the page. The menu should occupy 100% of the screen width.
I need to have a number of items appear left aligned in the menu and then a number right-aligned. And I mean in the menu itself, so, If I had 5 items in my menu they'd look like this for a normal menu (forgive the text layout of this example)...
First Second Third Fourth Fifth
My user wants ...
First Second Third Fourth Fifth
Is this possible?
--
Stuart
15 Answers, 1 is accepted
0
Stuart Hemming
Top achievements
Rank 2
answered on 13 Aug 2010, 02:12 PM
I have had something like it working with 2 RadMenus where the 2nd uses Dir="rtl" but there is a gap between them unless viewed in IE8 with compatibility switched on.
I've also had various failed attempts using templates.
--
Stuart
I've also had various failed attempts using templates.
--
Stuart
0
Cori
Top achievements
Rank 2
answered on 13 Aug 2010, 02:31 PM
Hello Stuart,
I have two possible solutions, hopefully you'll like one of them.
1. Using the single menu approach, you could add a blank menu item that acts as the separator and has its enabled state set to false, so they can't click on it. That way their is no gap between the two sets of items. You'll need to set the width as well, for it to occupy the correct width, but I can see the issue where it would fail on a window resize, unless you set the width of your other menu items.
2. Using the two menu approach, you could contain both in a div and the set the background image of the div to the one used by the RadMenu, so it doesn't look like their is a gap.
I was going to suggest to float the items on the right, but it doesn't work as I would have hoped.
I hope my solutions were helpful.
I have two possible solutions, hopefully you'll like one of them.
1. Using the single menu approach, you could add a blank menu item that acts as the separator and has its enabled state set to false, so they can't click on it. That way their is no gap between the two sets of items. You'll need to set the width as well, for it to occupy the correct width, but I can see the issue where it would fail on a window resize, unless you set the width of your other menu items.
2. Using the two menu approach, you could contain both in a div and the set the background image of the div to the one used by the RadMenu, so it doesn't look like their is a gap.
I was going to suggest to float the items on the right, but it doesn't work as I would have hoped.
I hope my solutions were helpful.
0
Stuart Hemming
Top achievements
Rank 2
answered on 13 Aug 2010, 02:42 PM
Cori,
You're right, I think about the first option. There are too many opportunities for it to break.
The 2nd option works but is a pain in that I have to allow my users to swap skins so I need to make sure that the relevant resources are available for each case. Grrrr.
Thanks for your input
--
Stuart
You're right, I think about the first option. There are too many opportunities for it to break.
The 2nd option works but is a pain in that I have to allow my users to swap skins so I need to make sure that the relevant resources are available for each case. Grrrr.
Thanks for your input
--
Stuart
0
Accepted
Cori
Top achievements
Rank 2
answered on 13 Aug 2010, 03:31 PM
Hello Stuart,
After playing around with jQuery, I think I have solution that you might like. So using my first solution, the single menu with an empty menu item used as the separator between the left and right items, I came up with a jQuery function that will resize the separator when the window resizes and I think it does a pretty good job. So here it is:
So pretty much it calculates the width of all the menu items and then subtracts it from the total window width and then returns the percent that the separator should be. I took into consideration the borders of the menu items, so the width doesn't push the other items to the next line. I set the empty menu item to have a value of "Empty" so that I can exclude it from my calculation of all the menu items.
You can even add this method to run in the document.ready() event, so it loads the correct width for the separator element when the page loads.
I hope that helps.
After playing around with jQuery, I think I have solution that you might like. So using my first solution, the single menu with an empty menu item used as the separator between the left and right items, I came up with a jQuery function that will resize the separator when the window resizes and I think it does a pretty good job. So here it is:
$telerik.$(window).resize(
function
() {
// get width of window
var
windowWidth = $telerik.$(window).width();
// menu item widths
var
menuItemWidth = 0;
// get menu
var
menu = $find(
"<%=mnuTest.ClientID %>"
);
for
(
var
i = 0; i < menu.get_allItems().length; i++) {
if
(menu.get_allItems()[i].get_value() !=
"Empty"
) {
menuItemWidth += $telerik.$(menu.get_allItems()[i].get_element()).width() + 2;
}
}
// get percent to adjust separator menu item
var
percentToAdjust = Math.floor((windowWidth - menuItemWidth) / windowWidth * 100);
$telerik.$(menu.
findItemByValue(
"Empty"
).get_element()).width(percentToAdjust +
"%"
);
});
So pretty much it calculates the width of all the menu items and then subtracts it from the total window width and then returns the percent that the separator should be. I took into consideration the borders of the menu items, so the width doesn't push the other items to the next line. I set the empty menu item to have a value of "Empty" so that I can exclude it from my calculation of all the menu items.
You can even add this method to run in the document.ready() event, so it loads the correct width for the separator element when the page loads.
I hope that helps.
0
Stuart Hemming
Top achievements
Rank 2
answered on 13 Aug 2010, 03:33 PM
I'll have a play now. I really must take the time to lean something of jQuery! :-) ...
--
Stuart
--
Stuart
0
Stuart Hemming
Top achievements
Rank 2
answered on 13 Aug 2010, 03:50 PM
Cori,
It only works in compatibility mode in IE8 :-( Mind yoiu, it works great then! :-)
I can see the code is executing in Chrome but there's nothing happening on the screen to suggest it's doing anything,
--
Stuart
It only works in compatibility mode in IE8 :-( Mind yoiu, it works great then! :-)
I can see the code is executing in Chrome but there's nothing happening on the screen to suggest it's doing anything,
--
Stuart
0
Stuart Hemming
Top achievements
Rank 2
answered on 13 Aug 2010, 04:03 PM
Ha!
I'm not convinced that RadMenu is rendering the RadMenuItem if the text is String.Empty. Setting it to " " makes it work!
Nice one.
Now to work how to get it working for OnLoad ...
--
Stuart
I'm not convinced that RadMenu is rendering the RadMenuItem if the text is String.Empty. Setting it to " " makes it work!
Nice one.
Now to work how to get it working for OnLoad ...
--
Stuart
0
Stuart Hemming
Top achievements
Rank 2
answered on 13 Aug 2010, 04:33 PM
Cori,
Thanks a lot for the help.
For anyone that's interested, here's my test example page ...
--
Stuart
Thanks a lot for the help.
For anyone that's interested, here's my test example page ...
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<
html
xmlns
=
"http://www.w3.org/1999/xhtml"
>
<
head
runat
=
"server"
>
<
title
></
title
>
<
style
type
=
"text/css"
>
</
style
>
</
head
>
<
body
>
<
form
id
=
"form1"
runat
=
"server"
>
<
div
>
<
telerik:RadScriptManager
ID
=
"RadScriptManager1"
runat
=
"server"
>
</
telerik:RadScriptManager
>
<
telerik:RadScriptBlock
ID
=
"RadScriptBlock1"
runat
=
"server"
>
<
script
type
=
"text/javascript"
>
function doResize()
{
// get width of window
var windowWidth = $telerik.$(window).width();
// menu item widths
var menuItemWidth = 0;
// get menu
var menu = $find("<%=RadMenu1.ClientID %>");
for (var i = 0; i <
menu.get_allItems
().length; i++)
{
if (menu.get_allItems()[i].get_value() != "Empty")
{
menuItemWidth += $telerik.$(menu.get_allItems()[i].get_element()).width() + 2;
}
}
// get percent to adjust separator menu item
var
percentToAdjust
=
Math
.floor((windowWidth - menuItemWidth) / windowWidth * 100);
$telerik.$(menu.findItemByValue("Empty").get_element()).width(percentToAdjust + "%");
}
var
resizeTimer
=
null
;
$telerik.$(window).resize(function()
{
if (resizeTimer) clearTimeout(resizeTimer);
resizeTimer
=
setTimeout
(doResize, 100);
});
$telerik.$(document).ready(function()
{
if (resizeTimer) clearTimeout(resizeTimer);
resizeTimer
=
setTimeout
(doResize, 100);
});
</script>
</
telerik:RadScriptBlock
>
<
telerik:RadMenu
ID
=
"RadMenu1"
runat
=
"server"
Skin
=
"WebBlue"
Width
=
"100%"
>
<
Items
>
<
telerik:RadMenuItem
Text
=
"Application"
></
telerik:RadMenuItem
>
<
telerik:RadMenuItem
Text
=
"Logoff"
></
telerik:RadMenuItem
>
<
telerik:RadMenuItem
Value
=
"Empty"
Enabled
=
"false"
Text
=
" "
/>
<
telerik:RadMenuItem
Text
=
"What's New"
></
telerik:RadMenuItem
>
<
telerik:RadMenuItem
Text
=
"Document Store"
></
telerik:RadMenuItem
>
<
telerik:RadMenuItem
Text
=
"Calendar"
></
telerik:RadMenuItem
>
<
telerik:RadMenuItem
Text
=
"Discussions"
></
telerik:RadMenuItem
>
</
Items
>
</
telerik:RadMenu
>
</
div
>
</
form
>
</
body
>
</
html
>
--
Stuart
0
Accepted
Cori
Top achievements
Rank 2
answered on 13 Aug 2010, 04:50 PM
Great, nice to see it worked for you. Instead of setting a time out for the load, you can call the doResize method in the OnClientLoad event of the RadMenu. The reason it didn't work in the document.ready() without a timeout is because the RadMenu did not complete loading, so calling the method in the OnClientLoad event makes sure that the RadMenu has fully loaded.
Also, I updated my resize code to use pixels, which look to do the resizing a little better than with percent. I've added it here in case you want to experiment with it and see it works better for you too.
I hope that helps.
Also, I updated my resize code to use pixels, which look to do the resizing a little better than with percent. I've added it here in case you want to experiment with it and see it works better for you too.
function
ResizeMenu() {
// get width of window
var
windowWidth = $telerik.$(window).width();
// menu item widths
var
menuItemWidth = 0;
// get menu
var
menu = $find(
"<%=mnuTest.ClientID %>"
);
for
(
var
i = 0; i < menu.get_allItems().length; i++) {
var
menuItem = menu.get_allItems()[i];
if
(menuItem.get_value() !=
"Empty"
) {
menuItemWidth += $telerik.$(menuItem.get_element()).outerWidth();
}
}
// total all menu item widths
var
percentToAdjust = Math.floor((windowWidth - menuItemWidth) - 22);
$telerik.$(menu.findItemByValue(
"Empty"
).get_element()).width(percentToAdjust < 0 ? 0 : percentToAdjust +
"px"
);
}
I hope that helps.
0
Cori
Top achievements
Rank 2
answered on 13 Aug 2010, 04:59 PM
One last thing, I noticed that when I enable script debugging in IE that I would always receive a null reference error. So I moved the $telerik.$(window).resize() event registration in the OnClientLoad event of the RadMenu and the error went away. So I would suggest doing that as well to avoid that null error exception.
0
Stuart Hemming
Top achievements
Rank 2
answered on 13 Aug 2010, 05:01 PM
> So I moved the $telerik.$(window).resize() event registration in theOnClientLoad event
Sorry mate, you've lost me.
Can you post an example?
--
Dim of Grantham
Sorry mate, you've lost me.
Can you post an example?
--
Dim of Grantham
0
Cori
Top achievements
Rank 2
answered on 13 Aug 2010, 05:27 PM
So I wrote it like this:
So I just moved the call, $telerik.$(window).resize(), into the OnClientLoad method.
Sorry for the confusion.
function
OnClientLoad(sender, args) {
ResizeMenu();
$telerik.$(window).resize(
function
() {
ResizeMenu();
});
}
So I just moved the call, $telerik.$(window).resize(), into the OnClientLoad method.
Sorry for the confusion.
0
Stuart Hemming
Top achievements
Rank 2
answered on 13 Aug 2010, 05:33 PM
Gotcha!
TVM.
--
Stuart
TVM.
--
Stuart
0
Stuart Hemming
Top achievements
Rank 2
answered on 14 Aug 2010, 02:26 PM
Can I ask a loosely related Q?
I've been doing a bit of reading about jQuery. I get that I should use $(something) to access an object and I get that the $ indicates that it is something jQueryish that's going on.
When I started to try and implement your solution on page load, using other online examples I tried $(document).ready() but got an error, the same happened trying to access $(window). But then I copied what you'd done and tried $telerik.$(document)... it worked.
I'm guessing that the $telerik is indicating I'm going through a namepace or something, but why did I need to do that to get to the DOM objects?
--
Stuart
I've been doing a bit of reading about jQuery. I get that I should use $(something) to access an object and I get that the $ indicates that it is something jQueryish that's going on.
When I started to try and implement your solution on page load, using other online examples I tried $(document).ready() but got an error, the same happened trying to access $(window). But then I copied what you'd done and tried $telerik.$(document)... it worked.
I'm guessing that the $telerik is indicating I'm going through a namepace or something, but why did I need to do that to get to the DOM objects?
--
Stuart
0
Stuart Hemming
Top achievements
Rank 2
answered on 15 Aug 2010, 03:43 PM
Never mind, I found this blog post by Atanas Korchev which answers that particular question.
--
Stuart
--
Stuart