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

Split Menu

15 Answers 173 Views
Menu
This is a migrated thread and some comments may be shown as answers.
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)...
First Second Third Fourth Fifth

My user wants ...
First Second                                   Third Fourth Fifth

Is this possible?

-- 
Stuart

15 Answers, 1 is accepted

Sort by
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
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.
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
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:

$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
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
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
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 ...
<%@ 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">
    <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.

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
0
Cori
Top achievements
Rank 2
answered on 13 Aug 2010, 05:27 PM
So I wrote it like this:

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
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
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
Tags
Menu
Asked by
Stuart Hemming
Top achievements
Rank 2
Answers by
Stuart Hemming
Top achievements
Rank 2
Cori
Top achievements
Rank 2
Share this question
or