Loading ...
Sorry, an error occurred while loading the content.

Adding Submenus Using YUI Connection Manager

Expand Messages
  • Ryan
    I am trying to use YUI Menu to create a menubar with dynamic submenus.  The submenus are populated via an AJAX callback when the user mouses over a menu item.
    Message 1 of 5 , Jul 31, 2008
    • 0 Attachment

      I am trying to use YUI Menu to create a menubar with dynamic submenus.  The submenus are populated via an AJAX callback when the user mouses over a menu item.  I have made some progress but it's not working quite right, and I have not been able to find any examples of this.  I feel like I must be missing something simple, but I don't know what it is.  

      The webapp consists of 3 files:  

      1. Default.aspx and its code-behind is the main page
      2. Callback.aspx returns some JSON in the YUI Menu format, based on an id passed in the querystring
      3. Ultralight.js contains the major javascript functions

      What happens right now is that the submenus at the first level are populated correctly, but when I scroll through the submenu, the selected item is not highlighted.  The submenu that does appear doesn't seem to have focus, as it tends to disappear when I try to move my pointer into it from the parent menu item.  I've tried adding relatively large values for the hidedelay and submenuhidedelay config properties, but it seems to have no effect.  This is in IE7.  Also, further submenus under the first submenu are never displayed when I mouse over.

      As far as I know, the JSON returned from Callback.aspx is correct.  It passes the isValid method of the YUI JSON utility and parses fine.  Here's an example of the output.

      [{ "text": "Folder1", "id": "15181", "submenu": { "id": "m15181", "itemdata": [ { "text": "Test", "url": "#" } ] } },
      { "text": "Folder2", "id": "15183", "submenu": { "id": "m15183", "itemdata": [ { "text": "Test", "url": "#" } ] } },
      { "text": "Folder3", "id": "15182", "submenu": { "id": "m15182", "itemdata": [ { "text": "Test", "url": "#" } ] } },
      { "text": "Document1", "id": "15565", "url": "javascript:view(15565);" },
      { "text": "Document2", "id": "15567", "url": "javascript:view(15567);" },
      { "text": "Document3", "id": "15566", "url": "javascript:view(15566);" }] 

      Below is the code I'm using, with the irrelevant parts removed for clarity.  Any suggestions are appreciated.

      Thanks,
      Ryan

       Default.aspx
      <!-- Standard reset and fonts -->
        <link rel="stylesheet" type="text/css" href="../yui/reset/reset.css" />
        <link rel="stylesheet" type="text/css" href="../yui/fonts/fonts.css" />
        <!-- CSS for Menu -->
        <link rel="stylesheet" type="text/css" href="../yui/menu/assets/skins/sam/menu.css" />
        <link rel="stylesheet" type="text/css" href="style/ultralight.css" />
        <!-- Dependency source files -->
        <script type="text/javascript" src="../yui/yahoo/yahoo-min.js"></script>  
        <script type="text/javascript" src="../yui/yahoo-dom-event/yahoo-dom-event.js"></script>
        <script type="text/javascript" src="../yui/connection/connection-min.js"></script>
        <script type="text/javascript" src="../yui/container/container_core.js"></script>
        <script type="text/javascript" src="../yui/json/json-min.js"></script>  
        <!-- Menu source file -->
        <script type="text/javascript" src="../yui/menu/menu.js"></script>  
      </head>
      <body class="yui-skin-sam">
        <div id="reportmenu" class="yuimenubar yuimenubarnav">
        <div class="bd">
        <ul class="first-of-type">
        <li class="yuimenubaritem first-of-type"><a class="yuimenubaritemlabel" href="#logo">
        &nbsp;<img src="images/logofavicon_sm.gif" /></a> 
        <div id="logo" class="yuimenu">
        <div class="bd">
        <ul>
        <li class="yuimenuitem first-of-type">
        <a class="yuimenuitemlabel" href="http://www.yahoo.com/">Yahoo!</a>
        </li>
        </ul>
        </div>
        </div>  
        </li>
        <asp:Repeater ID="folderMenu" runat="server">
        <ItemTemplate>
        <li class="yuimenubaritem" id="<%#Container.DataItem.UID %>">
        <a class="yuimenubaritemlabel"><%#Container.DataItem.Name%></a>  
        </li>  
        </ItemTemplate>
        </asp:Repeater>
        </ul>
        </div>
        </div>
      </body>

      Ultralight.js

      var oMenuBar;
      var sUrl = "Callback.aspx";

      YAHOO.util.Event.onContentReady("reportmenu", function () {
        oMenuBar = new YAHOO.widget.MenuBar("reportmenu", { 
        autosubmenudisplay: true, 
        hidedelay: 2000,
        submenuhidedelay: 2000,
        lazyload: true });
        for(var i=1; i<oMenuBar.getItems().length; i++)
        {  
        var id = oMenuBar.getItem(i).id;
        var oSubmenu = new YAHOO.widget.Menu("m" + id);
        oSubmenu.beforeShowEvent.subscribe(onMenuBeforeShow, oSubmenu, true);
        oMenuBar.getItem(i).cfg.setProperty("submenu", oSubmenu);  
        }  
         
        oMenuBar.render(); 
      });

      function onMenuBeforeShow(p_sType, p_sArgs, p_oMenu) {
        // Check if the menu has any items. If not, add them
        if(this.getItemGroups().length == 0) {
        var sThisUrl = sUrl + "?id=" + this.id.substr(1);
        var request = YAHOO.util.Connect.asyncRequest('GET', sThisUrl, callback); 
        }
      }

      var handleSuccess = function(o){
       if(o.responseText !== undefined){
        var data;
        if(YAHOO.lang.JSON.isValid(o.responseText))
        {
            try {
                data = YAHOO.lang.JSON.parse(o.responseText);
            }
            catch (e) {
                alert(e);
            }  
        }
        else 
        {
            alert("Invalid JSON");
        }  

        var oSubmenu = new YAHOO.widget.Menu("m" + oMenuBar.activeItem.id);
        oSubmenu.addItems(data);  
        oMenuBar.activeItem.cfg.setProperty("submenu", oSubmenu);  
         
        oSubmenu.render();
        oSubmenu.show();
       }
      }

      var handleFailure = function(o){
       if(o.responseText !== undefined){
        alert("Status code message: " + o.statusText);
       }
      }

      var callback =
      {
        success:handleSuccess,
        failure: handleFailure
      };

    • Todd Kloots
      Hi Ryan - The type of behavior you are describing (no selection or focus) is usually symptomatic of Menu or MenuItem instances using duplicate HTML ids. I
      Message 2 of 5 , Aug 4, 2008
      • 0 Attachment
        Hi Ryan -

        The type of behavior you are describing (no selection or focus) is
        usually symptomatic of Menu or MenuItem instances using duplicate HTML
        ids. I would examine the Menu's DOM using the browser's DOM inspector
        to check if this is the case. If you find that all of the ids for your
        Menu and MenuItem instances are unique and are still having this
        problem, please send me a URL to your functioning code so that I can
        take a look. If you feel uncomfortable emailing the URL to the Y!
        Group, feel free to contact me offline.

        Thanks,
        Todd

        Ryan wrote:
        >
        > I am trying to use YUI Menu to create a menubar with dynamic submenus.
        > The submenus are populated via an AJAX callback when the user mouses
        > over a menu item. I have made some progress but it's not working
        > quite right, and I have not been able to find any examples of this. I
        > feel like I must be missing something simple, but I don't know what it
        > is.
        >
        > The webapp consists of 3 files:
        >
        > 1. Default.aspx and its code-behind is the main page
        > 2. Callback.aspx returns some JSON in the YUI Menu format, based on
        > an id passed in the querystring
        > 3. Ultralight.js contains the major javascript functions
        >
        > What happens right now is that the submenus at the first level are
        > populated correctly, but when I scroll through the submenu, the
        > selected item is not highlighted. The submenu that does appear
        > doesn't seem to have focus, as it tends to disappear when I try to
        > move my pointer into it from the parent menu item. I've tried adding
        > relatively large values for the hidedelay and submenuhidedelay config
        > properties, but it seems to have no effect. This is in IE7. Also,
        > further submenus under the first submenu are never displayed when I
        > mouse over.
        >
        > As far as I know, the JSON returned from Callback.aspx is correct. It
        > passes the isValid method of the YUI JSON utility and parses fine.
        > Here's an example of the output.
        >
        > [{ "text": "Folder1", "id": "15181", "submenu": { "id": "m15181",
        > "itemdata": [ { "text": "Test", "url": "#" } ] } },
        > { "text": "Folder2", "id": "15183", "submenu": { "id": "m15183",
        > "itemdata": [ { "text": "Test", "url": "#" } ] } },
        > { "text": "Folder3", "id": "15182", "submenu": { "id": "m15182",
        > "itemdata": [ { "text": "Test", "url": "#" } ] } },
        > { "text": "Document1", "id": "15565", "url": "javascript:view(15565);" },
        > { "text": "Document2", "id": "15567", "url": "javascript:view(15567);" },
        > { "text": "Document3", "id": "15566", "url": "javascript:view(15566);" }]
        >
        > Below is the code I'm using, with the irrelevant parts removed for
        > clarity. Any suggestions are appreciated.
        >
        > Thanks,
        > Ryan
        >
        > *_Default.aspx_*
        > <!-- Standard reset and fonts -->
        > <link rel="stylesheet" type="text/css" href="../yui/reset/reset.css" />
        > <link rel="stylesheet" type="text/css" href="../yui/fonts/fonts.css" />
        > <!-- CSS for Menu -->
        > <link rel="stylesheet" type="text/css"
        > href="../yui/menu/assets/skins/sam/menu.css" />
        > <link rel="stylesheet" type="text/css" href="style/ultralight.css" />
        > <!-- Dependency source files -->
        > <script type="text/javascript"
        > src="../yui/yahoo/yahoo-min.js"></script>
        > <script type="text/javascript"
        > src="../yui/yahoo-dom-event/yahoo-dom-event.js"></script>
        > <script type="text/javascript"
        > src="../yui/connection/connection-min.js"></script>
        > <script type="text/javascript"
        > src="../yui/container/container_core.js"></script>
        > <script type="text/javascript" src="../yui/json/json-min.js"></script>
        > <!-- Menu source file -->
        > <script type="text/javascript" src="../yui/menu/menu.js"></script>
        > </head>
        > <body class="yui-skin-sam">
        > <div id="reportmenu" class="yuimenubar yuimenubarnav">
        > <div class="bd">
        > <ul class="first-of-type">
        > <li class="yuimenubaritem first-of-type"><a
        > class="yuimenubaritemlabel" href="#logo">
        >  <img src="images/logofavicon_sm.gif" /></a>
        > <div id="logo" class="yuimenu">
        > <div class="bd">
        > <ul>
        > <li class="yuimenuitem first-of-type">
        > <a class="yuimenuitemlabel" href="http://www.yahoo.com/">Yahoo!</a>
        > </li>
        > </ul>
        > </div>
        > </div>
        > </li>
        > <asp:Repeater ID="folderMenu" runat="server">
        > <ItemTemplate>
        > <li class="yuimenubaritem" id="<%#Container.DataItem.UID %>">
        > <a class="yuimenubaritemlabel"><%#Container.DataItem.Name%></a>
        > </li>
        > </ItemTemplate>
        > </asp:Repeater>
        > </ul>
        > </div>
        > </div>
        > </body>
        >
        > *_Ultralight.js_*
        >
        > var oMenuBar;
        > var sUrl = "Callback.aspx";
        >
        > YAHOO.util.Event.onContentReady("reportmenu", function () {
        > oMenuBar = new YAHOO.widget.MenuBar("reportmenu", {
        > autosubmenudisplay: true,
        > hidedelay: 2000,
        > submenuhidedelay: 2000,
        > lazyload: true });
        > for(var i=1; i<oMenuBar.getItems().length; i++)
        > {
        > var id = oMenuBar.getItem(i).id;
        > var oSubmenu = new YAHOO.widget.Menu("m" + id);
        > oSubmenu.beforeShowEvent.subscribe(onMenuBeforeShow, oSubmenu, true);
        > oMenuBar.getItem(i).cfg.setProperty("submenu", oSubmenu);
        > }
        >
        > oMenuBar.render();
        > });
        >
        > function onMenuBeforeShow(p_sType, p_sArgs, p_oMenu) {
        > // Check if the menu has any items. If not, add them
        > if(this.getItemGroups().length == 0) {
        > var sThisUrl = sUrl + "?id=" + this.id.substr(1);
        > var request = YAHOO.util.Connect.asyncRequest('GET', sThisUrl,
        > callback);
        > }
        > }
        >
        > var handleSuccess = function(o){
        > if(o.responseText !== undefined){
        > var data;
        > if(YAHOO.lang.JSON.isValid(o.responseText))
        > {
        > try {
        > data = YAHOO.lang.JSON.parse(o.responseText);
        > }
        > catch (e) {
        > alert(e);
        > }
        > }
        > else
        > {
        > alert("Invalid JSON");
        > }
        >
        > var oSubmenu = new YAHOO.widget.Menu("m" + oMenuBar.activeItem.id);
        > oSubmenu.addItems(data);
        > oMenuBar.activeItem.cfg.setProperty("submenu", oSubmenu);
        >
        > oSubmenu.render();
        > oSubmenu.show();
        > }
        > }
        >
        > var handleFailure = function(o){
        > if(o.responseText !== undefined){
        > alert("Status code message: " + o.statusText);
        > }
        > }
        >
        > var callback =
        > {
        > success:handleSuccess,
        > failure: handleFailure
        > };
        >
        >
      • Ryan
        Todd, Thanks, that was definitely the problem. I m not sure exactly where the IDs were coming up the same, but I changed them around and it works now. I am
        Message 3 of 5 , Aug 11, 2008
        • 0 Attachment
          Todd,
          Thanks, that was definitely the problem. I'm not sure exactly where
          the IDs were coming up the same, but I changed them around and it
          works now.

          I am having one other minor issue though. When I mouse over a
          MenuItem, the beforeShow event triggers and the callback fetches the
          submenu's contents. However, the menu never displays until I mouse
          out of the Item and then back into it. Any thoughts on why this
          would be happening?

          Unfortunately this site isn't on a public server or else I would send
          you the URL...

          Thanks again,
          Ryan
        • Ryan
          Any thoughts on this? Again, it seems like the menu populates on the first mouse-over, but does not display until I mouse-out and mouse- over again. Ryan ...
          Message 4 of 5 , Aug 19, 2008
          • 0 Attachment
            Any thoughts on this? Again, it seems like the menu populates on the
            first mouse-over, but does not display until I mouse-out and mouse-
            over again.

            Ryan

            --- In ydn-javascript@yahoogroups.com, "Ryan" <ryser2k@...> wrote:
            >
            > Todd,
            > Thanks, that was definitely the problem. I'm not sure exactly
            where
            > the IDs were coming up the same, but I changed them around and it
            > works now.
            >
            > I am having one other minor issue though. When I mouse over a
            > MenuItem, the beforeShow event triggers and the callback fetches
            the
            > submenu's contents. However, the menu never displays until I mouse
            > out of the Item and then back into it. Any thoughts on why this
            > would be happening?
            >
            > Unfortunately this site isn't on a public server or else I would
            send
            > you the URL...
            >
            > Thanks again,
            > Ryan
            >
          • Todd Kloots
            Ryan - It is really difficult to help if you cannot provide any code to look at. How are you putting each submenu together? You should start by setting the
            Message 5 of 5 , Aug 20, 2008
            • 0 Attachment
              Ryan -

              It is really difficult to help if you cannot provide any code to look
              at. How are you putting each submenu together? You should start by
              setting the "submenu" configuration property of each MenuItem to a Menu
              instance that contains no MenuItems. Then add a "beforeShow" event
              listener for that Menu, that makes the async request, gets the data,
              calls the Menu's "addItems" method, calls the Menu's "render" method,
              and finally unsubscribes the "beforeShow" event listener. That should
              work. Let me know.

              - Todd

              Ryan wrote:
              >
              > Any thoughts on this? Again, it seems like the menu populates on the
              > first mouse-over, but does not display until I mouse-out and mouse-
              > over again.
              >
              > Ryan
              >
              > --- In ydn-javascript@yahoogroups.com
              > <mailto:ydn-javascript%40yahoogroups.com>, "Ryan" <ryser2k@...> wrote:
              > >
              > > Todd,
              > > Thanks, that was definitely the problem. I'm not sure exactly
              > where
              > > the IDs were coming up the same, but I changed them around and it
              > > works now.
              > >
              > > I am having one other minor issue though. When I mouse over a
              > > MenuItem, the beforeShow event triggers and the callback fetches
              > the
              > > submenu's contents. However, the menu never displays until I mouse
              > > out of the Item and then back into it. Any thoughts on why this
              > > would be happening?
              > >
              > > Unfortunately this site isn't on a public server or else I would
              > send
              > > you the URL...
              > >
              > > Thanks again,
              > > Ryan
              > >
              >
              >
            Your message has been successfully submitted and would be delivered to recipients shortly.